From 0cd86ebd2386e14f0beeb08cd28963eabfb79a77 Mon Sep 17 00:00:00 2001 From: jsing Date: Sat, 25 Dec 2021 12:00:22 +0000 Subject: [PATCH] More consolidation of ASN.1 code. Consolidate various ASN1_item_* functions into asn1_item.c and the remaining NO_OLD_ASN1 code (not to be confused with the NO_ASN1_OLD code) into asn1_old.c. This is preferable to having many files, often with one or two functions per file. No functional change. Discussed with tb@ --- lib/libcrypto/Makefile | 8 +- lib/libcrypto/asn1/a_d2i_fp.c | 289 ------------- lib/libcrypto/asn1/a_digest.c | 87 ---- lib/libcrypto/asn1/a_dup.c | 118 ------ lib/libcrypto/asn1/a_verify.c | 168 -------- lib/libcrypto/asn1/{a_sign.c => asn1_item.c} | 379 +++++++++++++++++- lib/libcrypto/asn1/asn1_locl.h | 4 +- lib/libcrypto/asn1/{a_i2d_fp.c => asn1_old.c} | 100 +++-- 8 files changed, 438 insertions(+), 715 deletions(-) delete mode 100644 lib/libcrypto/asn1/a_d2i_fp.c delete mode 100644 lib/libcrypto/asn1/a_digest.c delete mode 100644 lib/libcrypto/asn1/a_dup.c delete mode 100644 lib/libcrypto/asn1/a_verify.c rename lib/libcrypto/asn1/{a_sign.c => asn1_item.c} (53%) rename lib/libcrypto/asn1/{a_i2d_fp.c => asn1_old.c} (82%) diff --git a/lib/libcrypto/Makefile b/lib/libcrypto/Makefile index cc53d8e6fef..9b9d448fa2f 100644 --- a/lib/libcrypto/Makefile +++ b/lib/libcrypto/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.60 2021/12/25 07:04:03 jsing Exp $ +# $OpenBSD: Makefile,v 1.61 2021/12/25 12:00:22 jsing Exp $ LIB= crypto LIBREBUILD=y @@ -53,8 +53,8 @@ SRCS+= aes_ctr.c aes_ige.c aes_wrap.c # asn1/ SRCS+= a_object.c a_bitstr.c a_time.c a_int.c a_octet.c a_pkey.c a_pubkey.c -SRCS+= a_print.c a_type.c a_dup.c a_d2i_fp.c a_i2d_fp.c a_string.c -SRCS+= a_enum.c a_utf8.c a_sign.c a_digest.c a_verify.c a_mbstr.c a_strex.c +SRCS+= a_print.c a_type.c a_string.c +SRCS+= a_enum.c a_utf8.c a_mbstr.c a_strex.c SRCS+= x_algor.c x_val.c x_pubkey.c x_sig.c x_req.c x_attrib.c x_bignum.c SRCS+= x_long.c x_name.c x_x509.c x_x509a.c x_crl.c x_info.c x_spki.c nsseq.c SRCS+= x_nx509.c @@ -65,7 +65,7 @@ SRCS+= n_pkey.c SRCS+= x_pkey.c x_exten.c bio_asn1.c bio_ndef.c asn_mime.c SRCS+= asn1_gen.c asn1_par.c asn1_old_lib.c asn1_err.c a_strnid.c SRCS+= evp_asn1.c asn_pack.c p5_pbe.c p5_pbev2.c p8_pkey.c asn_moid.c -SRCS+= a_time_tm.c asn1_types.c asn1_lib.c +SRCS+= a_time_tm.c asn1_item.c asn1_old.c asn1_types.c asn1_lib.c # bf/ SRCS+= bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c diff --git a/lib/libcrypto/asn1/a_d2i_fp.c b/lib/libcrypto/asn1/a_d2i_fp.c deleted file mode 100644 index 907ddd0aa97..00000000000 --- a/lib/libcrypto/asn1/a_d2i_fp.c +++ /dev/null @@ -1,289 +0,0 @@ -/* $OpenBSD: a_d2i_fp.c,v 1.17 2021/11/18 15:58:31 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include - -#include -#include -#include - -static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); - -#ifndef NO_OLD_ASN1 - -void * -ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x) -{ - BIO *b; - void *ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - ASN1error(ERR_R_BUF_LIB); - return (NULL); - } - BIO_set_fp(b, in, BIO_NOCLOSE); - ret = ASN1_d2i_bio(xnew, d2i, b, x); - BIO_free(b); - return (ret); -} - -void * -ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x) -{ - BUF_MEM *b = NULL; - const unsigned char *p; - void *ret = NULL; - int len; - - len = asn1_d2i_read_bio(in, &b); - if (len < 0) - goto err; - - p = (unsigned char *)b->data; - ret = d2i(x, &p, len); - -err: - if (b != NULL) - BUF_MEM_free(b); - return (ret); -} - -#endif - -void * -ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) -{ - BUF_MEM *b = NULL; - const unsigned char *p; - void *ret = NULL; - int len; - - len = asn1_d2i_read_bio(in, &b); - if (len < 0) - goto err; - - p = (const unsigned char *)b->data; - ret = ASN1_item_d2i(x, &p, len, it); - -err: - if (b != NULL) - BUF_MEM_free(b); - return (ret); -} - -void * -ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) -{ - BIO *b; - char *ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - ASN1error(ERR_R_BUF_LIB); - return (NULL); - } - BIO_set_fp(b, in, BIO_NOCLOSE); - ret = ASN1_item_d2i_bio(it, b, x); - BIO_free(b); - return (ret); -} - -#define HEADER_SIZE 8 -#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024) -static int -asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) -{ - BUF_MEM *b; - unsigned char *p; - const unsigned char *q; - long slen; - int i, inf, tag, xclass; - size_t want = HEADER_SIZE; - int eos = 0; - size_t off = 0; - size_t len = 0; - - b = BUF_MEM_new(); - if (b == NULL) { - ASN1error(ERR_R_MALLOC_FAILURE); - return -1; - } - - ERR_clear_error(); - for (;;) { - if (want >= (len - off)) { - want -= (len - off); - - if (len + want < len || - !BUF_MEM_grow_clean(b, len + want)) { - ASN1error(ERR_R_MALLOC_FAILURE); - goto err; - } - i = BIO_read(in, &(b->data[len]), want); - if ((i < 0) && ((len - off) == 0)) { - ASN1error(ASN1_R_NOT_ENOUGH_DATA); - goto err; - } - if (i > 0) { - if (len + i < len) { - ASN1error(ASN1_R_TOO_LONG); - goto err; - } - len += i; - } - } - /* else data already loaded */ - - p = (unsigned char *) & (b->data[off]); - q = p; - inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off); - if (inf & 0x80) { - unsigned long e; - - e = ERR_GET_REASON(ERR_peek_error()); - if (e != ASN1_R_TOO_LONG) - goto err; - else - ERR_clear_error(); /* clear error */ - } - i = q - p; /* header length */ - off += i; /* end of data */ - - if (inf & 1) { - /* no data body so go round again */ - eos++; - if (eos < 0) { - ASN1error(ASN1_R_HEADER_TOO_LONG); - goto err; - } - want = HEADER_SIZE; - } else if (eos && slen == 0 && tag == V_ASN1_EOC) { - /* eos value, so go back and read another header */ - eos--; - if (eos <= 0) - break; - else - want = HEADER_SIZE; - } else { - /* suck in slen bytes of data */ - want = slen; - if (want > (len - off)) { - size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE; - - want -= (len - off); - if (want > INT_MAX /* BIO_read takes an int length */ || - len+want < len) { - ASN1error(ASN1_R_TOO_LONG); - goto err; - } - while (want > 0) { - /* - * Read content in chunks of increasing size - * so we can return an error for EOF without - * having to allocate the entire content length - * in one go. - */ - size_t chunk = want > chunk_max ? chunk_max : want; - - if (!BUF_MEM_grow_clean(b, len + chunk)) { - ASN1error(ERR_R_MALLOC_FAILURE); - goto err; - } - want -= chunk; - while (chunk > 0) { - i = BIO_read(in, &(b->data[len]), chunk); - if (i <= 0) { - ASN1error(ASN1_R_NOT_ENOUGH_DATA); - goto err; - } - /* - * This can't overflow because |len+want| - * didn't overflow. - */ - len += i; - chunk -= i; - } - if (chunk_max < INT_MAX/2) - chunk_max *= 2; - } - } - if (off + slen < off) { - ASN1error(ASN1_R_TOO_LONG); - goto err; - } - off += slen; - if (eos <= 0) { - break; - } else - want = HEADER_SIZE; - } - } - - if (off > INT_MAX) { - ASN1error(ASN1_R_TOO_LONG); - goto err; - } - - *pb = b; - return off; - -err: - if (b != NULL) - BUF_MEM_free(b); - return -1; -} diff --git a/lib/libcrypto/asn1/a_digest.c b/lib/libcrypto/asn1/a_digest.c deleted file mode 100644 index 5b95adf1155..00000000000 --- a/lib/libcrypto/asn1/a_digest.c +++ /dev/null @@ -1,87 +0,0 @@ -/* $OpenBSD: a_digest.c,v 1.16 2018/04/06 09:19:36 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include -#include - -#include -#include -#include -#include - -int -ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn, - unsigned char *md, unsigned int *len) -{ - int i; - unsigned char *str = NULL; - - i = ASN1_item_i2d(asn, &str, it); - if (!str) - return (0); - - if (!EVP_Digest(str, i, md, len, type, NULL)) { - free(str); - return (0); - } - - free(str); - return (1); -} diff --git a/lib/libcrypto/asn1/a_dup.c b/lib/libcrypto/asn1/a_dup.c deleted file mode 100644 index 2e17a1e2194..00000000000 --- a/lib/libcrypto/asn1/a_dup.c +++ /dev/null @@ -1,118 +0,0 @@ -/* $OpenBSD: a_dup.c,v 1.14 2017/01/29 17:49:22 beck Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include -#include - -#ifndef NO_OLD_ASN1 - -void * -ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x) -{ - unsigned char *b, *p; - const unsigned char *p2; - int i; - char *ret; - - if (x == NULL) - return (NULL); - - i = i2d(x, NULL); - b = malloc(i + 10); - if (b == NULL) { - ASN1error(ERR_R_MALLOC_FAILURE); - return (NULL); - } - p = b; - i = i2d(x, &p); - p2 = b; - ret = d2i(NULL, &p2, i); - free(b); - return (ret); -} - -#endif - -/* ASN1_ITEM version of dup: this follows the model above except we don't need - * to allocate the buffer. At some point this could be rewritten to directly dup - * the underlying structure instead of doing and encode and decode. - */ - -void * -ASN1_item_dup(const ASN1_ITEM *it, void *x) -{ - unsigned char *b = NULL; - const unsigned char *p; - long i; - void *ret; - - if (x == NULL) - return (NULL); - - i = ASN1_item_i2d(x, &b, it); - if (b == NULL) { - ASN1error(ERR_R_MALLOC_FAILURE); - return (NULL); - } - p = b; - ret = ASN1_item_d2i(NULL, &p, i, it); - free(b); - return (ret); -} diff --git a/lib/libcrypto/asn1/a_verify.c b/lib/libcrypto/asn1/a_verify.c deleted file mode 100644 index a8a37908826..00000000000 --- a/lib/libcrypto/asn1/a_verify.c +++ /dev/null @@ -1,168 +0,0 @@ -/* $OpenBSD: a_verify.c,v 1.25 2021/12/12 21:30:13 tb Exp $ */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "asn1_locl.h" -#include "evp_locl.h" - -int -ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, - ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) -{ - EVP_MD_CTX ctx; - unsigned char *buf_in = NULL; - int ret = -1, inl; - - int mdnid, pknid; - - if (!pkey) { - ASN1error(ERR_R_PASSED_NULL_PARAMETER); - return -1; - } - - if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) - { - ASN1error(ASN1_R_INVALID_BIT_STRING_BITS_LEFT); - return -1; - } - - EVP_MD_CTX_init(&ctx); - - /* Convert signature OID into digest and public key OIDs */ - if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { - ASN1error(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); - goto err; - } - if (mdnid == NID_undef) { - if (!pkey->ameth || !pkey->ameth->item_verify) { - ASN1error(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); - goto err; - } - ret = pkey->ameth->item_verify(&ctx, it, asn, a, - signature, pkey); - /* Return value of 2 means carry on, anything else means we - * exit straight away: either a fatal error of the underlying - * verification routine handles all verification. - */ - if (ret != 2) - goto err; - ret = -1; - } else { - const EVP_MD *type; - type = EVP_get_digestbynid(mdnid); - if (type == NULL) { - ASN1error(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); - goto err; - } - - /* Check public key OID matches public key type */ - if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { - ASN1error(ASN1_R_WRONG_PUBLIC_KEY_TYPE); - goto err; - } - - if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) { - ASN1error(ERR_R_EVP_LIB); - ret = 0; - goto err; - } - - } - - inl = ASN1_item_i2d(asn, &buf_in, it); - - if (buf_in == NULL) { - ASN1error(ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) { - ASN1error(ERR_R_EVP_LIB); - ret = 0; - goto err; - } - - freezero(buf_in, (unsigned int)inl); - - if (EVP_DigestVerifyFinal(&ctx, signature->data, - (size_t)signature->length) <= 0) { - ASN1error(ERR_R_EVP_LIB); - ret = 0; - goto err; - } - /* we don't need to zero the 'ctx' because we just checked - * public information */ - /* memset(&ctx,0,sizeof(ctx)); */ - ret = 1; - -err: - EVP_MD_CTX_cleanup(&ctx); - return (ret); -} diff --git a/lib/libcrypto/asn1/a_sign.c b/lib/libcrypto/asn1/asn1_item.c similarity index 53% rename from lib/libcrypto/asn1/a_sign.c rename to lib/libcrypto/asn1/asn1_item.c index b6b4c209701..8db1713b298 100644 --- a/lib/libcrypto/asn1/a_sign.c +++ b/lib/libcrypto/asn1/asn1_item.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_sign.c,v 1.24 2021/12/12 21:30:13 tb Exp $ */ +/* $OpenBSD: asn1_item.c,v 1.1 2021/12/25 12:00:22 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -109,22 +109,64 @@ * */ -#include +#include -#include -#include -#include - -#include #include #include #include -#include #include #include "asn1_locl.h" #include "evp_locl.h" +/* + * ASN1_ITEM version of dup: this follows the model above except we don't need + * to allocate the buffer. At some point this could be rewritten to directly dup + * the underlying structure instead of doing and encode and decode. + */ + +int +ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn, + unsigned char *md, unsigned int *len) +{ + int i; + unsigned char *str = NULL; + + i = ASN1_item_i2d(asn, &str, it); + if (!str) + return (0); + + if (!EVP_Digest(str, i, md, len, type, NULL)) { + free(str); + return (0); + } + + free(str); + return (1); +} + +void * +ASN1_item_dup(const ASN1_ITEM *it, void *x) +{ + unsigned char *b = NULL; + const unsigned char *p; + long i; + void *ret; + + if (x == NULL) + return (NULL); + + i = ASN1_item_i2d(x, &b, it); + if (b == NULL) { + ASN1error(ERR_R_MALLOC_FAILURE); + return (NULL); + } + p = b; + ret = ASN1_item_d2i(NULL, &p, i, it); + free(b); + return (ret); +} + int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, const EVP_MD *type) @@ -138,7 +180,6 @@ ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx); } - int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) @@ -232,3 +273,323 @@ err: freezero((char *)buf_out, outll); return (outl); } + +int +ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, + ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) +{ + EVP_MD_CTX ctx; + unsigned char *buf_in = NULL; + int ret = -1, inl; + + int mdnid, pknid; + + if (!pkey) { + ASN1error(ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) + { + ASN1error(ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + return -1; + } + + EVP_MD_CTX_init(&ctx); + + /* Convert signature OID into digest and public key OIDs */ + if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { + ASN1error(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + goto err; + } + if (mdnid == NID_undef) { + if (!pkey->ameth || !pkey->ameth->item_verify) { + ASN1error(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + goto err; + } + ret = pkey->ameth->item_verify(&ctx, it, asn, a, + signature, pkey); + /* Return value of 2 means carry on, anything else means we + * exit straight away: either a fatal error of the underlying + * verification routine handles all verification. + */ + if (ret != 2) + goto err; + ret = -1; + } else { + const EVP_MD *type; + type = EVP_get_digestbynid(mdnid); + if (type == NULL) { + ASN1error(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + goto err; + } + + /* Check public key OID matches public key type */ + if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { + ASN1error(ASN1_R_WRONG_PUBLIC_KEY_TYPE); + goto err; + } + + if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) { + ASN1error(ERR_R_EVP_LIB); + ret = 0; + goto err; + } + + } + + inl = ASN1_item_i2d(asn, &buf_in, it); + + if (buf_in == NULL) { + ASN1error(ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) { + ASN1error(ERR_R_EVP_LIB); + ret = 0; + goto err; + } + + freezero(buf_in, (unsigned int)inl); + + if (EVP_DigestVerifyFinal(&ctx, signature->data, + (size_t)signature->length) <= 0) { + ASN1error(ERR_R_EVP_LIB); + ret = 0; + goto err; + } + /* we don't need to zero the 'ctx' because we just checked + * public information */ + /* memset(&ctx,0,sizeof(ctx)); */ + ret = 1; + +err: + EVP_MD_CTX_cleanup(&ctx); + return (ret); +} + +#define HEADER_SIZE 8 +#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024) +int +asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) +{ + BUF_MEM *b; + unsigned char *p; + const unsigned char *q; + long slen; + int i, inf, tag, xclass; + size_t want = HEADER_SIZE; + int eos = 0; + size_t off = 0; + size_t len = 0; + + b = BUF_MEM_new(); + if (b == NULL) { + ASN1error(ERR_R_MALLOC_FAILURE); + return -1; + } + + ERR_clear_error(); + for (;;) { + if (want >= (len - off)) { + want -= (len - off); + + if (len + want < len || + !BUF_MEM_grow_clean(b, len + want)) { + ASN1error(ERR_R_MALLOC_FAILURE); + goto err; + } + i = BIO_read(in, &(b->data[len]), want); + if ((i < 0) && ((len - off) == 0)) { + ASN1error(ASN1_R_NOT_ENOUGH_DATA); + goto err; + } + if (i > 0) { + if (len + i < len) { + ASN1error(ASN1_R_TOO_LONG); + goto err; + } + len += i; + } + } + /* else data already loaded */ + + p = (unsigned char *) & (b->data[off]); + q = p; + inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off); + if (inf & 0x80) { + unsigned long e; + + e = ERR_GET_REASON(ERR_peek_error()); + if (e != ASN1_R_TOO_LONG) + goto err; + else + ERR_clear_error(); /* clear error */ + } + i = q - p; /* header length */ + off += i; /* end of data */ + + if (inf & 1) { + /* no data body so go round again */ + eos++; + if (eos < 0) { + ASN1error(ASN1_R_HEADER_TOO_LONG); + goto err; + } + want = HEADER_SIZE; + } else if (eos && slen == 0 && tag == V_ASN1_EOC) { + /* eos value, so go back and read another header */ + eos--; + if (eos <= 0) + break; + else + want = HEADER_SIZE; + } else { + /* suck in slen bytes of data */ + want = slen; + if (want > (len - off)) { + size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE; + + want -= (len - off); + if (want > INT_MAX /* BIO_read takes an int length */ || + len+want < len) { + ASN1error(ASN1_R_TOO_LONG); + goto err; + } + while (want > 0) { + /* + * Read content in chunks of increasing size + * so we can return an error for EOF without + * having to allocate the entire content length + * in one go. + */ + size_t chunk = want > chunk_max ? chunk_max : want; + + if (!BUF_MEM_grow_clean(b, len + chunk)) { + ASN1error(ERR_R_MALLOC_FAILURE); + goto err; + } + want -= chunk; + while (chunk > 0) { + i = BIO_read(in, &(b->data[len]), chunk); + if (i <= 0) { + ASN1error(ASN1_R_NOT_ENOUGH_DATA); + goto err; + } + /* + * This can't overflow because |len+want| + * didn't overflow. + */ + len += i; + chunk -= i; + } + if (chunk_max < INT_MAX/2) + chunk_max *= 2; + } + } + if (off + slen < off) { + ASN1error(ASN1_R_TOO_LONG); + goto err; + } + off += slen; + if (eos <= 0) { + break; + } else + want = HEADER_SIZE; + } + } + + if (off > INT_MAX) { + ASN1error(ASN1_R_TOO_LONG); + goto err; + } + + *pb = b; + return off; + +err: + if (b != NULL) + BUF_MEM_free(b); + return -1; +} + +void * +ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) +{ + BUF_MEM *b = NULL; + const unsigned char *p; + void *ret = NULL; + int len; + + len = asn1_d2i_read_bio(in, &b); + if (len < 0) + goto err; + + p = (const unsigned char *)b->data; + ret = ASN1_item_d2i(x, &p, len, it); + +err: + if (b != NULL) + BUF_MEM_free(b); + return (ret); +} + +void * +ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) +{ + BIO *b; + char *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ASN1error(ERR_R_BUF_LIB); + return (NULL); + } + BIO_set_fp(b, in, BIO_NOCLOSE); + ret = ASN1_item_d2i_bio(it, b, x); + BIO_free(b); + return (ret); +} + +int +ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) +{ + unsigned char *b = NULL; + int i, j = 0, n, ret = 1; + + n = ASN1_item_i2d(x, &b, it); + if (b == NULL) { + ASN1error(ERR_R_MALLOC_FAILURE); + return (0); + } + + for (;;) { + i = BIO_write(out, &(b[j]), n); + if (i == n) + break; + if (i <= 0) { + ret = 0; + break; + } + j += i; + n -= i; + } + free(b); + return (ret); +} + +int +ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ASN1error(ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, out, BIO_NOCLOSE); + ret = ASN1_item_i2d_bio(it, b, x); + BIO_free(b); + return (ret); +} diff --git a/lib/libcrypto/asn1/asn1_locl.h b/lib/libcrypto/asn1/asn1_locl.h index 851c6e3400e..3b949dba654 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.14 2021/12/25 07:04:03 jsing Exp $ */ +/* $OpenBSD: asn1_locl.h,v 1.15 2021/12/25 12:00:22 jsing Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -157,6 +157,8 @@ struct x509_crl_method_st { int UTF8_getc(const unsigned char *str, int len, unsigned long *val); int UTF8_putc(unsigned char *str, int len, unsigned long value); +int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); + 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); diff --git a/lib/libcrypto/asn1/a_i2d_fp.c b/lib/libcrypto/asn1/asn1_old.c similarity index 82% rename from lib/libcrypto/asn1/a_i2d_fp.c rename to lib/libcrypto/asn1/asn1_old.c index 6398978aac9..d23cae06fbe 100644 --- a/lib/libcrypto/asn1/a_i2d_fp.c +++ b/lib/libcrypto/asn1/asn1_old.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_i2d_fp.c,v 1.15 2017/01/29 17:49:22 beck Exp $ */ +/* $OpenBSD: asn1_old.c,v 1.1 2021/12/25 12:00:22 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -56,66 +56,81 @@ * [including the GNU Public Licence.] */ +#include #include #include #include #include +#include "asn1_locl.h" + #ifndef NO_OLD_ASN1 -int -ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x) +void * +ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x) +{ + unsigned char *b, *p; + const unsigned char *p2; + int i; + char *ret; + + if (x == NULL) + return (NULL); + + i = i2d(x, NULL); + b = malloc(i + 10); + if (b == NULL) { + ASN1error(ERR_R_MALLOC_FAILURE); + return (NULL); + } + p = b; + i = i2d(x, &p); + p2 = b; + ret = d2i(NULL, &p2, i); + free(b); + return (ret); +} + +void * +ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x) { BIO *b; - int ret; + void *ret; if ((b = BIO_new(BIO_s_file())) == NULL) { ASN1error(ERR_R_BUF_LIB); - return (0); + return (NULL); } - BIO_set_fp(b, out, BIO_NOCLOSE); - ret = ASN1_i2d_bio(i2d, b, x); + BIO_set_fp(b, in, BIO_NOCLOSE); + ret = ASN1_d2i_bio(xnew, d2i, b, x); BIO_free(b); return (ret); } -int -ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x) +void * +ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x) { - char *b; - unsigned char *p; - int i, j = 0, n, ret = 1; + BUF_MEM *b = NULL; + const unsigned char *p; + void *ret = NULL; + int len; - n = i2d(x, NULL); - b = malloc(n); - if (b == NULL) { - ASN1error(ERR_R_MALLOC_FAILURE); - return (0); - } + len = asn1_d2i_read_bio(in, &b); + if (len < 0) + goto err; - p = (unsigned char *)b; - i2d(x, &p); + p = (unsigned char *)b->data; + ret = d2i(x, &p, len); - for (;;) { - i = BIO_write(out, &(b[j]), n); - if (i == n) - break; - if (i <= 0) { - ret = 0; - break; - } - j += i; - n -= i; - } - free(b); +err: + if (b != NULL) + BUF_MEM_free(b); return (ret); } -#endif - int -ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) +ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x) { BIO *b; int ret; @@ -125,23 +140,28 @@ ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) return (0); } BIO_set_fp(b, out, BIO_NOCLOSE); - ret = ASN1_item_i2d_bio(it, b, x); + ret = ASN1_i2d_bio(i2d, b, x); BIO_free(b); return (ret); } int -ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) +ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x) { - unsigned char *b = NULL; + char *b; + unsigned char *p; int i, j = 0, n, ret = 1; - n = ASN1_item_i2d(x, &b, it); + n = i2d(x, NULL); + b = malloc(n); if (b == NULL) { ASN1error(ERR_R_MALLOC_FAILURE); return (0); } + p = (unsigned char *)b; + i2d(x, &p); + for (;;) { i = BIO_write(out, &(b[j]), n); if (i == n) @@ -156,3 +176,5 @@ ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) free(b); return (ret); } + +#endif -- 2.20.1