summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2024-08-28 06:17:06 +0000
committertb <>2024-08-28 06:17:06 +0000
commitde1c20338c8303d97973d7ccd003ff3d04a96c2a (patch)
tree13dfad166a5c724aa2725339e55b84713d0f148a
parent0769c03c9ac155717446eb09c6440b513c1af085 (diff)
downloadopenbsd-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.c20
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;