Fix overflow checks when converting ASN.1 integers to long.
(Credit to libFuzzer for finding this.) Change-Id: I0353d686d883703d39145c5bdd1e56368a587a35 Reviewed-on: https://boringssl-review.googlesource.com/22324 Reviewed-by: Adam Langley <agl@google.com> Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: Adam Langley <agl@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
parent
f5beb883c2
commit
2a768d04c6
@ -56,6 +56,7 @@
|
|||||||
|
|
||||||
#include <openssl/asn1.h>
|
#include <openssl/asn1.h>
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
@ -110,7 +111,6 @@ int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
|
|||||||
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
|
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
|
||||||
{
|
{
|
||||||
int neg = 0, i;
|
int neg = 0, i;
|
||||||
long r = 0;
|
|
||||||
|
|
||||||
if (a == NULL)
|
if (a == NULL)
|
||||||
return (0L);
|
return (0L);
|
||||||
@ -120,20 +120,31 @@ long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
|
|||||||
else if (i != V_ASN1_ENUMERATED)
|
else if (i != V_ASN1_ENUMERATED)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (a->length > (int)sizeof(long)) {
|
OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) >= sizeof(long),
|
||||||
/* hmm... a bit ugly */
|
long_larger_than_uint64_t);
|
||||||
return (0xffffffffL);
|
|
||||||
}
|
|
||||||
if (a->data == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0; i < a->length; i++) {
|
if (a->length > (int)sizeof(uint64_t)) {
|
||||||
r <<= 8;
|
/* hmm... a bit ugly */
|
||||||
r |= (unsigned char)a->data[i];
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t r64 = 0;
|
||||||
|
if (a->data != NULL) {
|
||||||
|
for (i = 0; i < a->length; i++) {
|
||||||
|
r64 <<= 8;
|
||||||
|
r64 |= (unsigned char)a->data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r64 > LONG_MAX) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long r = (long) r64;
|
||||||
if (neg)
|
if (neg)
|
||||||
r = -r;
|
r = -r;
|
||||||
return (r);
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
|
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
#include <openssl/asn1.h>
|
#include <openssl/asn1.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/mem.h>
|
#include <openssl/mem.h>
|
||||||
@ -385,7 +386,6 @@ int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
|
|||||||
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
|
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
|
||||||
{
|
{
|
||||||
int neg = 0, i;
|
int neg = 0, i;
|
||||||
long r = 0;
|
|
||||||
|
|
||||||
if (a == NULL)
|
if (a == NULL)
|
||||||
return (0L);
|
return (0L);
|
||||||
@ -395,20 +395,31 @@ long ASN1_INTEGER_get(const ASN1_INTEGER *a)
|
|||||||
else if (i != V_ASN1_INTEGER)
|
else if (i != V_ASN1_INTEGER)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (a->length > (int)sizeof(long)) {
|
OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) >= sizeof(long),
|
||||||
|
long_larger_than_uint64_t);
|
||||||
|
|
||||||
|
if (a->length > (int)sizeof(uint64_t)) {
|
||||||
/* hmm... a bit ugly, return all ones */
|
/* hmm... a bit ugly, return all ones */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (a->data == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
uint64_t r64 = 0;
|
||||||
|
if (a->data != NULL) {
|
||||||
for (i = 0; i < a->length; i++) {
|
for (i = 0; i < a->length; i++) {
|
||||||
r <<= 8;
|
r64 <<= 8;
|
||||||
r |= (unsigned char)a->data[i];
|
r64 |= (unsigned char)a->data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r64 > LONG_MAX) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long r = (long) r64;
|
||||||
if (neg)
|
if (neg)
|
||||||
r = -r;
|
r = -r;
|
||||||
return (r);
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
|
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
|
||||||
|
Loading…
Reference in New Issue
Block a user