diff --git a/Stack/Opc.Ua.Core/Security/Certificates/CertificateValidator.cs b/Stack/Opc.Ua.Core/Security/Certificates/CertificateValidator.cs index 872a80959f..7a37804be3 100644 --- a/Stack/Opc.Ua.Core/Security/Certificates/CertificateValidator.cs +++ b/Stack/Opc.Ua.Core/Security/Certificates/CertificateValidator.cs @@ -817,9 +817,21 @@ namespace Opc.Ua case X509ChainStatusFlags.UntrustedRoot: { + // self signed cert signature validation + // .Net Core ChainStatus returns NotSignatureValid only on Windows, + // so we have to do the extra cert signature check on all platforms + if (issuer == null && !isIssuer && + id.Certificate != null && Utils.CompareDistinguishedName(id.Certificate.Subject, id.Certificate.Subject)) + { + if (!IsSignatureValid(id.Certificate)) + { + goto case X509ChainStatusFlags.NotSignatureValid; + } + } + // ignore this error because the root check is done // by looking the certificate up in the trusted issuer stores passed to the validator. - // the ChainStatus uses the Windows trusted issuer stores. + // the ChainStatus uses the trusted issuer stores. break; } @@ -915,6 +927,22 @@ namespace Opc.Ua oid.Value == "1.3.14.3.2.13" || // sha1DSA oid.Value == "1.3.14.3.2.27"; // dsaSHA1 } + /// + /// Returns if a self signed certificate is properly signed. + /// + private static bool IsSignatureValid(X509Certificate2 cert) + { + Org.BouncyCastle.X509.X509Certificate bcCert = new Org.BouncyCastle.X509.X509CertificateParser().ReadCertificate(cert.RawData); + try + { + bcCert.Verify(bcCert.GetPublicKey()); + } + catch + { + return false; + } + return true; + } #endregion #region WcfValidatorWrapper Class