Skip to content

Commit f7815c8

Browse files
authored
Simplify SetECDsaPublicKey and padd with leading zeros (#2962)
* Simplify SetECDsaPublicKey and padd with leading zeros * Added SetECCurve
1 parent a2f761e commit f7815c8

File tree

3 files changed

+49
-44
lines changed

3 files changed

+49
-44
lines changed

Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/PEMReader.cs

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
using Org.BouncyCastle.OpenSsl;
3636
using Org.BouncyCastle.Security;
3737
using Org.BouncyCastle.Crypto.Parameters;
38+
using Opc.Ua.Security.Certificates.BouncyCastle;
3839

3940
namespace Opc.Ua.Security.Certificates
4041
{
@@ -168,9 +169,9 @@ private static ECDsa CreateECDsaFromECPrivateKey(ECPrivateKeyParameters eCPrivat
168169
var d = eCPrivateKeyParameters.D.ToByteArrayUnsigned();
169170

170171
// pad all to the same length since ToByteArrayUnsigned might drop leading zeroes
171-
x = PadWithLeadingZeros(x, keySizeBytes);
172-
y = PadWithLeadingZeros(y, keySizeBytes);
173-
d = PadWithLeadingZeros(d, keySizeBytes);
172+
x = X509Utils.PadWithLeadingZeros(x, keySizeBytes);
173+
y = X509Utils.PadWithLeadingZeros(y, keySizeBytes);
174+
d = X509Utils.PadWithLeadingZeros(d, keySizeBytes);
174175

175176

176177
var ecParams = new ECParameters {
@@ -190,34 +191,6 @@ private static ECDsa CreateECDsaFromECPrivateKey(ECPrivateKeyParameters eCPrivat
190191
}
191192
#endif
192193

193-
/// <summary>
194-
/// Pads a byte array with leading zeros to reach the specifieed size
195-
/// If the input is allready the given size, it just returns it
196-
/// </summary>
197-
/// <param name="arrayToPad">Provided array to pad</param>
198-
/// <param name="desiredSize">The desired total length of byte array after padding</param>
199-
/// <returns></returns>
200-
private static byte[] PadWithLeadingZeros(byte[] arrayToPad, int desiredSize)
201-
{
202-
if (arrayToPad.Length == desiredSize)
203-
{
204-
return arrayToPad;
205-
}
206-
207-
int paddingLength = desiredSize - arrayToPad.Length;
208-
if (paddingLength < 0)
209-
{
210-
throw new ArgumentException($"Input byte array is larger than the desired size {desiredSize} bytes.");
211-
}
212-
213-
var paddedArray = new byte[desiredSize];
214-
215-
// Right-align the arrayToPad into paddedArray
216-
Buffer.BlockCopy(arrayToPad, 0, paddedArray, paddingLength, arrayToPad.Length);
217-
218-
return paddedArray;
219-
220-
}
221194
#endregion
222195

223196
#region Internal class

Libraries/Opc.Ua.Security.Certificates/Org.BouncyCastle/X509Utils.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,35 @@ internal static RSA SetRSAPublicKey(byte[] publicKey)
370370
rsaPublicKey.ImportParameters(parameters);
371371
return rsaPublicKey;
372372
}
373+
374+
/// <summary>
375+
/// Pads a byte array with leading zeros to reach the specifieed size
376+
/// If the input is allready the given size, it just returns it
377+
/// </summary>
378+
/// <param name="arrayToPad">Provided array to pad</param>
379+
/// <param name="desiredSize">The desired total length of byte array after padding</param>
380+
/// <returns></returns>
381+
internal static byte[] PadWithLeadingZeros(byte[] arrayToPad, int desiredSize)
382+
{
383+
if (arrayToPad.Length == desiredSize)
384+
{
385+
return arrayToPad;
386+
}
387+
388+
int paddingLength = desiredSize - arrayToPad.Length;
389+
if (paddingLength < 0)
390+
{
391+
throw new ArgumentException($"Input byte array is larger than the desired size {desiredSize} bytes.");
392+
}
393+
394+
var paddedArray = new byte[desiredSize];
395+
396+
// Right-align the arrayToPad into paddedArray
397+
Buffer.BlockCopy(arrayToPad, 0, paddedArray, paddingLength, arrayToPad.Length);
398+
399+
return paddedArray;
400+
401+
}
373402
#endregion
374403
}
375404
}

Libraries/Opc.Ua.Security.Certificates/X509Certificate/CertificateBuilder.cs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
using Org.BouncyCastle.Asn1.X509;
4343
using Org.BouncyCastle.Asn1.X9;
4444
using Org.BouncyCastle.Math.EC;
45+
using Opc.Ua.Security.Certificates.BouncyCastle;
4546
#endif
4647

4748
namespace Opc.Ua.Security.Certificates
@@ -297,35 +298,36 @@ public override ICertificateBuilderCreateForECDsaAny SetECDsaPublicKey(byte[] pu
297298
var publicKeyInfo = SubjectPublicKeyInfo.GetInstance(asn1Obj);
298299
var algParams = publicKeyInfo.Algorithm.Parameters;
299300
var x962Params = X962Parameters.GetInstance(algParams);
300-
var ecPoint = publicKeyInfo.PublicKey.GetBytes();
301301

302302
ECParameters ecParameters = new ECParameters();
303-
X9ECParameters ecParametersAsn1 = null;
303+
304+
var domainParameters = asymmetricPubKeyParameters.Parameters;
305+
var q = asymmetricPubKeyParameters.Q;
306+
// calculate keySize round up (bitLength + 7) / 8
307+
int keySizeBytes = (domainParameters.N.BitLength + 7) / 8;
304308

305309
if (x962Params.IsNamedCurve)
306310
{
307311
// Named
308312
var namedCurveOid = (DerObjectIdentifier)x962Params.Parameters;
309313
string curveName = namedCurveOid.Id;
310-
311314
var ecCurve = System.Security.Cryptography.ECCurve.CreateFromOid(new Oid(curveName));
312315
ecParameters.Curve = ecCurve;
313316
}
314317
else
315318
{
316-
// Explicit but still need to create the curve as named since the platform does not support it's creation
317-
// otherwise
318-
ecParametersAsn1 = X9ECParameters.GetInstance(x962Params.Parameters);
319-
ecParameters.Curve = BouncyCastle.X509Utils.IdentifyEccCurveByCoefficients(ecParametersAsn1.Curve.A.GetEncoded(),
320-
ecParametersAsn1.Curve.B.GetEncoded());// instead of ecParametersAsn1.Curve;
321-
319+
// Explicit parameters
320+
var a = X509Utils.PadWithLeadingZeros(domainParameters.Curve.A.ToBigInteger().ToByteArrayUnsigned(), keySizeBytes);
321+
var b = X509Utils.PadWithLeadingZeros(domainParameters.Curve.B.ToBigInteger().ToByteArrayUnsigned(), keySizeBytes);
322+
ecParameters.Curve = BouncyCastle.X509Utils.IdentifyEccCurveByCoefficients(a,b);
322323
}
323324

324-
//Extract the public key coordinates
325-
var publicKeyPoint = new X9ECPoint(ecParametersAsn1.Curve, ecPoint).Point;
325+
var x = X509Utils.PadWithLeadingZeros(q.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(), keySizeBytes);
326+
var y = X509Utils.PadWithLeadingZeros(q.AffineYCoord.ToBigInteger().ToByteArrayUnsigned(), keySizeBytes);
327+
// Use the Q point
326328
ecParameters.Q = new System.Security.Cryptography.ECPoint {
327-
X = publicKeyPoint.AffineXCoord.ToBigInteger().ToByteArrayUnsigned(),
328-
Y = publicKeyPoint.AffineYCoord?.ToBigInteger().ToByteArrayUnsigned()
329+
X = x,
330+
Y = y
329331
};
330332

331333
m_ecdsaPublicKey.ImportParameters(ecParameters);
@@ -334,6 +336,7 @@ public override ICertificateBuilderCreateForECDsaAny SetECDsaPublicKey(byte[] pu
334336
#else
335337
m_ecdsaPublicKey.ImportSubjectPublicKeyInfo(publicKey, out bytes);
336338
#endif
339+
SetECCurve(m_ecdsaPublicKey.ExportParameters(false).Curve);
337340
}
338341
catch (Exception e)
339342
{

0 commit comments

Comments
 (0)