diff --git a/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/PEMReader.cs b/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/PEMReader.cs
index 17249e2c8..2d2666947 100644
--- a/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/PEMReader.cs
+++ b/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/PEMReader.cs
@@ -35,6 +35,7 @@
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Parameters;
+using Opc.Ua.Security.Certificates.BouncyCastle;
namespace Opc.Ua.Security.Certificates
{
@@ -168,9 +169,9 @@ private static ECDsa CreateECDsaFromECPrivateKey(ECPrivateKeyParameters eCPrivat
var d = eCPrivateKeyParameters.D.ToByteArrayUnsigned();
// pad all to the same length since ToByteArrayUnsigned might drop leading zeroes
- x = PadWithLeadingZeros(x, keySizeBytes);
- y = PadWithLeadingZeros(y, keySizeBytes);
- d = PadWithLeadingZeros(d, keySizeBytes);
+ x = X509Utils.PadWithLeadingZeros(x, keySizeBytes);
+ y = X509Utils.PadWithLeadingZeros(y, keySizeBytes);
+ d = X509Utils.PadWithLeadingZeros(d, keySizeBytes);
var ecParams = new ECParameters {
@@ -190,34 +191,6 @@ private static ECDsa CreateECDsaFromECPrivateKey(ECPrivateKeyParameters eCPrivat
}
#endif
- ///
- /// Pads a byte array with leading zeros to reach the specifieed size
- /// If the input is allready the given size, it just returns it
- ///
- /// Provided array to pad
- /// The desired total length of byte array after padding
- ///
- private static byte[] PadWithLeadingZeros(byte[] arrayToPad, int desiredSize)
- {
- if (arrayToPad.Length == desiredSize)
- {
- return arrayToPad;
- }
-
- int paddingLength = desiredSize - arrayToPad.Length;
- if (paddingLength < 0)
- {
- throw new ArgumentException($"Input byte array is larger than the desired size {desiredSize} bytes.");
- }
-
- var paddedArray = new byte[desiredSize];
-
- // Right-align the arrayToPad into paddedArray
- Buffer.BlockCopy(arrayToPad, 0, paddedArray, paddingLength, arrayToPad.Length);
-
- return paddedArray;
-
- }
#endregion
#region Internal class
diff --git a/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/X509Utils.cs b/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/X509Utils.cs
index f125728a2..ca17f0833 100644
--- a/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/X509Utils.cs
+++ b/Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/X509Utils.cs
@@ -370,6 +370,35 @@ internal static RSA SetRSAPublicKey(byte[] publicKey)
rsaPublicKey.ImportParameters(parameters);
return rsaPublicKey;
}
+
+ ///
+ /// Pads a byte array with leading zeros to reach the specifieed size
+ /// If the input is allready the given size, it just returns it
+ ///
+ /// Provided array to pad
+ /// The desired total length of byte array after padding
+ ///
+ internal static byte[] PadWithLeadingZeros(byte[] arrayToPad, int desiredSize)
+ {
+ if (arrayToPad.Length == desiredSize)
+ {
+ return arrayToPad;
+ }
+
+ int paddingLength = desiredSize - arrayToPad.Length;
+ if (paddingLength < 0)
+ {
+ throw new ArgumentException($"Input byte array is larger than the desired size {desiredSize} bytes.");
+ }
+
+ var paddedArray = new byte[desiredSize];
+
+ // Right-align the arrayToPad into paddedArray
+ Buffer.BlockCopy(arrayToPad, 0, paddedArray, paddingLength, arrayToPad.Length);
+
+ return paddedArray;
+
+ }
#endregion
}
}
diff --git a/Libraries/Opc.Ua.Security.Certificates/X509Certificate/CertificateBuilder.cs b/Libraries/Opc.Ua.Security.Certificates/X509Certificate/CertificateBuilder.cs
index de8480f04..fe4e49861 100644
--- a/Libraries/Opc.Ua.Security.Certificates/X509Certificate/CertificateBuilder.cs
+++ b/Libraries/Opc.Ua.Security.Certificates/X509Certificate/CertificateBuilder.cs
@@ -42,6 +42,7 @@
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Math.EC;
+using Opc.Ua.Security.Certificates.BouncyCastle;
#endif
namespace Opc.Ua.Security.Certificates
@@ -297,35 +298,36 @@ public override ICertificateBuilderCreateForECDsaAny SetECDsaPublicKey(byte[] pu
var publicKeyInfo = SubjectPublicKeyInfo.GetInstance(asn1Obj);
var algParams = publicKeyInfo.Algorithm.Parameters;
var x962Params = X962Parameters.GetInstance(algParams);
- var ecPoint = publicKeyInfo.PublicKey.GetBytes();
ECParameters ecParameters = new ECParameters();
- X9ECParameters ecParametersAsn1 = null;
+
+ var domainParameters = asymmetricPubKeyParameters.Parameters;
+ var q = asymmetricPubKeyParameters.Q;
+ // calculate keySize round up (bitLength + 7) / 8
+ int keySizeBytes = (domainParameters.N.BitLength + 7) / 8;
if (x962Params.IsNamedCurve)
{
// Named
var namedCurveOid = (DerObjectIdentifier)x962Params.Parameters;
string curveName = namedCurveOid.Id;
-
var ecCurve = System.Security.Cryptography.ECCurve.CreateFromOid(new Oid(curveName));
ecParameters.Curve = ecCurve;
}
else
{
- // Explicit but still need to create the curve as named since the platform does not support it's creation
- // otherwise
- ecParametersAsn1 = X9ECParameters.GetInstance(x962Params.Parameters);
- ecParameters.Curve = BouncyCastle.X509Utils.IdentifyEccCurveByCoefficients(ecParametersAsn1.Curve.A.GetEncoded(),
- ecParametersAsn1.Curve.B.GetEncoded());// instead of ecParametersAsn1.Curve;
-
+ // Explicit parameters
+ var a = X509Utils.PadWithLeadingZeros(domainParameters.Curve.A.ToBigInteger().ToByteArrayUnsigned(), keySizeBytes);
+ var b = X509Utils.PadWithLeadingZeros(domainParameters.Curve.B.ToBigInteger().ToByteArrayUnsigned(), keySizeBytes);
+ ecParameters.Curve = BouncyCastle.X509Utils.IdentifyEccCurveByCoefficients(a,b);
}
- //Extract the public key coordinates
- var publicKeyPoint = new X9ECPoint(ecParametersAsn1.Curve, ecPoint).Point;
+ var x = X509Utils.PadWithLeadingZeros(q.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(), keySizeBytes);
+ var y = X509Utils.PadWithLeadingZeros(q.AffineYCoord.ToBigInteger().ToByteArrayUnsigned(), keySizeBytes);
+ // Use the Q point
ecParameters.Q = new System.Security.Cryptography.ECPoint {
- X = publicKeyPoint.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(),
- Y = publicKeyPoint.AffineYCoord?.ToBigInteger().ToByteArrayUnsigned()
+ X = x,
+ Y = y
};
m_ecdsaPublicKey.ImportParameters(ecParameters);
@@ -334,6 +336,7 @@ public override ICertificateBuilderCreateForECDsaAny SetECDsaPublicKey(byte[] pu
#else
m_ecdsaPublicKey.ImportSubjectPublicKeyInfo(publicKey, out bytes);
#endif
+ SetECCurve(m_ecdsaPublicKey.ExportParameters(false).Curve);
}
catch (Exception e)
{