Skip to content

Commit

Permalink
Simplify SetECDsaPublicKey and padd with leading zeros (#2962)
Browse files Browse the repository at this point in the history
* Simplify SetECDsaPublicKey and padd with leading zeros

* Added SetECCurve
  • Loading branch information
mrsuciu authored Jan 24, 2025
1 parent a2f761e commit f7815c8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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 {
Expand All @@ -190,34 +191,6 @@ private static ECDsa CreateECDsaFromECPrivateKey(ECPrivateKeyParameters eCPrivat
}
#endif

/// <summary>
/// Pads a byte array with leading zeros to reach the specifieed size
/// If the input is allready the given size, it just returns it
/// </summary>
/// <param name="arrayToPad">Provided array to pad</param>
/// <param name="desiredSize">The desired total length of byte array after padding</param>
/// <returns></returns>
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,35 @@ internal static RSA SetRSAPublicKey(byte[] publicKey)
rsaPublicKey.ImportParameters(parameters);
return rsaPublicKey;
}

/// <summary>
/// Pads a byte array with leading zeros to reach the specifieed size
/// If the input is allready the given size, it just returns it
/// </summary>
/// <param name="arrayToPad">Provided array to pad</param>
/// <param name="desiredSize">The desired total length of byte array after padding</param>
/// <returns></returns>
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
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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)
{
Expand Down

0 comments on commit f7815c8

Please sign in to comment.