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 | |
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
-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; |