diff --git a/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/CertificateBuilder.cs b/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/CertificateBuilder.cs index ab2ccb283a..5bf24e38e6 100644 --- a/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/CertificateBuilder.cs +++ b/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/CertificateBuilder.cs @@ -125,15 +125,7 @@ namespace Opc.Ua.Security.Certificates if (publicKey == null) throw new ArgumentNullException(nameof(publicKey)); try { - var asymmetricKeyParameter = PublicKeyFactory.CreateKey(publicKey); - var rsaKeyParameters = asymmetricKeyParameter as RsaKeyParameters; - var parameters = new RSAParameters { - Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned(), - Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned() - }; - RSA rsaPublicKey = RSA.Create(); - rsaPublicKey.ImportParameters(parameters); - m_rsaPublicKey = rsaPublicKey; + m_rsaPublicKey = X509Utils.SetRSAPublicKey(publicKey); } catch (Exception e) { diff --git a/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/X509Utils.cs b/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/X509Utils.cs index cb38f1f84e..ae896e0e71 100644 --- a/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/X509Utils.cs +++ b/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/X509Utils.cs @@ -191,6 +191,22 @@ namespace Opc.Ua.Security.Certificates.BouncyCastle return Convert.ToBase64String(tokenBuffer); } } + + /// + /// Returns a RSA object with an imported public key. + /// + internal static RSA SetRSAPublicKey(byte[] publicKey) + { + var asymmetricKeyParameter = PublicKeyFactory.CreateKey(publicKey); + var rsaKeyParameters = asymmetricKeyParameter as RsaKeyParameters; + var parameters = new RSAParameters { + Exponent = rsaKeyParameters.Exponent.ToByteArrayUnsigned(), + Modulus = rsaKeyParameters.Modulus.ToByteArrayUnsigned() + }; + RSA rsaPublicKey = RSA.Create(); + rsaPublicKey.ImportParameters(parameters); + return rsaPublicKey; + } #endregion } } diff --git a/Libraries/Opc.Ua.Security.Certificates/X509Certificate/CertificateBuilder.cs b/Libraries/Opc.Ua.Security.Certificates/X509Certificate/CertificateBuilder.cs index d41d5ebdbf..9ea52a76e0 100644 --- a/Libraries/Opc.Ua.Security.Certificates/X509Certificate/CertificateBuilder.cs +++ b/Libraries/Opc.Ua.Security.Certificates/X509Certificate/CertificateBuilder.cs @@ -295,14 +295,16 @@ namespace Opc.Ua.Security.Certificates public override ICertificateBuilderCreateForRSAAny SetRSAPublicKey(byte[] publicKey) { if (publicKey == null) throw new ArgumentNullException(nameof(publicKey)); -#if NET472_OR_GREATER - throw new NotSupportedException("Import a RSAPublicKey is not supported on this platform."); -#else int bytes = 0; try { +#if NET472_OR_GREATER + m_rsaPublicKey = BouncyCastle.X509Utils.SetRSAPublicKey(publicKey); + bytes = publicKey.Length; +#else m_rsaPublicKey = RSA.Create(); m_rsaPublicKey.ImportSubjectPublicKeyInfo(publicKey, out bytes); +#endif } catch (Exception e) { @@ -314,7 +316,6 @@ namespace Opc.Ua.Security.Certificates throw new ArgumentException("Decoded the public key but extra bytes were found."); } return this; -#endif } #endregion diff --git a/Libraries/Opc.Ua.Server/Configuration/ConfigurationNodeManager.cs b/Libraries/Opc.Ua.Server/Configuration/ConfigurationNodeManager.cs index 346f7e270b..1ca3de9605 100644 --- a/Libraries/Opc.Ua.Server/Configuration/ConfigurationNodeManager.cs +++ b/Libraries/Opc.Ua.Server/Configuration/ConfigurationNodeManager.cs @@ -120,6 +120,7 @@ namespace Opc.Ua.Server m_configuration = configuration; // TODO: configure cert groups in configuration ServerCertificateGroup defaultApplicationGroup = new ServerCertificateGroup { + NodeId = Opc.Ua.ObjectIds.ServerConfiguration_CertificateGroups_DefaultApplicationGroup, BrowseName = Opc.Ua.BrowseNames.DefaultApplicationGroup, CertificateTypes = new NodeId[] { ObjectTypeIds.RsaSha256ApplicationCertificateType }, ApplicationCertificate = configuration.SecurityConfiguration.ApplicationCertificate, @@ -200,7 +201,8 @@ namespace Opc.Ua.Server case ObjectTypes.CertificateGroupType: { - var result = m_certificateGroups.FirstOrDefault(group => group.BrowseName == passiveNode.BrowseName); + var result = m_certificateGroups.FirstOrDefault(group => group.NodeId == passiveNode.NodeId); + if (result != null) { CertificateGroupState activeNode = new CertificateGroupState(passiveNode.Parent); diff --git a/Libraries/Opc.Ua.Server/Diagnostics/AuditEvents.cs b/Libraries/Opc.Ua.Server/Diagnostics/AuditEvents.cs index e24cc9e697..073f103963 100644 --- a/Libraries/Opc.Ua.Server/Diagnostics/AuditEvents.cs +++ b/Libraries/Opc.Ua.Server/Diagnostics/AuditEvents.cs @@ -1224,9 +1224,17 @@ namespace Opc.Ua.Server { exception = exception.InnerException; } + if (exception is ServiceResultException sre) { - statusCode = sre.InnerResult.StatusCode; + if (sre.InnerResult != null) + { + statusCode = sre.InnerResult.StatusCode; + } + else + { + statusCode = sre.StatusCode; + } } ISystemContext systemContext = server.DefaultAuditContext; diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e8b8fd64f0..026b373847 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -64,6 +64,12 @@ stages: framework: net462 agents: '@{ windows = "windows-2019" }' jobnamesuffix: net462 + - template: .azurepipelines/test.yml + parameters: + configuration: Release + framework: net48 + agents: '@{ windows = "windows-2019" }' + jobnamesuffix: net48 - template: .azurepipelines/test.yml parameters: configuration: Release