Rewrite asn1_enc_save() using CBS.
authorjsing <jsing@openbsd.org>
Thu, 12 May 2022 19:33:19 +0000 (19:33 +0000)
committerjsing <jsing@openbsd.org>
Thu, 12 May 2022 19:33:19 +0000 (19:33 +0000)
Rework and clean up other asn1_enc_* related functions while here.

ok tb@

lib/libcrypto/asn1/asn1_locl.h
lib/libcrypto/asn1/tasn_dec.c
lib/libcrypto/asn1/tasn_utl.c

index 79239fa..3a0e509 100644 (file)
@@ -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);
index 8732ab5..69e27a9 100644 (file)
@@ -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))
index e3b2c9e..1fd061f 100644 (file)
@@ -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.
  */
  *
  */
 
+#include <limits.h>
 #include <stddef.h>
 #include <string.h>
+
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
 #include <openssl/objects.h>
 #include <openssl/err.h>
 
+#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;
 }