From 47fd635d385b82d6f17831526807d8b9a7f3b7f6 Mon Sep 17 00:00:00 2001 From: jsing Date: Thu, 5 May 2022 19:18:56 +0000 Subject: [PATCH] Use size_t for ASN.1 lengths. Change asn1_get_length_cbs() and asn1_get_object_cbs() to handle and return a length as a size_t rather than a uint32_t. This makes it simpler and less error prone in the callers. Suggested by and ok tb@ --- lib/libcrypto/asn1/asn1_lib.c | 16 +++++++++------- lib/libcrypto/asn1/asn1_locl.h | 6 +++--- lib/libcrypto/asn1/asn1_old_lib.c | 7 ++++--- lib/libcrypto/asn1/tasn_dec.c | 7 ++++--- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/lib/libcrypto/asn1/asn1_lib.c b/lib/libcrypto/asn1/asn1_lib.c index 97ce6caeefe..ac8da0e61d4 100644 --- a/lib/libcrypto/asn1/asn1_lib.c +++ b/lib/libcrypto/asn1/asn1_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_lib.c,v 1.53 2022/04/28 18:30:57 jsing Exp $ */ +/* $OpenBSD: asn1_lib.c,v 1.54 2022/05/05 19:18:56 jsing Exp $ */ /* * Copyright (c) 2021 Joel Sing * @@ -78,10 +78,10 @@ asn1_get_identifier_cbs(CBS *cbs, int der_mode, uint8_t *out_class, int asn1_get_length_cbs(CBS *cbs, int der_mode, int *out_indefinite, - uint32_t *out_length) + size_t *out_length) { uint8_t len_bytes; - uint32_t length; + size_t length; uint8_t val; /* @@ -127,7 +127,7 @@ asn1_get_length_cbs(CBS *cbs, int der_mode, int *out_indefinite, return 0; if (der_mode && length == 0 && val == 0) return 0; - if (length > (UINT32_MAX >> 8)) + if (length > (SIZE_MAX >> 8)) return 0; length = (length << 8) | val; } @@ -140,11 +140,12 @@ asn1_get_length_cbs(CBS *cbs, int der_mode, int *out_indefinite, int asn1_get_object_cbs(CBS *cbs, int der_mode, uint8_t *out_tag_class, int *out_constructed, uint32_t *out_tag_number, int *out_indefinite, - uint32_t *out_length) + size_t *out_length) { int constructed, indefinite; - uint32_t tag_number, length; + uint32_t tag_number; uint8_t tag_class; + size_t length; *out_tag_class = 0; *out_constructed = 0; @@ -176,8 +177,9 @@ asn1_get_primitive(CBS *cbs, int der_mode, uint32_t *out_tag_number, CBS *out_content) { int constructed, indefinite; - uint32_t tag_number, length; + uint32_t tag_number; uint8_t tag_class; + size_t length; *out_tag_number = 0; diff --git a/lib/libcrypto/asn1/asn1_locl.h b/lib/libcrypto/asn1/asn1_locl.h index 86907aa8f07..79239faea17 100644 --- a/lib/libcrypto/asn1/asn1_locl.h +++ b/lib/libcrypto/asn1/asn1_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_locl.h,v 1.28 2022/04/28 18:30:57 jsing Exp $ */ +/* $OpenBSD: asn1_locl.h,v 1.29 2022/05/05 19:18:56 jsing Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -196,10 +196,10 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); int asn1_get_identifier_cbs(CBS *cbs, int der_mode, uint8_t *out_class, int *out_constructed, uint32_t *out_tag_number); int asn1_get_length_cbs(CBS *cbs, int der_mode, int *out_indefinite, - uint32_t *out_length); + size_t *out_length); int asn1_get_object_cbs(CBS *cbs, int der_mode, uint8_t *out_class, int *out_constructed, uint32_t *out_tag_number, int *out_indefinite, - uint32_t *out_length); + size_t *out_length); int asn1_get_primitive(CBS *cbs, int der_mode, uint32_t *out_tag_number, CBS *out_content); diff --git a/lib/libcrypto/asn1/asn1_old_lib.c b/lib/libcrypto/asn1/asn1_old_lib.c index e41a5ea2575..a4d3cc71b41 100644 --- a/lib/libcrypto/asn1/asn1_old_lib.c +++ b/lib/libcrypto/asn1/asn1_old_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_old_lib.c,v 1.3 2022/01/14 07:57:17 tb Exp $ */ +/* $OpenBSD: asn1_old_lib.c,v 1.4 2022/05/05 19:18:56 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -72,8 +72,9 @@ ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, int *pclass, long omax) { int constructed, indefinite; - uint32_t tag_number, length; + uint32_t tag_number; uint8_t tag_class; + size_t length; CBS cbs; int ret = 0; @@ -99,7 +100,7 @@ ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, * signal an error by setting the 8th bit in the return value... but we * still provide all of the decoded data. */ - if (length > CBS_len(&cbs)) { + if (length > CBS_len(&cbs) || length > LONG_MAX) { ASN1error(ASN1_R_TOO_LONG); ret = 0x80; } diff --git a/lib/libcrypto/asn1/tasn_dec.c b/lib/libcrypto/asn1/tasn_dec.c index 0131e3c27c2..103774fc195 100644 --- a/lib/libcrypto/asn1/tasn_dec.c +++ b/lib/libcrypto/asn1/tasn_dec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tasn_dec.c,v 1.57 2022/05/04 10:57:48 jsing Exp $ */ +/* $OpenBSD: tasn_dec.c,v 1.58 2022/05/05 19:18:56 jsing Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -1049,9 +1049,10 @@ asn1_check_tag_cbs(CBS *cbs, size_t *out_len, int *out_tag, uint8_t *out_class, char *out_indefinite, char *out_constructed, int expected_tag, int expected_class, char optional) { - uint32_t tag_number, length; int constructed, indefinite; + uint32_t tag_number; uint8_t tag_class; + size_t length; if (out_len != NULL) *out_len = 0; @@ -1096,7 +1097,7 @@ asn1_check_tag_cbs(CBS *cbs, size_t *out_len, int *out_tag, uint8_t *out_class, return 0; } - if (tag_number > INT_MAX || CBS_len(cbs) > INT_MAX) { + if (tag_number > INT_MAX) { ASN1error(ASN1_R_TOO_LONG); return 0; } -- 2.20.1