diff options
author | Adam Langley <agl@google.com> | 2015-04-23 13:54:37 -0700 |
---|---|---|
committer | Kenny Root <kroot@google.com> | 2015-04-23 21:57:00 +0000 |
commit | d82ab38ca2b63638a2cb0b5d8a2c76d90c86dd31 (patch) | |
tree | 3cea780c4956edec6e4be340cf510a618b794c8c | |
parent | 217eaab310220731646f2a1a0159d71e4eb09d4a (diff) | |
download | external_boringssl-d82ab38ca2b63638a2cb0b5d8a2c76d90c86dd31.zip external_boringssl-d82ab38ca2b63638a2cb0b5d8a2c76d90c86dd31.tar.gz external_boringssl-d82ab38ca2b63638a2cb0b5d8a2c76d90c86dd31.tar.bz2 |
Ensure BN_asc2bn, BN_dec2bn, and BN_hex2bn never give -0.
When |BN_dec2bn| and |BN_hex2bn| were merged (way back in the initial
BoringSSL change), the neg flag was set too soon and could be cleared by
|BN_add_word|.
This is an import of upstream's c85573cc. The unittest change isn't
included here because bn_test.c has changed significantly in upstream
and BoringSSL unittests aren't run in the Android environment.
Bug: 20523350
Change-Id: Iaf8efe2fe3419218437f5ebb9a15f73559860a0f
-rw-r--r-- | src/crypto/asn1/a_int.c | 2 | ||||
-rw-r--r-- | src/crypto/bn/convert.c | 19 |
2 files changed, 11 insertions, 10 deletions
diff --git a/src/crypto/asn1/a_int.c b/src/crypto/asn1/a_int.c index eb0887a..2ecccc5 100644 --- a/src/crypto/asn1/a_int.c +++ b/src/crypto/asn1/a_int.c @@ -416,7 +416,7 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_INTEGER, ASN1_R_NESTED_ASN1_ERROR); goto err; } - if (BN_is_negative(bn)) + if (BN_is_negative(bn) && !BN_is_zero(bn)) ret->type = V_ASN1_NEG_INTEGER; else ret->type=V_ASN1_INTEGER; j=BN_num_bits(bn); diff --git a/src/crypto/bn/convert.c b/src/crypto/bn/convert.c index f764eed..9c7b9be 100644 --- a/src/crypto/bn/convert.c +++ b/src/crypto/bn/convert.c @@ -263,20 +263,19 @@ static void decode_hex(BIGNUM *bn, const char *in, int i) { bn->top = h; } -/* decode_dec decodes |i| bytes of decimal data from |in| and updates |bn|. */ -static void decode_dec(BIGNUM *bn, const char *in, int i) { - int j; +/* decode_dec decodes |in_len| bytes of decimal data from |in| and updates |bn|. */ +static void decode_dec(BIGNUM *bn, const char *in, int in_len) { + int i, j; BN_ULONG l = 0; - j = BN_DEC_NUM - (i % BN_DEC_NUM); + j = BN_DEC_NUM - (in_len % BN_DEC_NUM); if (j == BN_DEC_NUM) { j = 0; } l = 0; - while (*in) { + for (i = 0; i < in_len; i++) { l *= 10; - l += *in - '0'; - in++; + l += in[i] - '0'; if (++j == BN_DEC_NUM) { BN_mul_word(bn, BN_DEC_CONV); BN_add_word(bn, l); @@ -320,7 +319,6 @@ static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_ ret = *outp; BN_zero(ret); } - ret->neg = neg; /* i is the number of hex digests; */ if (bn_expand(ret, i * 4) == NULL) { @@ -330,6 +328,9 @@ static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_ decode(ret, in, i); bn_correct_top(ret); + if (!BN_is_zero(ret)) { + ret->neg = neg; + } *outp = ret; return num; @@ -440,7 +441,7 @@ int BN_asc2bn(BIGNUM **outp, const char *in) { } } - if (*orig_in == '-') { + if (*orig_in == '-' && !BN_is_zero(*outp)) { (*outp)->neg = 1; } |