diff options
| author | tb <> | 2024-08-28 06:17:06 +0000 |
|---|---|---|
| committer | tb <> | 2024-08-28 06:17:06 +0000 |
| commit | de1c20338c8303d97973d7ccd003ff3d04a96c2a (patch) | |
| tree | 13dfad166a5c724aa2725339e55b84713d0f148a /src | |
| parent | 0769c03c9ac155717446eb09c6440b513c1af085 (diff) | |
| download | openbsd-de1c20338c8303d97973d7ccd003ff3d04a96c2a.tar.gz openbsd-de1c20338c8303d97973d7ccd003ff3d04a96c2a.tar.bz2 openbsd-de1c20338c8303d97973d7ccd003ff3d04a96c2a.zip | |
Avoid polluting the error stack when printing certificates
For a certificate serial number between LONG_MAX and ULONG_MAX, the call to
ASN1_INTEGER_get() fails and leaves an error on the stack because the check
bs->length <= sizeof(long) doesn't quite do what it's supposed to do (bs is
probably for bitstring, although the more common reading would be adequate,
too.)
Fix this by checking for non-negativity and using ASN1_INTEGER_get_uint64()
and add a lengthy comment to explain the nonsense per beck's request.
discussed with jsing
ok beck
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/asn1/t_x509.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/lib/libcrypto/asn1/t_x509.c b/src/lib/libcrypto/asn1/t_x509.c index 5e753f3278..75bae5214a 100644 --- a/src/lib/libcrypto/asn1/t_x509.c +++ b/src/lib/libcrypto/asn1/t_x509.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: t_x509.c,v 1.45 2024/04/09 13:55:02 beck Exp $ */ | 1 | /* $OpenBSD: t_x509.c,v 1.46 2024/08/28 06:17:06 tb Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -56,6 +56,7 @@ | |||
| 56 | * [including the GNU Public Licence.] | 56 | * [including the GNU Public Licence.] |
| 57 | */ | 57 | */ |
| 58 | 58 | ||
| 59 | #include <limits.h> | ||
| 59 | #include <stdio.h> | 60 | #include <stdio.h> |
| 60 | 61 | ||
| 61 | #include <openssl/opensslconf.h> | 62 | #include <openssl/opensslconf.h> |
| @@ -155,8 +156,21 @@ X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag) | |||
| 155 | 156 | ||
| 156 | bs = X509_get_serialNumber(x); | 157 | bs = X509_get_serialNumber(x); |
| 157 | l = -1; | 158 | l = -1; |
| 158 | if (bs->length <= (int)sizeof(long)) | 159 | |
| 159 | l = ASN1_INTEGER_get(bs); | 160 | /* |
| 161 | * For historical reasons, non-negative serial numbers are | ||
| 162 | * printed in decimal as long as they fit into a long. Using | ||
| 163 | * ASN1_INTEGER_get_uint64() avoids an error on the stack for | ||
| 164 | * numbers between LONG_MAX and ULONG_MAX. Otherwise fall back | ||
| 165 | * to hexadecimal, also for numbers that are non-conformant | ||
| 166 | * (negative or larger than 2^159 - 1). | ||
| 167 | */ | ||
| 168 | if (bs->length <= sizeof(long) && bs->type == V_ASN1_INTEGER) { | ||
| 169 | uint64_t u64; | ||
| 170 | |||
| 171 | if (ASN1_INTEGER_get_uint64(&u64, bs) && u64 <= LONG_MAX) | ||
| 172 | l = (long)u64; | ||
| 173 | } | ||
| 160 | if (l >= 0) { | 174 | if (l >= 0) { |
| 161 | if (BIO_printf(bp, " %ld (0x%lx)\n", l, l) <= 0) | 175 | if (BIO_printf(bp, " %ld (0x%lx)\n", l, l) <= 0) |
| 162 | goto err; | 176 | goto err; |
