X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=src%2Fec%2Fecdsa_atr.c;h=3a11226e49446667136e5825d9a171649f01aced;hp=91a1d0cc9be6d47723411fe2267a602068c14a03;hb=6dd8c51ba7e8ca106ede7ff58b5c507042bbf6eb;hpb=3210f38e0491b39aec1ef419cb4114e9483089fb diff --git a/src/ec/ecdsa_atr.c b/src/ec/ecdsa_atr.c index 91a1d0c..3a11226 100644 --- a/src/ec/ecdsa_atr.c +++ b/src/ec/ecdsa_atr.c @@ -33,6 +33,11 @@ br_ecdsa_asn1_to_raw(void *sig, size_t sig_len) * deviations to DER with regards to minimality of encoding of * lengths and integer values. These deviations are still * unambiguous. + * + * Signature format is a SEQUENCE of two INTEGER values. We + * support only integers of less than 127 bytes each (signed + * encoding) so the resulting raw signature will have length + * at most 254 bytes. */ unsigned char *buf, *r, *s; @@ -43,9 +48,20 @@ br_ecdsa_asn1_to_raw(void *sig, size_t sig_len) if (sig_len < 8) { return 0; } + + /* + * First byte is SEQUENCE tag. + */ if (buf[0] != 0x30) { return 0; } + + /* + * The SEQUENCE length will be encoded over one or two bytes. We + * limit the total SEQUENCE contents to 255 bytes, because it + * makes things simpler; this is enough for subgroup orders up + * to 999 bits. + */ zlen = buf[1]; if (zlen > 0x80) { if (zlen != 0x81) { @@ -62,6 +78,10 @@ br_ecdsa_asn1_to_raw(void *sig, size_t sig_len) } off = 2; } + + /* + * First INTEGER (r). + */ if (buf[off ++] != 0x02) { return 0; } @@ -71,6 +91,10 @@ br_ecdsa_asn1_to_raw(void *sig, size_t sig_len) } r = buf + off; off += rlen; + + /* + * Second INTEGER (s). + */ if (off + 2 > sig_len) { return 0; } @@ -83,6 +107,9 @@ br_ecdsa_asn1_to_raw(void *sig, size_t sig_len) } s = buf + off; + /* + * Removing leading zeros from r and s. + */ while (rlen > 0 && *r == 0) { rlen --; r ++; @@ -92,6 +119,11 @@ br_ecdsa_asn1_to_raw(void *sig, size_t sig_len) s ++; } + /* + * Compute common length for the two integers, then copy integers + * into the temporary buffer, and finally copy it back over the + * signature buffer. + */ zlen = rlen > slen ? rlen : slen; sig_len = zlen << 1; memset(tmp, 0, sig_len);