fix decoding of ecdsa signature (#1257)

- incorrect decoding caused flaky builds, verification error only if keys have trailing zeros
This commit is contained in:
Martin Regen
2021-01-27 08:48:29 +01:00
committed by GitHub
parent 4a14df9cd5
commit 29fc3f2bfc
2 changed files with 14 additions and 10 deletions
@@ -208,7 +208,7 @@ namespace Opc.Ua.Security.Certificates
{
using (ECDsa key = certificate.GetECDsaPublicKey())
{
var decodedSignature = DecodeECDsa(Signature);
var decodedSignature = DecodeECDsa(Signature, key.KeySize);
return key.VerifyData(Tbs, decodedSignature, Name);
}
}
@@ -258,7 +258,8 @@ namespace Opc.Ua.Security.Certificates
/// Decode a ECDSA signature from ASN.1.
/// </summary>
/// <param name="signature">The signature to decode from ASN.1</param>
private static byte[] DecodeECDsa(ReadOnlyMemory<byte> signature)
/// <param name="keySize">The keySize in bits.</param>
private static byte[] DecodeECDsa(ReadOnlyMemory<byte> signature, int keySize)
{
AsnReader reader = new AsnReader(signature, AsnEncodingRules.DER);
var seqReader = reader.ReadSequence();
@@ -266,17 +267,20 @@ namespace Opc.Ua.Security.Certificates
var r = seqReader.ReadIntegerBytes();
var s = seqReader.ReadIntegerBytes();
seqReader.ThrowIfNotEmpty();
if (r.Span[0] == 0)
keySize >>= 3;
if (r.Span[0] == 0 && r.Length > keySize)
{
r = r.Slice(1);
}
if (s.Span[0] == 0)
if (s.Span[0] == 0 && s.Length > keySize)
{
s = s.Slice(1);
}
var result = new byte[r.Length + s.Length];
r.CopyTo(new Memory<byte>(result, 0, r.Length));
s.CopyTo(new Memory<byte>(result, r.Length, s.Length));
var result = new byte[2 * keySize];
int offset = keySize - r.Length;
r.CopyTo(new Memory<byte>(result, offset, r.Length));
offset = 2 * keySize - s.Length;
s.CopyTo(new Memory<byte>(result, offset, s.Length));
return result;
}
}
@@ -112,7 +112,7 @@ namespace Opc.Ua.Security.Certificates.Tests
/// <summary>
/// Create the default RSA certificate.
/// </summary>
[Theory]
[Theory, Repeat(10)]
public void CreateSelfSignedForECDsaDefaultTest(ECCurveHashPair eccurveHashPair)
{
// default cert
@@ -145,7 +145,7 @@ namespace Opc.Ua.Security.Certificates.Tests
Assert.True(X509Utils.VerifySelfSigned(cert), "Verify self signed.");
}
[Theory]
[Theory, Repeat(10)]
public void CreateSelfSignedForECDsaAllFields(
ECCurveHashPair ecCurveHashPair
)
@@ -182,7 +182,7 @@ namespace Opc.Ua.Security.Certificates.Tests
Assert.True(X509Utils.VerifySelfSigned(cert));
}
[Theory]
[Theory, Repeat(10)]
public void CreateCACertForECDsa(
ECCurveHashPair ecCurveHashPair
)