diff --git a/Stack/Opc.Ua.Core/Security/Certificates/CertificateFactory.cs b/Stack/Opc.Ua.Core/Security/Certificates/CertificateFactory.cs
index 9e4d0867f7..f5b5e05e60 100644
--- a/Stack/Opc.Ua.Core/Security/Certificates/CertificateFactory.cs
+++ b/Stack/Opc.Ua.Core/Security/Certificates/CertificateFactory.cs
@@ -836,24 +836,20 @@ public class CertificateFactory
try
{
// verify the public and private key match
- using (RSA rsaPrivateKey = certWithPrivateKey.GetRSAPrivateKey())
+ RSA rsaPrivateKey = certWithPrivateKey.GetRSAPrivateKey();
+ RSA rsaPublicKey = certWithPublicKey.GetRSAPublicKey();
+ X509KeyUsageFlags keyUsage = GetKeyUsage(certWithPublicKey);
+ if ((keyUsage & X509KeyUsageFlags.DataEncipherment) != 0)
{
- using (RSA rsaPublicKey = certWithPublicKey.GetRSAPublicKey())
- {
- X509KeyUsageFlags keyUsage = GetKeyUsage(certWithPublicKey);
- if ((keyUsage & X509KeyUsageFlags.DataEncipherment) != 0)
- {
- result = VerifyRSAKeyPairCrypt(rsaPublicKey, rsaPrivateKey);
- }
- else if ((keyUsage & X509KeyUsageFlags.DigitalSignature) != 0)
- {
- result = VerifyRSAKeyPairSign(rsaPublicKey, rsaPrivateKey);
- }
- else
- {
- throw new CryptographicException("Don't know how to verify the public/private key pair.");
- }
- }
+ result = VerifyRSAKeyPairCrypt(rsaPublicKey, rsaPrivateKey);
+ }
+ else if ((keyUsage & X509KeyUsageFlags.DigitalSignature) != 0)
+ {
+ result = VerifyRSAKeyPairSign(rsaPublicKey, rsaPrivateKey);
+ }
+ else
+ {
+ throw new CryptographicException("Don't know how to verify the public/private key pair.");
}
}
catch (Exception e)
@@ -1050,14 +1046,12 @@ public class CertificateFactory
///
private static RsaKeyParameters GetPublicKeyParameter(X509Certificate2 certificate)
{
- using (RSA rsa = certificate.GetRSAPublicKey())
- {
- RSAParameters rsaParams = rsa.ExportParameters(false);
- return new RsaKeyParameters(
- false,
- new BigInteger(1, rsaParams.Modulus),
- new BigInteger(1, rsaParams.Exponent));
- }
+ RSA rsa = certificate.GetRSAPublicKey();
+ RSAParameters rsaParams = rsa.ExportParameters(false);
+ return new RsaKeyParameters(
+ false,
+ new BigInteger(1, rsaParams.Modulus),
+ new BigInteger(1, rsaParams.Exponent));
}
///
@@ -1067,20 +1061,18 @@ public class CertificateFactory
private static RsaPrivateCrtKeyParameters GetPrivateKeyParameter(X509Certificate2 certificate)
{
// try to get signing/private key from certificate passed in
- using (RSA rsa = certificate.GetRSAPrivateKey())
- {
- RSAParameters rsaParams = rsa.ExportParameters(true);
- RsaPrivateCrtKeyParameters keyParams = new RsaPrivateCrtKeyParameters(
- new BigInteger(1, rsaParams.Modulus),
- new BigInteger(1, rsaParams.Exponent),
- new BigInteger(1, rsaParams.D),
- new BigInteger(1, rsaParams.P),
- new BigInteger(1, rsaParams.Q),
- new BigInteger(1, rsaParams.DP),
- new BigInteger(1, rsaParams.DQ),
- new BigInteger(1, rsaParams.InverseQ));
- return keyParams;
- }
+ RSA rsa = certificate.GetRSAPrivateKey();
+ RSAParameters rsaParams = rsa.ExportParameters(true);
+ RsaPrivateCrtKeyParameters keyParams = new RsaPrivateCrtKeyParameters(
+ new BigInteger(1, rsaParams.Modulus),
+ new BigInteger(1, rsaParams.Exponent),
+ new BigInteger(1, rsaParams.D),
+ new BigInteger(1, rsaParams.P),
+ new BigInteger(1, rsaParams.Q),
+ new BigInteger(1, rsaParams.DP),
+ new BigInteger(1, rsaParams.DQ),
+ new BigInteger(1, rsaParams.InverseQ));
+ return keyParams;
}
///
diff --git a/Stack/Opc.Ua.Core/Security/Certificates/CertificateValidator.cs b/Stack/Opc.Ua.Core/Security/Certificates/CertificateValidator.cs
index 471eabc6c0..5575bb2b87 100644
--- a/Stack/Opc.Ua.Core/Security/Certificates/CertificateValidator.cs
+++ b/Stack/Opc.Ua.Core/Security/Certificates/CertificateValidator.cs
@@ -709,12 +709,10 @@ namespace Opc.Ua
throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "SHA1 signed certificates are not trusted");
}
- using (RSA rsa = certificate.GetRSAPublicKey())
+ RSA rsa = certificate.GetRSAPublicKey();
+ if (rsa.KeySize < m_minimumCertificateKeySize)
{
- if (rsa.KeySize < m_minimumCertificateKeySize)
- {
- throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Certificate doesn't meet minimum key length requirement");
- }
+ throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Certificate doesn't meet minimum key length requirement");
}
CertificateIdentifier trustedCertificate = await GetTrustedCertificate(certificate);
diff --git a/Stack/Opc.Ua.Core/Security/Certificates/RsaUtils.cs b/Stack/Opc.Ua.Core/Security/Certificates/RsaUtils.cs
index 29e506bf10..088d3ca9a8 100644
--- a/Stack/Opc.Ua.Core/Security/Certificates/RsaUtils.cs
+++ b/Stack/Opc.Ua.Core/Security/Certificates/RsaUtils.cs
@@ -28,10 +28,8 @@ namespace Opc.Ua
///
public static int GetPlainTextBlockSize(X509Certificate2 encryptingCertificate, bool useOaep)
{
- using (RSA rsa = encryptingCertificate.GetRSAPublicKey())
- {
- return GetPlainTextBlockSize(rsa, useOaep);
- }
+ RSA rsa = encryptingCertificate.GetRSAPublicKey();
+ return GetPlainTextBlockSize(rsa, useOaep);
}
///
@@ -58,30 +56,20 @@ namespace Opc.Ua
///
public static int GetCipherTextBlockSize(X509Certificate2 encryptingCertificate, bool useOaep)
{
- using (RSA rsa = encryptingCertificate.GetRSAPublicKey())
- {
- if (rsa != null)
- {
- return rsa.KeySize / 8;
- }
- }
- return -1;
+ RSA rsa = encryptingCertificate.GetRSAPublicKey();
+ return GetCipherTextBlockSize(rsa, useOaep);
}
///
- /// Returns the length of a RSA PKCS#1 v1.5 signature of a digest.
+ /// Return the ciphertext block size for RSA OAEP encryption.
///
- public static int RsaPkcs15_GetSignatureLength(X509Certificate2 signingCertificate)
+ public static int GetCipherTextBlockSize(RSA rsa, bool useOaep)
{
- using (RSA rsa = signingCertificate.GetRSAPublicKey())
+ if (rsa != null)
{
- if (rsa == null)
- {
- throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
- }
-
return rsa.KeySize / 8;
}
+ return -1;
}
///
@@ -92,17 +80,14 @@ namespace Opc.Ua
X509Certificate2 signingCertificate)
{
// extract the private key.
- using (RSA rsa = signingCertificate.GetRSAPrivateKey())
+ RSA rsa = signingCertificate.GetRSAPrivateKey();
+ if (rsa == null)
{
-
- if (rsa == null)
- {
- throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
- }
-
- // create the signature.
- return rsa.SignData(dataToSign.Array, dataToSign.Offset, dataToSign.Count, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
+ throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
}
+
+ // create the signature.
+ return rsa.SignData(dataToSign.Array, dataToSign.Offset, dataToSign.Count, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
}
///
@@ -113,17 +98,14 @@ namespace Opc.Ua
X509Certificate2 signingCertificate)
{
// extract the private key.
- using (RSA rsa = signingCertificate.GetRSAPrivateKey())
+ RSA rsa = signingCertificate.GetRSAPrivateKey();
+ if (rsa == null)
{
-
- if (rsa == null)
- {
- throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
- }
-
- // create the signature.
- return rsa.SignData(dataToSign.Array, dataToSign.Offset, dataToSign.Count, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
+ throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
}
+
+ // create the signature.
+ return rsa.SignData(dataToSign.Array, dataToSign.Offset, dataToSign.Count, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
///
@@ -134,18 +116,15 @@ namespace Opc.Ua
byte[] signature,
X509Certificate2 signingCertificate)
{
- // extract the private key.
- using (RSA rsa = signingCertificate.GetRSAPublicKey())
+ // extract the public key.
+ RSA rsa = signingCertificate.GetRSAPublicKey();
+ if (rsa == null)
{
-
- if (rsa == null)
- {
- throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
- }
-
- // verify signature.
- return rsa.VerifyData(dataToVerify.Array, dataToVerify.Offset, dataToVerify.Count, signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
+ throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
}
+
+ // verify signature.
+ return rsa.VerifyData(dataToVerify.Array, dataToVerify.Offset, dataToVerify.Count, signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
}
///
@@ -157,17 +136,14 @@ namespace Opc.Ua
X509Certificate2 signingCertificate)
{
// extract the private key.
- using (RSA rsa = signingCertificate.GetRSAPublicKey())
+ RSA rsa = signingCertificate.GetRSAPublicKey();
+ if (rsa == null)
{
-
- if (rsa == null)
- {
- throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
- }
-
- // verify signature.
- return rsa.VerifyData(dataToVerify.Array, dataToVerify.Offset, dataToVerify.Count, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
+ throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
}
+
+ // verify signature.
+ return rsa.VerifyData(dataToVerify.Array, dataToVerify.Offset, dataToVerify.Count, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
///
@@ -178,10 +154,16 @@ namespace Opc.Ua
X509Certificate2 encryptingCertificate,
bool useOaep)
{
- int plaintextBlockSize = GetPlainTextBlockSize(encryptingCertificate, useOaep);
+ RSA rsa = encryptingCertificate.GetRSAPublicKey();
+ if (rsa == null)
+ {
+ throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
+ }
+
+ int plaintextBlockSize = GetPlainTextBlockSize(rsa, useOaep);
int blockCount = ((dataToEncrypt.Length + 4) / plaintextBlockSize) + 1;
int plainTextSize = blockCount * plaintextBlockSize;
- int cipherTextSize = blockCount * GetCipherTextBlockSize(encryptingCertificate, useOaep);
+ int cipherTextSize = blockCount * GetCipherTextBlockSize(rsa, useOaep);
byte[] plainText = new byte[plainTextSize];
@@ -195,7 +177,7 @@ namespace Opc.Ua
Array.Copy(dataToEncrypt, 0, plainText, 4, dataToEncrypt.Length);
byte[] buffer = new byte[cipherTextSize];
- ArraySegment cipherText = Encrypt(new ArraySegment(plainText), encryptingCertificate, useOaep, new ArraySegment(buffer));
+ ArraySegment cipherText = Encrypt(new ArraySegment(plainText), rsa, useOaep, new ArraySegment(buffer));
System.Diagnostics.Debug.Assert(cipherText.Count == buffer.Length);
return buffer;
@@ -206,61 +188,51 @@ namespace Opc.Ua
///
public static ArraySegment Encrypt(
ArraySegment dataToEncrypt,
- X509Certificate2 encryptingCertificate,
+ RSA rsa,
bool useOaep,
ArraySegment outputBuffer)
{
- // get the encrypting key.
- using (RSA rsa = encryptingCertificate.GetRSAPublicKey())
+ int inputBlockSize = GetPlainTextBlockSize(rsa, useOaep);
+ int outputBlockSize = GetCipherTextBlockSize(rsa, useOaep);
+
+ // verify the input data is the correct block size.
+ if (dataToEncrypt.Count % inputBlockSize != 0)
+ {
+ Utils.Trace("Message is not an integral multiple of the block size. Length = {0}, BlockSize = {1}.", dataToEncrypt.Count, inputBlockSize);
+ }
+
+ byte[] encryptedBuffer = outputBuffer.Array;
+
+ using (MemoryStream ostrm = new MemoryStream(
+ encryptedBuffer,
+ outputBuffer.Offset,
+ outputBuffer.Count))
{
- if (rsa == null)
+ // encrypt body.
+ byte[] input = new byte[inputBlockSize];
+
+ for (int ii = dataToEncrypt.Offset; ii < dataToEncrypt.Offset + dataToEncrypt.Count; ii += inputBlockSize)
{
- throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
- }
-
- int inputBlockSize = GetPlainTextBlockSize(encryptingCertificate, useOaep);
- int outputBlockSize = rsa.KeySize / 8;
-
- // verify the input data is the correct block size.
- if (dataToEncrypt.Count % inputBlockSize != 0)
- {
- Utils.Trace("Message is not an integral multiple of the block size. Length = {0}, BlockSize = {1}.", dataToEncrypt.Count, inputBlockSize);
- }
-
- byte[] encryptedBuffer = outputBuffer.Array;
-
- using (MemoryStream ostrm = new MemoryStream(
- encryptedBuffer,
- outputBuffer.Offset,
- outputBuffer.Count))
- {
-
- // encrypt body.
- byte[] input = new byte[inputBlockSize];
-
- for (int ii = dataToEncrypt.Offset; ii < dataToEncrypt.Offset + dataToEncrypt.Count; ii += inputBlockSize)
+ Array.Copy(dataToEncrypt.Array, ii, input, 0, input.Length);
+ if (useOaep == true)
{
- Array.Copy(dataToEncrypt.Array, ii, input, 0, input.Length);
- if (useOaep == true)
- {
- byte[] cipherText = rsa.Encrypt(input, RSAEncryptionPadding.OaepSHA1);
- ostrm.Write(cipherText, 0, cipherText.Length);
- }
- else
- {
- byte[] cipherText = rsa.Encrypt(input, RSAEncryptionPadding.Pkcs1);
- ostrm.Write(cipherText, 0, cipherText.Length);
- }
+ byte[] cipherText = rsa.Encrypt(input, RSAEncryptionPadding.OaepSHA1);
+ ostrm.Write(cipherText, 0, cipherText.Length);
+ }
+ else
+ {
+ byte[] cipherText = rsa.Encrypt(input, RSAEncryptionPadding.Pkcs1);
+ ostrm.Write(cipherText, 0, cipherText.Length);
}
}
-
- // return buffer
- return new ArraySegment(
- encryptedBuffer,
- outputBuffer.Offset,
- (dataToEncrypt.Count / inputBlockSize) * outputBlockSize);
}
+
+ // return buffer
+ return new ArraySegment(
+ encryptedBuffer,
+ outputBuffer.Offset,
+ (dataToEncrypt.Count / inputBlockSize) * outputBlockSize);
}
///
@@ -271,11 +243,17 @@ namespace Opc.Ua
X509Certificate2 encryptingCertificate,
bool useOaep)
{
- int plainTextSize = dataToDecrypt.Count / GetCipherTextBlockSize(encryptingCertificate, useOaep);
+ RSA rsa = encryptingCertificate.GetRSAPrivateKey();
+ if (rsa == null)
+ {
+ throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
+ }
+
+ int plainTextSize = dataToDecrypt.Count / GetCipherTextBlockSize(rsa, useOaep);
plainTextSize *= GetPlainTextBlockSize(encryptingCertificate, useOaep);
byte[] buffer = new byte[plainTextSize];
- ArraySegment plainText = Decrypt(dataToDecrypt, encryptingCertificate, useOaep, new ArraySegment(buffer));
+ ArraySegment plainText = Decrypt(dataToDecrypt, rsa, useOaep, new ArraySegment(buffer));
System.Diagnostics.Debug.Assert(plainText.Count == buffer.Length);
// decode length.
@@ -297,57 +275,48 @@ namespace Opc.Ua
///
public static ArraySegment Decrypt(
ArraySegment dataToDecrypt,
- X509Certificate2 encryptingCertificate,
+ RSA rsa,
bool useOaep,
ArraySegment outputBuffer)
{
- // get the encrypting key.
- using (RSA rsa = encryptingCertificate.GetRSAPrivateKey())
+ int inputBlockSize = GetCipherTextBlockSize(rsa, useOaep);
+ int outputBlockSize = GetPlainTextBlockSize(rsa, useOaep);
+
+ // verify the input data is the correct block size.
+ if (dataToDecrypt.Count % inputBlockSize != 0)
{
- if (rsa == null)
+ Utils.Trace("Message is not an integral multiple of the block size. Length = {0}, BlockSize = {1}.", dataToDecrypt.Count, inputBlockSize);
+ }
+
+ byte[] decryptedBuffer = outputBuffer.Array;
+
+ using (MemoryStream ostrm = new MemoryStream(
+ decryptedBuffer,
+ outputBuffer.Offset,
+ outputBuffer.Count))
+ {
+
+ // decrypt body.
+ byte[] input = new byte[inputBlockSize];
+
+ for (int ii = dataToDecrypt.Offset; ii < dataToDecrypt.Offset + dataToDecrypt.Count; ii += inputBlockSize)
{
- throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
- }
-
- int inputBlockSize = rsa.KeySize / 8;
- int outputBlockSize = GetPlainTextBlockSize(encryptingCertificate, useOaep);
-
- // verify the input data is the correct block size.
- if (dataToDecrypt.Count % inputBlockSize != 0)
- {
- Utils.Trace("Message is not an integral multiple of the block size. Length = {0}, BlockSize = {1}.", dataToDecrypt.Count, inputBlockSize);
- }
-
- byte[] decryptedBuffer = outputBuffer.Array;
-
- using (MemoryStream ostrm = new MemoryStream(
- decryptedBuffer,
- outputBuffer.Offset,
- outputBuffer.Count))
- {
-
- // decrypt body.
- byte[] input = new byte[inputBlockSize];
-
- for (int ii = dataToDecrypt.Offset; ii < dataToDecrypt.Offset + dataToDecrypt.Count; ii += inputBlockSize)
+ Array.Copy(dataToDecrypt.Array, ii, input, 0, input.Length);
+ if (useOaep == true)
{
- Array.Copy(dataToDecrypt.Array, ii, input, 0, input.Length);
- if (useOaep == true)
- {
- byte[] plainText = rsa.Decrypt(input, RSAEncryptionPadding.OaepSHA1);
- ostrm.Write(plainText, 0, plainText.Length);
- }
- else
- {
- byte[] plainText = rsa.Decrypt(input, RSAEncryptionPadding.Pkcs1);
- ostrm.Write(plainText, 0, plainText.Length);
- }
+ byte[] plainText = rsa.Decrypt(input, RSAEncryptionPadding.OaepSHA1);
+ ostrm.Write(plainText, 0, plainText.Length);
+ }
+ else
+ {
+ byte[] plainText = rsa.Decrypt(input, RSAEncryptionPadding.Pkcs1);
+ ostrm.Write(plainText, 0, plainText.Length);
}
}
-
- // return buffers.
- return new ArraySegment(decryptedBuffer, outputBuffer.Offset, (dataToDecrypt.Count / inputBlockSize) * outputBlockSize);
}
+
+ // return buffers.
+ return new ArraySegment(decryptedBuffer, outputBuffer.Offset, (dataToDecrypt.Count / inputBlockSize) * outputBlockSize);
}
#endregion
}
diff --git a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Asymmetric.cs b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Asymmetric.cs
index e248a2661a..8d5dac16a1 100644
--- a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Asymmetric.cs
+++ b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Asymmetric.cs
@@ -29,8 +29,8 @@ namespace Opc.Ua.Bindings
///
public EndpointDescription EndpointDescription
{
- get
- {
+ get
+ {
lock (DataLock)
{
return m_selectedEndpoint;
@@ -55,7 +55,7 @@ namespace Opc.Ua.Bindings
{
get { return m_serverCertificate; }
}
-
+
///
/// The security mode used with the channel.
///
@@ -63,7 +63,7 @@ namespace Opc.Ua.Bindings
{
get { return m_securityMode; }
}
-
+
///
/// The security policy used with the channel.
///
@@ -71,24 +71,24 @@ namespace Opc.Ua.Bindings
{
get { return m_securityPolicyUri; }
}
-
+
///
/// Whether the channel is restricted to discovery operations.
///
protected bool DiscoveryOnly
{
- get
- {
- return m_discoveryOnly;
+ get
+ {
+ return m_discoveryOnly;
}
}
-
+
///
/// The certificate for the client.
///
protected X509Certificate2 ClientCertificate
{
- get { return m_clientCertificate; }
+ get { return m_clientCertificate; }
set { m_clientCertificate = value; }
}
@@ -116,7 +116,7 @@ namespace Opc.Ua.Bindings
return null;
}
- StringBuilder builder = new StringBuilder(thumbprint.Length*2);
+ StringBuilder builder = new StringBuilder(thumbprint.Length * 2);
for (int ii = 0; ii < thumbprint.Length; ii++)
{
@@ -136,27 +136,27 @@ namespace Opc.Ua.Bindings
return null;
}
- byte[] bytes = new byte[thumbprint.Length/2];
+ byte[] bytes = new byte[thumbprint.Length / 2];
- for (int ii = 0; ii < thumbprint.Length-1; ii += 2)
+ for (int ii = 0; ii < thumbprint.Length - 1; ii += 2)
{
- bytes[ii/2] = Convert.ToByte(thumbprint.Substring(ii, 2), 16);
+ bytes[ii / 2] = Convert.ToByte(thumbprint.Substring(ii, 2), 16);
}
return bytes;
}
-
+
///
/// Compares two certificates.
///
protected static void CompareCertificates(X509Certificate2 expected, X509Certificate2 actual, bool allowNull)
{
bool equal = true;
-
+
if (expected == null)
{
equal = actual == null;
-
+
// accept everything if no expected certificate and nulls are allowed.
if (allowNull)
{
@@ -175,7 +175,7 @@ namespace Opc.Ua.Bindings
if (!equal)
{
throw ServiceResultException.Create(
- StatusCodes.BadCertificateInvalid,
+ StatusCodes.BadCertificateInvalid,
"Certificate mismatch. Expecting '{0}'/{1},. Received '{2}'/{3}.",
(expected != null) ? expected.Subject : "(null)",
(expected != null) ? expected.Thumbprint : "(null)",
@@ -183,9 +183,9 @@ namespace Opc.Ua.Bindings
(actual != null) ? actual.Thumbprint : "(null)");
}
}
-#endregion
+ #endregion
-#region Asymmetric Cryptography Functions
+ #region Asymmetric Cryptography Functions
///
/// Returns the length of the symmetric encryption key.
///
@@ -194,21 +194,21 @@ namespace Opc.Ua.Bindings
switch (SecurityPolicyUri)
{
case SecurityPolicies.Basic128Rsa15:
- {
- return 16;
- }
+ {
+ return 16;
+ }
case SecurityPolicies.Basic256:
case SecurityPolicies.Basic256Sha256:
- {
- return 32;
- }
+ {
+ return 32;
+ }
default:
case SecurityPolicies.None:
- {
- return 0;
- }
+ {
+ return 0;
+ }
}
}
@@ -237,7 +237,7 @@ namespace Opc.Ua.Bindings
return true;
}
}
-
+
return false;
}
@@ -251,19 +251,19 @@ namespace Opc.Ua.Bindings
case SecurityPolicies.Basic256:
case SecurityPolicies.Basic256Sha256:
{
- return Rsa_GetPlainTextBlockSize(receiverCertificate, true);
+ return RsaUtils.GetPlainTextBlockSize(receiverCertificate, true);
}
case SecurityPolicies.Basic128Rsa15:
{
- return Rsa_GetPlainTextBlockSize(receiverCertificate, false);
+ return RsaUtils.GetPlainTextBlockSize(receiverCertificate, false);
}
default:
case SecurityPolicies.None:
- {
- return 1;
- }
+ {
+ return 1;
+ }
}
}
@@ -277,19 +277,19 @@ namespace Opc.Ua.Bindings
case SecurityPolicies.Basic256:
case SecurityPolicies.Basic256Sha256:
{
- return Rsa_GetCipherTextBlockSize(receiverCertificate, true);
+ return RsaUtils.GetCipherTextBlockSize(receiverCertificate, true);
}
case SecurityPolicies.Basic128Rsa15:
{
- return Rsa_GetCipherTextBlockSize(receiverCertificate, false);
+ return RsaUtils.GetCipherTextBlockSize(receiverCertificate, false);
}
default:
case SecurityPolicies.None:
- {
- return 1;
- }
+ {
+ return 1;
+ }
}
}
@@ -297,9 +297,9 @@ namespace Opc.Ua.Bindings
/// Calculates the size of the asymmetric security header.
///
protected int GetAsymmetricHeaderSize(
- string securityPolicyUri,
+ string securityPolicyUri,
X509Certificate2 senderCertificate)
- {
+ {
int headerSize = 0;
headerSize += TcpMessageLimits.BaseHeaderSize;
@@ -322,7 +322,7 @@ namespace Opc.Ua.Bindings
if (headerSize >= SendBufferSize - TcpMessageLimits.SequenceHeaderSize - GetAsymmetricSignatureSize(senderCertificate) - 1)
{
throw ServiceResultException.Create(
- StatusCodes.BadInternalError,
+ StatusCodes.BadInternalError,
"AsymmetricSecurityHeader is {0} bytes which is too large for the send buffer size of {1} bytes.",
headerSize,
SendBufferSize);
@@ -366,7 +366,7 @@ namespace Opc.Ua.Bindings
return headerSize;
}
-
+
///
/// Calculates the size of the footer with an asymmetric signature.
///
@@ -377,15 +377,15 @@ namespace Opc.Ua.Bindings
case SecurityPolicies.Basic128Rsa15:
case SecurityPolicies.Basic256:
case SecurityPolicies.Basic256Sha256:
- {
- return RsaPkcs15_GetSignatureLength(senderCertificate);
- }
+ {
+ return RsaUtils.GetSignatureLength(senderCertificate);
+ }
default:
case SecurityPolicies.None:
- {
- return 0;
- }
+ {
+ return 0;
+ }
}
}
@@ -393,12 +393,12 @@ namespace Opc.Ua.Bindings
/// Writes the asymmetric security header to the buffer.
///
protected void WriteAsymmetricMessageHeader(
- BinaryEncoder encoder,
- uint messageType,
- uint secureChannelId,
- string securityPolicyUri,
- X509Certificate2 senderCertificate,
- X509Certificate2 receiverCertificate)
+ BinaryEncoder encoder,
+ uint messageType,
+ uint secureChannelId,
+ string securityPolicyUri,
+ X509Certificate2 senderCertificate,
+ X509Certificate2 receiverCertificate)
{
int start = encoder.Position;
@@ -417,11 +417,11 @@ namespace Opc.Ua.Bindings
encoder.WriteByteString(null, null);
encoder.WriteByteString(null, null);
}
-
+
if (encoder.Position - start > SendBufferSize)
{
throw ServiceResultException.Create(
- StatusCodes.BadInternalError,
+ StatusCodes.BadInternalError,
"AsymmetricSecurityHeader is {0} bytes which is too large for the send buffer size of {1} bytes.",
encoder.Position - start,
SendBufferSize);
@@ -455,12 +455,12 @@ namespace Opc.Ua.Bindings
/// Sends a OpenSecureChannel response.
///
protected BufferCollection WriteAsymmetricMessage(
- uint messageType,
- uint requestId,
- X509Certificate2 senderCertificate,
- X509Certificate2 receiverCertificate,
+ uint messageType,
+ uint requestId,
+ X509Certificate2 senderCertificate,
+ X509Certificate2 receiverCertificate,
ArraySegment messageBody)
- {
+ {
bool success = false;
BufferCollection chunksToSend = new BufferCollection();
@@ -470,7 +470,7 @@ namespace Opc.Ua.Bindings
{
int headerSize = GetAsymmetricHeaderSize(SecurityPolicyUri, senderCertificate);
int signatureSize = GetAsymmetricSignatureSize(senderCertificate);
-
+
BinaryEncoder encoder = new BinaryEncoder(buffer, 0, SendBufferSize, Quotas.MessageContext);
WriteAsymmetricMessageHeader(
@@ -480,16 +480,16 @@ namespace Opc.Ua.Bindings
SecurityPolicyUri,
senderCertificate,
receiverCertificate);
-
+
// save the header.
ArraySegment header = new ArraySegment(buffer, 0, headerSize);
-
+
// calculate the space available.
int plainTextBlockSize = GetPlainTextBlockSize(receiverCertificate);
int cipherTextBlockSize = GetCipherTextBlockSize(receiverCertificate);
int maxCipherTextSize = SendBufferSize - headerSize;
- int maxCipherBlocks = maxCipherTextSize/cipherTextBlockSize;
- int maxPlainTextSize = maxCipherBlocks*plainTextBlockSize;
+ int maxCipherBlocks = maxCipherTextSize / cipherTextBlockSize;
+ int maxPlainTextSize = maxCipherBlocks * plainTextBlockSize;
int maxPayloadSize = maxPlainTextSize - signatureSize - 1 - TcpMessageLimits.SequenceHeaderSize;
int bytesToWrite = messageBody.Count;
@@ -512,11 +512,11 @@ namespace Opc.Ua.Bindings
}
// write the message body.
- encoder.WriteRawBytes(messageBody.Array, messageBody.Offset+startOfBytes, payloadSize);
+ encoder.WriteRawBytes(messageBody.Array, messageBody.Offset + startOfBytes, payloadSize);
// calculate the amount of plain text to encrypt.
int plainTextSize = encoder.Position - headerSize + signatureSize;
-
+
// calculate the padding.
int padding = 0;
@@ -566,28 +566,28 @@ namespace Opc.Ua.Bindings
}
// calculate the number of block to encrypt.
- int encryptedBlocks = plainTextSize/plainTextBlockSize;
+ int encryptedBlocks = plainTextSize / plainTextBlockSize;
// calculate the size of the encrypted data.
- int cipherTextSize = encryptedBlocks*cipherTextBlockSize;
-
+ int cipherTextSize = encryptedBlocks * cipherTextBlockSize;
+
// put the message size after encryption into the header.
UpdateMessageSize(buffer, 0, cipherTextSize + headerSize);
// write the signature.
byte[] signature = Sign(new ArraySegment(buffer, 0, encoder.Position), senderCertificate);
-
+
if (signature != null)
{
encoder.WriteRawBytes(signature, 0, signature.Length);
}
-
+
int messageSize = encoder.Close();
// encrypt the data.
ArraySegment encryptedBuffer = Encrypt(
- new ArraySegment(buffer, headerSize, messageSize-headerSize),
- header,
+ new ArraySegment(buffer, headerSize, messageSize - headerSize),
+ header,
receiverCertificate);
// check for math errors due to code bugs.
@@ -621,7 +621,7 @@ namespace Opc.Ua.Bindings
}
finally
{
- BufferManager.ReturnBuffer(buffer, "WriteAsymmetricMessage");
+ BufferManager.ReturnBuffer(buffer, "WriteAsymmetricMessage");
if (!success)
{
@@ -635,12 +635,12 @@ namespace Opc.Ua.Bindings
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "messageType"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "messageSize")]
protected void ReadAsymmetricMessageHeader(
- BinaryDecoder decoder,
- X509Certificate2 receiverCertificate,
- out uint secureChannelId,
+ BinaryDecoder decoder,
+ X509Certificate2 receiverCertificate,
+ out uint secureChannelId,
out X509Certificate2 senderCertificate,
- out string securityPolicyUri)
- {
+ out string securityPolicyUri)
+ {
senderCertificate = null;
uint messageType = decoder.ReadUInt32(null);
@@ -660,11 +660,11 @@ namespace Opc.Ua.Bindings
catch (Exception e)
{
throw ServiceResultException.Create(
- StatusCodes.BadSecurityChecksFailed,
+ StatusCodes.BadSecurityChecksFailed,
e,
"The asymmetric security header could not be parsed.");
}
-
+
// verify sender certificate.
if (certificateData != null && certificateData.Length > 0)
{
@@ -714,7 +714,7 @@ namespace Opc.Ua.Bindings
///
protected void ReviseSecurityMode(bool firstCall, MessageSecurityMode requestedMode)
{
- bool supported = false;
+ bool supported = false;
// server may support multiple security modes - check if the one the client used is supported.
if (firstCall && !m_discoveryOnly)
@@ -723,7 +723,7 @@ namespace Opc.Ua.Bindings
{
if (endpoint.SecurityMode == requestedMode)
{
- if (requestedMode == MessageSecurityMode.None ||
+ if (requestedMode == MessageSecurityMode.None ||
endpoint.SecurityPolicyUri == m_securityPolicyUri)
{
m_securityMode = endpoint.SecurityMode;
@@ -740,7 +740,7 @@ namespace Opc.Ua.Bindings
throw ServiceResultException.Create(StatusCodes.BadSecurityModeRejected, "Security mode is not acceptable to the server.");
}
}
-
+
///
/// Sets to endpoint according to the endpoint url.
///
@@ -780,15 +780,15 @@ namespace Opc.Ua.Bindings
/// Processes an OpenSecureChannel request message.
///
protected ArraySegment ReadAsymmetricMessage(
- ArraySegment buffer,
- X509Certificate2 receiverCertificate,
- out uint channelId,
+ ArraySegment buffer,
+ X509Certificate2 receiverCertificate,
+ out uint channelId,
out X509Certificate2 senderCertificate,
- out uint requestId,
- out uint sequenceNumber)
- {
+ out uint requestId,
+ out uint sequenceNumber)
+ {
BinaryDecoder decoder = new BinaryDecoder(buffer.Array, buffer.Offset, buffer.Count, Quotas.MessageContext);
-
+
string securityPolicyUri = null;
// parse the security header.
@@ -804,7 +804,7 @@ namespace Opc.Ua.Bindings
{
Quotas.CertificateValidator.Validate(senderCertificate);
}
-
+
// check if this is the first open secure channel request.
if (!m_uninitialized)
{
@@ -819,25 +819,25 @@ namespace Opc.Ua.Bindings
if (m_endpoints != null)
{
foreach (EndpointDescription endpoint in m_endpoints)
- {
+ {
// There may be multiple endpoints with the same securityPolicyUri.
// Just choose the first one that matches. This choice will be re-examined
// When the OpenSecureChannel request body is processed.
if (endpoint.SecurityPolicyUri == securityPolicyUri || (securityPolicyUri == SecurityPolicies.None && endpoint.SecurityMode == MessageSecurityMode.None))
{
- m_securityMode = endpoint.SecurityMode;
+ m_securityMode = endpoint.SecurityMode;
m_securityPolicyUri = securityPolicyUri;
- m_discoveryOnly = false;
- m_uninitialized = false;
- m_selectedEndpoint = endpoint;
-
+ m_discoveryOnly = false;
+ m_uninitialized = false;
+ m_selectedEndpoint = endpoint;
+
// recalculate the key sizes.
CalculateSymmetricKeySizes();
break;
}
}
}
-
+
// allow a discovery only channel with no security if policy not suppported
if (m_uninitialized)
{
@@ -846,11 +846,11 @@ namespace Opc.Ua.Bindings
throw ServiceResultException.Create(StatusCodes.BadSecurityPolicyRejected, "The security policy is not supported.");
}
- m_securityMode = MessageSecurityMode.None;
+ m_securityMode = MessageSecurityMode.None;
m_securityPolicyUri = SecurityPolicies.None;
- m_discoveryOnly = true;
- m_uninitialized = false;
- m_selectedEndpoint = null;
+ m_discoveryOnly = true;
+ m_uninitialized = false;
+ m_selectedEndpoint = null;
}
}
@@ -861,7 +861,7 @@ namespace Opc.Ua.Bindings
new ArraySegment(buffer.Array, buffer.Offset + headerSize, buffer.Count - headerSize),
new ArraySegment(buffer.Array, buffer.Offset, headerSize),
receiverCertificate);
-
+
// extract signature.
int signatureSize = GetAsymmetricSignatureSize(senderCertificate);
@@ -869,14 +869,14 @@ namespace Opc.Ua.Bindings
for (int ii = 0; ii < signatureSize; ii++)
{
- signature[ii] = plainText.Array[plainText.Offset+plainText.Count-signatureSize+ii];
+ signature[ii] = plainText.Array[plainText.Offset + plainText.Count - signatureSize + ii];
}
-
+
// verify the signature.
- ArraySegment dataToVerify = new ArraySegment(plainText.Array, plainText.Offset, plainText.Count-signatureSize);
-
+ ArraySegment dataToVerify = new ArraySegment(plainText.Array, plainText.Offset, plainText.Count - signatureSize);
+
if (!Verify(dataToVerify, signature, senderCertificate))
- {
+ {
Utils.Trace("Could not verify signature on message.");
throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "Could not verify the signature on the message.");
}
@@ -920,11 +920,11 @@ namespace Opc.Ua.Bindings
// decode message.
decoder = new BinaryDecoder(
- plainText.Array,
- plainText.Offset + headerSize,
- plainText.Count - headerSize,
+ plainText.Array,
+ plainText.Offset + headerSize,
+ plainText.Count - headerSize,
Quotas.MessageContext);
-
+
sequenceNumber = decoder.ReadUInt32(null);
requestId = decoder.ReadUInt32(null);
@@ -932,12 +932,12 @@ namespace Opc.Ua.Bindings
decoder.Close();
Utils.Trace("Security Policy: {0}", SecurityPolicyUri);
- Utils.Trace("Sender Certificate: {0}", (senderCertificate != null)?senderCertificate.Subject:"(none)");
+ Utils.Trace("Sender Certificate: {0}", (senderCertificate != null) ? senderCertificate.Subject : "(none)");
// return the body.
return new ArraySegment(
- plainText.Array,
- plainText.Offset + headerSize,
+ plainText.Array,
+ plainText.Offset + headerSize,
plainText.Count - headerSize - signatureSize - paddingCount);
}
@@ -950,26 +950,26 @@ namespace Opc.Ua.Bindings
///
protected byte[] Sign(
ArraySegment dataToSign,
- X509Certificate2 senderCertificate)
+ X509Certificate2 senderCertificate)
{
switch (SecurityPolicyUri)
{
default:
case SecurityPolicies.None:
- {
- return null;
- }
+ {
+ return null;
+ }
case SecurityPolicies.Basic256:
case SecurityPolicies.Basic128Rsa15:
- {
- return RsaPkcs15_Sign(dataToSign, senderCertificate, HashAlgorithmName.SHA1);
- }
+ {
+ return RsaPkcs15_Sign(dataToSign, senderCertificate, HashAlgorithmName.SHA1);
+ }
case SecurityPolicies.Basic256Sha256:
- {
- return RsaPkcs15_Sign(dataToSign, senderCertificate, HashAlgorithmName.SHA256);
- }
+ {
+ return RsaPkcs15_Sign(dataToSign, senderCertificate, HashAlgorithmName.SHA256);
+ }
}
}
@@ -983,32 +983,32 @@ namespace Opc.Ua.Bindings
///
protected bool Verify(
ArraySegment dataToVerify,
- byte[] signature,
- X509Certificate2 senderCertificate)
- {
+ byte[] signature,
+ X509Certificate2 senderCertificate)
+ {
// verify signature.
switch (SecurityPolicyUri)
{
case SecurityPolicies.None:
- {
- return true;
- }
+ {
+ return true;
+ }
case SecurityPolicies.Basic128Rsa15:
case SecurityPolicies.Basic256:
- {
- return RsaPkcs15_Verify(dataToVerify, signature, senderCertificate, HashAlgorithmName.SHA1);
- }
+ {
+ return RsaPkcs15_Verify(dataToVerify, signature, senderCertificate, HashAlgorithmName.SHA1);
+ }
case SecurityPolicies.Basic256Sha256:
- {
- return RsaPkcs15_Verify(dataToVerify, signature, senderCertificate, HashAlgorithmName.SHA256);
- }
+ {
+ return RsaPkcs15_Verify(dataToVerify, signature, senderCertificate, HashAlgorithmName.SHA256);
+ }
default:
- {
- return false;
- }
+ {
+ return false;
+ }
}
}
@@ -1023,30 +1023,30 @@ namespace Opc.Ua.Bindings
protected ArraySegment Encrypt(
ArraySegment dataToEncrypt,
ArraySegment headerToCopy,
- X509Certificate2 receiverCertificate)
- {
+ X509Certificate2 receiverCertificate)
+ {
switch (SecurityPolicyUri)
{
default:
case SecurityPolicies.None:
- {
- byte[] encryptedBuffer = BufferManager.TakeBuffer(SendBufferSize, "Encrypt");
+ {
+ byte[] encryptedBuffer = BufferManager.TakeBuffer(SendBufferSize, "Encrypt");
- Array.Copy(headerToCopy.Array, headerToCopy.Offset, encryptedBuffer, 0, headerToCopy.Count);
- Array.Copy(dataToEncrypt.Array, dataToEncrypt.Offset, encryptedBuffer, headerToCopy.Count, dataToEncrypt.Count);
+ Array.Copy(headerToCopy.Array, headerToCopy.Offset, encryptedBuffer, 0, headerToCopy.Count);
+ Array.Copy(dataToEncrypt.Array, dataToEncrypt.Offset, encryptedBuffer, headerToCopy.Count, dataToEncrypt.Count);
- return new ArraySegment(encryptedBuffer, 0, dataToEncrypt.Count+headerToCopy.Count);
- }
+ return new ArraySegment(encryptedBuffer, 0, dataToEncrypt.Count + headerToCopy.Count);
+ }
case SecurityPolicies.Basic256:
case SecurityPolicies.Basic256Sha256:
- {
- return Rsa_Encrypt(dataToEncrypt, headerToCopy, receiverCertificate, true);
- }
+ {
+ return Rsa_Encrypt(dataToEncrypt, headerToCopy, receiverCertificate, true);
+ }
case SecurityPolicies.Basic128Rsa15:
- {
- return Rsa_Encrypt(dataToEncrypt, headerToCopy, receiverCertificate, false);
- }
+ {
+ return Rsa_Encrypt(dataToEncrypt, headerToCopy, receiverCertificate, false);
+ }
}
}
@@ -1060,43 +1060,43 @@ namespace Opc.Ua.Bindings
protected ArraySegment Decrypt(
ArraySegment dataToDecrypt,
ArraySegment headerToCopy,
- X509Certificate2 receiverCertificate)
+ X509Certificate2 receiverCertificate)
{
switch (SecurityPolicyUri)
{
default:
case SecurityPolicies.None:
- {
- byte[] decryptedBuffer = BufferManager.TakeBuffer(SendBufferSize, "Decrypt");
+ {
+ byte[] decryptedBuffer = BufferManager.TakeBuffer(SendBufferSize, "Decrypt");
- Array.Copy(headerToCopy.Array, headerToCopy.Offset, decryptedBuffer, 0, headerToCopy.Count);
- Array.Copy(dataToDecrypt.Array, dataToDecrypt.Offset, decryptedBuffer, headerToCopy.Count, dataToDecrypt.Count);
+ Array.Copy(headerToCopy.Array, headerToCopy.Offset, decryptedBuffer, 0, headerToCopy.Count);
+ Array.Copy(dataToDecrypt.Array, dataToDecrypt.Offset, decryptedBuffer, headerToCopy.Count, dataToDecrypt.Count);
- return new ArraySegment(decryptedBuffer, 0, dataToDecrypt.Count+headerToCopy.Count);
- }
+ return new ArraySegment(decryptedBuffer, 0, dataToDecrypt.Count + headerToCopy.Count);
+ }
case SecurityPolicies.Basic256:
case SecurityPolicies.Basic256Sha256:
- {
- return Rsa_Decrypt(dataToDecrypt, headerToCopy, receiverCertificate, true);
- }
+ {
+ return Rsa_Decrypt(dataToDecrypt, headerToCopy, receiverCertificate, true);
+ }
case SecurityPolicies.Basic128Rsa15:
- {
- return Rsa_Decrypt(dataToDecrypt, headerToCopy, receiverCertificate, false);
- }
+ {
+ return Rsa_Decrypt(dataToDecrypt, headerToCopy, receiverCertificate, false);
+ }
}
}
-#endregion
+ #endregion
-#region Private Fields
+ #region Private Fields
private EndpointDescriptionCollection m_endpoints;
private MessageSecurityMode m_securityMode;
private string m_securityPolicyUri;
private bool m_discoveryOnly;
private EndpointDescription m_selectedEndpoint;
- private X509Certificate2 m_serverCertificate;
+ private X509Certificate2 m_serverCertificate;
private X509Certificate2 m_clientCertificate;
private bool m_uninitialized;
-#endregion
+ #endregion
}
}
diff --git a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Rsa.cs b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Rsa.cs
index cecb7c73d1..b62e7d6424 100644
--- a/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Rsa.cs
+++ b/Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Rsa.cs
@@ -23,57 +23,6 @@ namespace Opc.Ua.Bindings
///
public partial class UaSCUaBinaryChannel
{
- ///
- /// Return the plaintext block size for RSA OAEP encryption.
- ///
- protected static int Rsa_GetPlainTextBlockSize(X509Certificate2 encryptingCertificate, bool useOaep)
- {
- using (RSA rsa = encryptingCertificate.GetRSAPublicKey())
- {
- if (rsa != null)
- {
- if (useOaep)
- {
- return rsa.KeySize / 8 - 42;
- }
- else
- {
- return rsa.KeySize / 8 - 11;
- }
- }
- }
- return -1;
- }
-
- ///
- /// Return the ciphertext block size for RSA OAEP encryption.
- ///
- protected static int Rsa_GetCipherTextBlockSize(X509Certificate2 encryptingCertificate, bool useOaep)
- {
- using (RSA rsa = encryptingCertificate.GetRSAPublicKey())
- {
- if (rsa != null)
- {
- return rsa.KeySize / 8;
- }
- }
- return -1;
- }
-
- ///
- /// Returns the length of a RSA PKCS#1 v1.5 signature.
- ///
- private static int RsaPkcs15_GetSignatureLength(X509Certificate2 signingCertificate)
- {
- using (RSA rsa = signingCertificate.GetRSAPublicKey())
- {
- if (rsa == null)
- {
- throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
- }
- return rsa.KeySize / 8;
- }
- }
///
/// Creates an RSA PKCS#1 v1.5 signature of a hash algorithm for the stream.
@@ -84,16 +33,14 @@ namespace Opc.Ua.Bindings
HashAlgorithmName algorithm)
{
// extract the private key.
- using (RSA rsa = signingCertificate.GetRSAPrivateKey())
+ RSA rsa = signingCertificate.GetRSAPrivateKey();
+ if (rsa == null)
{
- if (rsa == null)
- {
- throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
- }
-
- // create the signature.
- return rsa.SignData(dataToSign.Array, dataToSign.Offset, dataToSign.Count, algorithm, RSASignaturePadding.Pkcs1);
+ throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
}
+
+ // create the signature.
+ return rsa.SignData(dataToSign.Array, dataToSign.Offset, dataToSign.Count, algorithm, RSASignaturePadding.Pkcs1);
}
@@ -102,35 +49,32 @@ namespace Opc.Ua.Bindings
///
private static bool RsaPkcs15_Verify(
ArraySegment dataToVerify,
- byte[] signature,
- X509Certificate2 signingCertificate,
+ byte[] signature,
+ X509Certificate2 signingCertificate,
HashAlgorithmName algorithm)
{
// extract the public key.
- using (RSA rsa = signingCertificate.GetRSAPublicKey())
+ RSA rsa = signingCertificate.GetRSAPublicKey();
+ if (rsa == null)
{
+ throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
+ }
- if (rsa == null)
- {
- throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
- }
+ // verify signature.
+ if (!rsa.VerifyData(dataToVerify.Array, dataToVerify.Offset, dataToVerify.Count, signature, algorithm, RSASignaturePadding.Pkcs1))
+ {
+ string messageType = new UTF8Encoding().GetString(dataToVerify.Array, dataToVerify.Offset, 4);
+ int messageLength = BitConverter.ToInt32(dataToVerify.Array, dataToVerify.Offset + 4);
+ string actualSignature = Utils.ToHexString(signature);
- // verify signature.
- if (!rsa.VerifyData(dataToVerify.Array, dataToVerify.Offset, dataToVerify.Count, signature, algorithm, RSASignaturePadding.Pkcs1))
- {
- string messageType = new UTF8Encoding().GetString(dataToVerify.Array, dataToVerify.Offset, 4);
- int messageLength = BitConverter.ToInt32(dataToVerify.Array, dataToVerify.Offset + 4);
- string actualSignature = Utils.ToHexString(signature);
+ Utils.Trace(
+ "Could not validate signature.\r\nCertificate={0}, MessageType={1}, Length={2}\r\nActualSignature={3}",
+ signingCertificate.Subject,
+ messageType,
+ messageLength,
+ actualSignature);
- Utils.Trace(
- "Could not validate signature.\r\nCertificate={0}, MessageType={1}, Length={2}\r\nActualSignature={3}",
- signingCertificate.Subject,
- messageType,
- messageLength,
- actualSignature);
-
- return false;
- }
+ return false;
}
return true;
}
@@ -141,56 +85,54 @@ namespace Opc.Ua.Bindings
private ArraySegment Rsa_Encrypt(
ArraySegment dataToEncrypt,
ArraySegment headerToCopy,
- X509Certificate2 encryptingCertificate,
- bool useOaep)
+ X509Certificate2 encryptingCertificate,
+ bool useOaep)
{
// get the encrypting key.
- using (RSA rsa = encryptingCertificate.GetRSAPublicKey())
+ RSA rsa = encryptingCertificate.GetRSAPublicKey();
+ if (rsa == null)
{
- if (rsa == null)
+ throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
+ }
+
+ int inputBlockSize = RsaUtils.GetPlainTextBlockSize(rsa, useOaep);
+ int outputBlockSize = RsaUtils.GetCipherTextBlockSize(rsa, useOaep);
+
+ // verify the input data is the correct block size.
+ if (dataToEncrypt.Count % inputBlockSize != 0)
+ {
+ Utils.Trace("Message is not an integral multiple of the block size. Length = {0}, BlockSize = {1}.", dataToEncrypt.Count, inputBlockSize);
+ }
+
+ byte[] encryptedBuffer = BufferManager.TakeBuffer(SendBufferSize, "Rsa_Encrypt");
+ Array.Copy(headerToCopy.Array, headerToCopy.Offset, encryptedBuffer, 0, headerToCopy.Count);
+
+ using (MemoryStream ostrm = new MemoryStream(
+ encryptedBuffer,
+ headerToCopy.Count,
+ encryptedBuffer.Length - headerToCopy.Count))
+ {
+
+ // encrypt body.
+ byte[] input = new byte[inputBlockSize];
+
+ for (int ii = dataToEncrypt.Offset; ii < dataToEncrypt.Offset + dataToEncrypt.Count; ii += inputBlockSize)
{
- throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No public key for certificate.");
- }
-
- int inputBlockSize = Rsa_GetPlainTextBlockSize(encryptingCertificate, useOaep);
- int outputBlockSize = rsa.KeySize / 8;
-
- // verify the input data is the correct block size.
- if (dataToEncrypt.Count % inputBlockSize != 0)
- {
- Utils.Trace("Message is not an integral multiple of the block size. Length = {0}, BlockSize = {1}.", dataToEncrypt.Count, inputBlockSize);
- }
-
- byte[] encryptedBuffer = BufferManager.TakeBuffer(SendBufferSize, "Rsa_Encrypt");
- Array.Copy(headerToCopy.Array, headerToCopy.Offset, encryptedBuffer, 0, headerToCopy.Count);
-
- using (MemoryStream ostrm = new MemoryStream(
- encryptedBuffer,
- headerToCopy.Count,
- encryptedBuffer.Length - headerToCopy.Count))
- {
-
- // encrypt body.
- byte[] input = new byte[inputBlockSize];
-
- for (int ii = dataToEncrypt.Offset; ii < dataToEncrypt.Offset + dataToEncrypt.Count; ii += inputBlockSize)
+ Array.Copy(dataToEncrypt.Array, ii, input, 0, input.Length);
+ if (useOaep == true)
{
- Array.Copy(dataToEncrypt.Array, ii, input, 0, input.Length);
- if (useOaep == true)
- {
- byte[] cipherText = rsa.Encrypt(input, RSAEncryptionPadding.OaepSHA1);
- ostrm.Write(cipherText, 0, cipherText.Length);
- }
- else
- {
- byte[] cipherText = rsa.Encrypt(input, RSAEncryptionPadding.Pkcs1);
- ostrm.Write(cipherText, 0, cipherText.Length);
- }
+ byte[] cipherText = rsa.Encrypt(input, RSAEncryptionPadding.OaepSHA1);
+ ostrm.Write(cipherText, 0, cipherText.Length);
+ }
+ else
+ {
+ byte[] cipherText = rsa.Encrypt(input, RSAEncryptionPadding.Pkcs1);
+ ostrm.Write(cipherText, 0, cipherText.Length);
}
}
- // return buffer
- return new ArraySegment(encryptedBuffer, 0, (dataToEncrypt.Count / inputBlockSize) * outputBlockSize + headerToCopy.Count);
}
+ // return buffer
+ return new ArraySegment(encryptedBuffer, 0, (dataToEncrypt.Count / inputBlockSize) * outputBlockSize + headerToCopy.Count);
}
///
@@ -199,58 +141,55 @@ namespace Opc.Ua.Bindings
private ArraySegment Rsa_Decrypt(
ArraySegment dataToDecrypt,
ArraySegment headerToCopy,
- X509Certificate2 encryptingCertificate,
- bool useOaep)
+ X509Certificate2 encryptingCertificate,
+ bool useOaep)
{
// get the encrypting key.
- using (RSA rsa = encryptingCertificate.GetRSAPrivateKey())
+ RSA rsa = encryptingCertificate.GetRSAPrivateKey();
+ if (rsa == null)
+ {
+ throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
+ }
+
+ int inputBlockSize = RsaUtils.GetCipherTextBlockSize(rsa, useOaep);
+ int outputBlockSize = RsaUtils.GetPlainTextBlockSize(rsa, useOaep);
+
+ // verify the input data is the correct block size.
+ if (dataToDecrypt.Count % inputBlockSize != 0)
+ {
+ Utils.Trace("Message is not an integral multiple of the block size. Length = {0}, BlockSize = {1}.", dataToDecrypt.Count, inputBlockSize);
+ }
+
+ byte[] decryptedBuffer = BufferManager.TakeBuffer(SendBufferSize, "Rsa_Decrypt");
+ Array.Copy(headerToCopy.Array, headerToCopy.Offset, decryptedBuffer, 0, headerToCopy.Count);
+
+ using (MemoryStream ostrm = new MemoryStream(
+ decryptedBuffer,
+ headerToCopy.Count,
+ decryptedBuffer.Length - headerToCopy.Count))
{
- if (rsa == null)
+ // decrypt body.
+ byte[] input = new byte[inputBlockSize];
+
+ for (int ii = dataToDecrypt.Offset; ii < dataToDecrypt.Offset + dataToDecrypt.Count; ii += inputBlockSize)
{
- throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
- }
-
- int inputBlockSize = rsa.KeySize / 8;
- int outputBlockSize = Rsa_GetPlainTextBlockSize(encryptingCertificate, useOaep);
-
- // verify the input data is the correct block size.
- if (dataToDecrypt.Count % inputBlockSize != 0)
- {
- Utils.Trace("Message is not an integral multiple of the block size. Length = {0}, BlockSize = {1}.", dataToDecrypt.Count, inputBlockSize);
- }
-
- byte[] decryptedBuffer = BufferManager.TakeBuffer(SendBufferSize, "Rsa_Decrypt");
- Array.Copy(headerToCopy.Array, headerToCopy.Offset, decryptedBuffer, 0, headerToCopy.Count);
-
- using (MemoryStream ostrm = new MemoryStream(
- decryptedBuffer,
- headerToCopy.Count,
- decryptedBuffer.Length - headerToCopy.Count))
- {
-
- // decrypt body.
- byte[] input = new byte[inputBlockSize];
-
- for (int ii = dataToDecrypt.Offset; ii < dataToDecrypt.Offset + dataToDecrypt.Count; ii += inputBlockSize)
+ Array.Copy(dataToDecrypt.Array, ii, input, 0, input.Length);
+ if (useOaep == true)
{
- Array.Copy(dataToDecrypt.Array, ii, input, 0, input.Length);
- if (useOaep == true)
- {
- byte[] plainText = rsa.Decrypt(input, RSAEncryptionPadding.OaepSHA1);
- ostrm.Write(plainText, 0, plainText.Length);
- }
- else
- {
- byte[] plainText = rsa.Decrypt(input, RSAEncryptionPadding.Pkcs1);
- ostrm.Write(plainText, 0, plainText.Length);
- }
+ byte[] plainText = rsa.Decrypt(input, RSAEncryptionPadding.OaepSHA1);
+ ostrm.Write(plainText, 0, plainText.Length);
+ }
+ else
+ {
+ byte[] plainText = rsa.Decrypt(input, RSAEncryptionPadding.Pkcs1);
+ ostrm.Write(plainText, 0, plainText.Length);
}
}
-
- // return buffers.
- return new ArraySegment(decryptedBuffer, 0, (dataToDecrypt.Count / inputBlockSize) * outputBlockSize + headerToCopy.Count);
}
+
+ // return buffers.
+ return new ArraySegment(decryptedBuffer, 0, (dataToDecrypt.Count / inputBlockSize) * outputBlockSize + headerToCopy.Count);
}
}
}