From b3e79a77cfb5db756bb740c48e65035edb7893f3 Mon Sep 17 00:00:00 2001 From: jsing Date: Thu, 12 May 2022 19:33:19 +0000 Subject: [PATCH] Rewrite asn1_enc_save() using CBS. Rework and clean up other asn1_enc_* related functions while here. ok tb@ --- lib/libcrypto/asn1/asn1_locl.h | 4 +- lib/libcrypto/asn1/tasn_dec.c | 8 ++- lib/libcrypto/asn1/tasn_utl.c | 103 ++++++++++++++++++++------------- 3 files changed, 69 insertions(+), 46 deletions(-) diff --git a/lib/libcrypto/asn1/asn1_locl.h b/lib/libcrypto/asn1/asn1_locl.h index 79239faea17..3a0e5091e3c 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.29 2022/05/05 19:18:56 jsing Exp $ */ +/* $OpenBSD: asn1_locl.h,v 1.30 2022/05/12 19:33:19 jsing Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -172,8 +172,8 @@ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it); void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it); void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_enc_save(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it); int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it); -int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it); int i2d_ASN1_BOOLEAN(int a, unsigned char **pp); int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length); diff --git a/lib/libcrypto/asn1/tasn_dec.c b/lib/libcrypto/asn1/tasn_dec.c index 8732ab53cf8..69e27a9f0f7 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.64 2022/05/12 19:11:14 jsing Exp $ */ +/* $OpenBSD: tasn_dec.c,v 1.65 2022/05/12 19:33:19 jsing Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -249,6 +249,7 @@ asn1_item_ex_d2i_sequence(ASN1_VALUE **pval, const unsigned char **in, long len, ASN1_aux_cb *asn1_cb = NULL; char seq_eoc, seq_nolen, cst, isopt; const unsigned char *p = NULL, *q; + CBS cbs; int i; int ret = 0; @@ -383,9 +384,10 @@ asn1_item_ex_d2i_sequence(ASN1_VALUE **pval, const unsigned char **in, long len, } } /* Save encoding */ - if (!asn1_enc_save(pval, *in, p - *in, it)) { + CBS_init(&cbs, *in, p - *in); + if (!asn1_enc_save(pval, &cbs, it)) { ASN1error(ERR_R_MALLOC_FAILURE); - goto auxerr; + goto err; } *in = p; if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) diff --git a/lib/libcrypto/asn1/tasn_utl.c b/lib/libcrypto/asn1/tasn_utl.c index e3b2c9e4dc6..1fd061f9f8a 100644 --- a/lib/libcrypto/asn1/tasn_utl.c +++ b/lib/libcrypto/asn1/tasn_utl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tasn_utl.c,v 1.15 2022/05/12 19:24:38 jsing Exp $ */ +/* $OpenBSD: tasn_utl.c,v 1.16 2022/05/12 19:33:19 jsing Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -56,13 +56,17 @@ * */ +#include #include #include + #include #include #include #include +#include "bytestring.h" + /* Utility functions for manipulating fields and offsets */ /* Add 'offset' to 'addr' */ @@ -123,79 +127,96 @@ asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) static ASN1_ENCODING * asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) { - const ASN1_AUX *aux; + const ASN1_AUX *aux = it->funcs; - if (!pval || !*pval) + if (pval == NULL || *pval == NULL) return NULL; - aux = it->funcs; - if (!aux || !(aux->flags & ASN1_AFLG_ENCODING)) + + if (aux == NULL || (aux->flags & ASN1_AFLG_ENCODING) == 0) return NULL; + return offset2ptr(*pval, aux->enc_offset); } void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) { - ASN1_ENCODING *enc; + ASN1_ENCODING *aenc; - enc = asn1_get_enc_ptr(pval, it); - if (enc) { - enc->enc = NULL; - enc->len = 0; - enc->modified = 1; - } + if ((aenc = asn1_get_enc_ptr(pval, it)) == NULL) + return; + + aenc->enc = NULL; + aenc->len = 0; + aenc->modified = 1; +} + +static void +asn1_enc_clear(ASN1_ENCODING *aenc) +{ + freezero(aenc->enc, aenc->len); + aenc->enc = NULL; + aenc->len = 0; + aenc->modified = 1; } void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { - ASN1_ENCODING *enc; - - enc = asn1_get_enc_ptr(pval, it); - if (enc) { - freezero(enc->enc, enc->len); - enc->enc = NULL; - enc->len = 0; - enc->modified = 1; - } + ASN1_ENCODING *aenc; + + if ((aenc = asn1_get_enc_ptr(pval, it)) == NULL) + return; + + asn1_enc_clear(aenc); } int -asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, - const ASN1_ITEM *it) +asn1_enc_save(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it) { - ASN1_ENCODING *enc; + ASN1_ENCODING *aenc; + uint8_t *data = NULL; + size_t data_len = 0; - enc = asn1_get_enc_ptr(pval, it); - if (!enc) + if ((aenc = asn1_get_enc_ptr(pval, it)) == NULL) return 1; - freezero(enc->enc, enc->len); - enc->enc = malloc(inlen); - if (!enc->enc) + asn1_enc_clear(aenc); + + if (!CBS_stow(cbs, &data, &data_len)) + return 0; + if (data_len > LONG_MAX) { + freezero(data, data_len); return 0; - memcpy(enc->enc, in, inlen); - enc->len = inlen; - enc->modified = 0; + } + + aenc->enc = data; + aenc->len = (long)data_len; + aenc->modified = 0; return 1; } int -asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, +asn1_enc_restore(int *out_len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it) { - ASN1_ENCODING *enc; + ASN1_ENCODING *aenc; + + if ((aenc = asn1_get_enc_ptr(pval, it)) == NULL) + return 0; - enc = asn1_get_enc_ptr(pval, it); - if (!enc || enc->modified) + if (aenc->modified) return 0; - if (out) { - memcpy(*out, enc->enc, enc->len); - *out += enc->len; + + if (out != NULL) { + memcpy(*out, aenc->enc, aenc->len); + *out += aenc->len; } - if (len) - *len = enc->len; + + if (out_len != NULL) + *out_len = aenc->len; + return 1; } -- 2.20.1