Pretty-print large INTEGERs and ENUMERATEDs in hex.
This avoids taking quadratic time to pretty-print certificates with excessively large integer fields. Very large integers aren't any more readable in decimal than hexadecimal anyway, and the i2s_* functions will parse either form. Found by libFuzzer. Change-Id: Id586cd1b0eef8936d38ff50433ae7c819f0054f3 Reviewed-on: https://boringssl-review.googlesource.com/23424 Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
27bc0f26c8
commit
56aaf164ac
@ -26,6 +26,7 @@
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/pool.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
@ -996,3 +997,41 @@ TEST(X509Test, TestPrintUTCTIME) {
|
||||
std::string(reinterpret_cast<const char *>(contents), len));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(X509Test, PrettyPrintIntegers) {
|
||||
static const char *kTests[] = {
|
||||
// Small numbers are pretty-printed in decimal.
|
||||
"0",
|
||||
"-1",
|
||||
"1",
|
||||
"42",
|
||||
"-42",
|
||||
"256",
|
||||
"-256",
|
||||
// Large numbers are pretty-printed in hex to avoid taking quadratic time.
|
||||
"0x0123456789",
|
||||
"-0x0123456789",
|
||||
};
|
||||
for (const char *in : kTests) {
|
||||
SCOPED_TRACE(in);
|
||||
BIGNUM *bn = nullptr;
|
||||
ASSERT_TRUE(BN_asc2bn(&bn, in));
|
||||
bssl::UniquePtr<BIGNUM> free_bn(bn);
|
||||
|
||||
{
|
||||
bssl::UniquePtr<ASN1_INTEGER> asn1(BN_to_ASN1_INTEGER(bn, nullptr));
|
||||
ASSERT_TRUE(asn1);
|
||||
bssl::UniquePtr<char> out(i2s_ASN1_INTEGER(nullptr, asn1.get()));
|
||||
ASSERT_TRUE(out.get());
|
||||
EXPECT_STREQ(in, out.get());
|
||||
}
|
||||
|
||||
{
|
||||
bssl::UniquePtr<ASN1_ENUMERATED> asn1(BN_to_ASN1_ENUMERATED(bn, nullptr));
|
||||
ASSERT_TRUE(asn1);
|
||||
bssl::UniquePtr<char> out(i2s_ASN1_ENUMERATED(nullptr, asn1.get()));
|
||||
ASSERT_TRUE(out.get());
|
||||
EXPECT_STREQ(in, out.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -155,6 +155,45 @@ int X509V3_add_value_bool_nf(char *name, int asn1_bool,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *bignum_to_string(const BIGNUM *bn)
|
||||
{
|
||||
char *tmp, *ret;
|
||||
size_t len;
|
||||
|
||||
/*
|
||||
* Display large numbers in hex and small numbers in decimal. Converting to
|
||||
* decimal takes quadratic time and is no more useful than hex for large
|
||||
* numbers.
|
||||
*/
|
||||
if (BN_num_bits(bn) < 32) {
|
||||
return BN_bn2dec(bn);
|
||||
}
|
||||
|
||||
tmp = BN_bn2hex(bn);
|
||||
if (tmp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = strlen(tmp) + 3;
|
||||
ret = OPENSSL_malloc(len);
|
||||
if (ret == NULL) {
|
||||
OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(tmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Prepend "0x", but place it after the "-" if negative. */
|
||||
if (tmp[0] == '-') {
|
||||
BUF_strlcpy(ret, "-0x", len);
|
||||
BUF_strlcat(ret, tmp + 1, len);
|
||||
} else {
|
||||
BUF_strlcpy(ret, "0x", len);
|
||||
BUF_strlcat(ret, tmp, len);
|
||||
}
|
||||
OPENSSL_free(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
|
||||
{
|
||||
BIGNUM *bntmp = NULL;
|
||||
@ -162,7 +201,7 @@ char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
|
||||
if (!a)
|
||||
return NULL;
|
||||
if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
|
||||
!(strtmp = BN_bn2dec(bntmp)))
|
||||
!(strtmp = bignum_to_string(bntmp)))
|
||||
OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
|
||||
BN_free(bntmp);
|
||||
return strtmp;
|
||||
@ -175,7 +214,7 @@ char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
|
||||
if (!a)
|
||||
return NULL;
|
||||
if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
|
||||
!(strtmp = BN_bn2dec(bntmp)))
|
||||
!(strtmp = bignum_to_string(bntmp)))
|
||||
OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
|
||||
BN_free(bntmp);
|
||||
return strtmp;
|
||||
|
Loading…
Reference in New Issue
Block a user