diff options
author | Andy Polyakov <appro@openssl.org> | 2017-04-28 10:06:35 +0200 |
---|---|---|
committer | Andy Polyakov <appro@openssl.org> | 2017-04-30 15:19:20 +0200 |
commit | d3d51adc87137fec7472a7e741490622ce725671 (patch) | |
tree | 5b4d97e16d3568482735587a8e093c4a055a24cd /crypto/asn1 | |
parent | 913d3a644edafee2a20c620e8625e9f3be49f643 (diff) |
asn1/a_int.c: fix "next negative minimum" corner case in c2i_ibuf.
"Next" refers to negative minimum "next" to one presentable by given
number of bytes. For example, -128 is negative minimum presentable by
one byte, and -256 is "next" one.
Thanks to Kazuki Yamaguchi for report, GH#3339
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(cherry picked from commit 1e93d619b78832834ae32f5c0c1b0e466267f72d)
Diffstat (limited to 'crypto/asn1')
-rw-r--r-- | crypto/asn1/a_int.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/crypto/asn1/a_int.c b/crypto/asn1/a_int.c index e154343925..217650a036 100644 --- a/crypto/asn1/a_int.c +++ b/crypto/asn1/a_int.c @@ -167,10 +167,21 @@ static size_t c2i_ibuf(unsigned char *b, int *pneg, } return 1; } - if (p[0] == 0 || p[0] == 0xFF) + + pad = 0; + if (p[0] == 0) { pad = 1; - else - pad = 0; + } else if (p[0] == 0xFF) { + size_t i; + + /* + * Special case [of "one less minimal negative" for given length]: + * if any other bytes non zero it was padded, otherwise not. + */ + for (pad = 0, i = 1; i < plen; i++) + pad |= p[i]; + pad = pad != 0 ? 1 : 0; + } /* reject illegal padding: first two octets MSB can't match */ if (pad && (neg == (p[1] & 0x80))) { ASN1err(ASN1_F_C2I_IBUF, ASN1_R_ILLEGAL_PADDING); |