diff options
Diffstat (limited to 'crypto/asn1')
-rw-r--r-- | crypto/asn1/a_object.c | 15 | ||||
-rw-r--r-- | crypto/asn1/a_print.c | 9 | ||||
-rw-r--r-- | crypto/asn1/a_strex.c | 4 | ||||
-rw-r--r-- | crypto/asn1/asn1_lib.c | 21 | ||||
-rw-r--r-- | crypto/asn1/asn1_par.c | 3 | ||||
-rw-r--r-- | crypto/asn1/asn_mime.c | 6 | ||||
-rw-r--r-- | crypto/asn1/bio_asn1.c | 11 | ||||
-rw-r--r-- | crypto/asn1/bio_ndef.c | 46 | ||||
-rw-r--r-- | crypto/asn1/charmap.h | 2 | ||||
-rw-r--r-- | crypto/asn1/charmap.pl | 9 | ||||
-rw-r--r-- | crypto/asn1/d2i_pr.c | 73 | ||||
-rw-r--r-- | crypto/asn1/t_spki.c | 4 |
12 files changed, 147 insertions, 56 deletions
diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c index d67a723c9611..8ade9e50a7cb 100644 --- a/crypto/asn1/a_object.c +++ b/crypto/asn1/a_object.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -286,16 +286,13 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, } } - /* - * only the ASN1_OBJECTs from the 'table' will have values for ->sn or - * ->ln - */ if ((a == NULL) || ((*a) == NULL) || !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { if ((ret = ASN1_OBJECT_new()) == NULL) return NULL; - } else + } else { ret = (*a); + } p = *pp; /* detach data from object */ @@ -313,6 +310,12 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA; } memcpy(data, p, length); + /* If there are dynamic strings, free them here, and clear the flag */ + if ((ret->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) != 0) { + OPENSSL_free((char *)ret->sn); + OPENSSL_free((char *)ret->ln); + ret->flags &= ~ASN1_OBJECT_FLAG_DYNAMIC_STRINGS; + } /* reattach data to object, after which it remains const */ ret->data = data; ret->length = length; diff --git a/crypto/asn1/a_print.c b/crypto/asn1/a_print.c index 85a631a27aa7..3790e82bb13a 100644 --- a/crypto/asn1/a_print.c +++ b/crypto/asn1/a_print.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,12 +18,13 @@ int ASN1_PRINTABLE_type(const unsigned char *s, int len) int ia5 = 0; int t61 = 0; - if (len <= 0) - len = -1; if (s == NULL) return V_ASN1_PRINTABLESTRING; - while ((*s) && (len-- != 0)) { + if (len < 0) + len = strlen((const char *)s); + + while (len-- > 0) { c = *(s++); if (!ossl_isasn1print(c)) ia5 = 1; diff --git a/crypto/asn1/a_strex.c b/crypto/asn1/a_strex.c index 4879b33785e9..284dde274c9f 100644 --- a/crypto/asn1/a_strex.c +++ b/crypto/asn1/a_strex.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -280,6 +280,8 @@ static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, t.type = str->type; t.value.ptr = (char *)str; der_len = i2d_ASN1_TYPE(&t, NULL); + if (der_len <= 0) + return -1; if ((der_buf = OPENSSL_malloc(der_len)) == NULL) { ASN1err(ASN1_F_DO_DUMP, ERR_R_MALLOC_FAILURE); return -1; diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c index 366afc5f6c6b..b9b7ad8e9e02 100644 --- a/crypto/asn1/asn1_lib.c +++ b/crypto/asn1/asn1_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -292,7 +292,12 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in) } if ((size_t)str->length <= len || str->data == NULL) { c = str->data; +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* No NUL terminator in fuzzing builds */ + str->data = OPENSSL_realloc(c, len != 0 ? len : 1); +#else str->data = OPENSSL_realloc(c, len + 1); +#endif if (str->data == NULL) { ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE); str->data = c; @@ -302,8 +307,17 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in) str->length = len; if (data != NULL) { memcpy(str->data, data, len); - /* an allowance for strings :-) */ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Set the unused byte to something non NUL and printable. */ + if (len == 0) + str->data[len] = '~'; +#else + /* + * Add a NUL terminator. This should not be necessary - but we add it as + * a safety precaution + */ str->data[len] = '\0'; +#endif } return 1; } @@ -365,7 +379,8 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) i = (a->length - b->length); if (i == 0) { - i = memcmp(a->data, b->data, a->length); + if (a->length != 0) + i = memcmp(a->data, b->data, a->length); if (i == 0) return a->type - b->type; else diff --git a/crypto/asn1/asn1_par.c b/crypto/asn1/asn1_par.c index 3f10c7cb94c5..a32fa47f2206 100644 --- a/crypto/asn1/asn1_par.c +++ b/crypto/asn1/asn1_par.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -325,6 +325,7 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, } if (BIO_puts(bp, "]") <= 0) goto end; + dump_cont = 0; } if (!nl) { diff --git a/crypto/asn1/asn_mime.c b/crypto/asn1/asn_mime.c index 38735cd86f3e..36853612b69c 100644 --- a/crypto/asn1/asn_mime.c +++ b/crypto/asn1/asn_mime.c @@ -489,6 +489,7 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags) char eol; int len; char linebuf[MAX_SMLEN]; + int ret; /* * Buffer output so we don't write one line at a time. This is useful * when streaming as we don't end up with one OCTET STRING per line. @@ -523,9 +524,12 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags) BIO_write(out, "\r\n", 2); } } - (void)BIO_flush(out); + ret = BIO_flush(out); BIO_pop(out); BIO_free(bf); + if (ret <= 0) + return 0; + return 1; } diff --git a/crypto/asn1/bio_asn1.c b/crypto/asn1/bio_asn1.c index 86ee56632305..17b0d1aa6cad 100644 --- a/crypto/asn1/bio_asn1.c +++ b/crypto/asn1/bio_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -138,6 +138,11 @@ static int asn1_bio_free(BIO *b) if (ctx == NULL) return 0; + if (ctx->prefix_free != NULL) + ctx->prefix_free(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg); + if (ctx->suffix_free != NULL) + ctx->suffix_free(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg); + OPENSSL_free(ctx->buf); OPENSSL_free(ctx); BIO_set_data(b, NULL); @@ -167,7 +172,7 @@ static int asn1_bio_write(BIO *b, const char *in, int inl) case ASN1_STATE_START: if (!asn1_bio_setup_ex(b, ctx, ctx->prefix, ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER)) - return 0; + return -1; break; /* Copy any pre data first */ @@ -184,7 +189,7 @@ static int asn1_bio_write(BIO *b, const char *in, int inl) case ASN1_STATE_HEADER: ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl; if (!ossl_assert(ctx->buflen <= ctx->bufsize)) - return 0; + return -1; p = ctx->buf; ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class); ctx->copylen = inl; diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c index 6222c99074de..c8a776b482d0 100644 --- a/crypto/asn1/bio_ndef.c +++ b/crypto/asn1/bio_ndef.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -49,12 +49,19 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg); static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg); +/* + * On success, the returned BIO owns the input BIO as part of its BIO chain. + * On failure, NULL is returned and the input BIO is owned by the caller. + * + * Unfortunately cannot constify this due to CMS_stream() and PKCS7_stream() + */ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) { NDEF_SUPPORT *ndef_aux = NULL; BIO *asn_bio = NULL; const ASN1_AUX *aux = it->funcs; ASN1_STREAM_ARG sarg; + BIO *pop_bio = NULL; if (!aux || !aux->asn1_cb) { ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED); @@ -69,21 +76,39 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) out = BIO_push(asn_bio, out); if (out == NULL) goto err; + pop_bio = asn_bio; - BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free); - BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free); + if (BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free) <= 0 + || BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free) <= 0 + || BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux) <= 0) + goto err; /* - * Now let callback prepends any digest, cipher etc BIOs ASN1 structure - * needs. + * Now let the callback prepend any digest, cipher, etc., that the BIO's + * ASN1 structure needs. */ sarg.out = out; sarg.ndef_bio = NULL; sarg.boundary = NULL; - if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) + /* + * The asn1_cb(), must not have mutated asn_bio on error, leaving it in the + * middle of some partially built, but not returned BIO chain. + */ + if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) { + /* + * ndef_aux is now owned by asn_bio so we must not free it in the err + * clean up block + */ + ndef_aux = NULL; goto err; + } + + /* + * We must not fail now because the callback has prepended additional + * BIOs to the chain + */ ndef_aux->val = val; ndef_aux->it = it; @@ -91,11 +116,11 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) ndef_aux->boundary = sarg.boundary; ndef_aux->out = out; - BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux); - return sarg.ndef_bio; err: + /* BIO_pop() is NULL safe */ + (void)BIO_pop(pop_bio); BIO_free(asn_bio); OPENSSL_free(ndef_aux); return NULL; @@ -113,6 +138,8 @@ static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg) ndef_aux = *(NDEF_SUPPORT **)parg; derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); + if (derlen < 0) + return 0; if ((p = OPENSSL_malloc(derlen)) == NULL) { ASN1err(ASN1_F_NDEF_PREFIX, ERR_R_MALLOC_FAILURE); return 0; @@ -140,6 +167,9 @@ static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, ndef_aux = *(NDEF_SUPPORT **)parg; + if (ndef_aux == NULL) + return 0; + OPENSSL_free(ndef_aux->derbuf); ndef_aux->derbuf = NULL; diff --git a/crypto/asn1/charmap.h b/crypto/asn1/charmap.h index e234c9e615d0..5630291bd58c 100644 --- a/crypto/asn1/charmap.h +++ b/crypto/asn1/charmap.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by crypto/asn1/charmap.pl * - * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/asn1/charmap.pl b/crypto/asn1/charmap.pl index dadd8df7749d..52fa5a7900ca 100644 --- a/crypto/asn1/charmap.pl +++ b/crypto/asn1/charmap.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the OpenSSL license (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,9 @@ # https://www.openssl.org/source/license.html use strict; +use FindBin; +use lib "$FindBin::Bin/../../util/perl"; +use OpenSSL::copyright; my ($i, @arr); @@ -82,8 +85,8 @@ $arr[ord("?")] |= $PSTRING_CHAR; # Now generate the C code -# Output year depends on the year of the script. -my $YEAR = [localtime([stat($0)]->[9])]->[5] + 1900; +# Year the file was generated. +my $YEAR = OpenSSL::copyright::year_of($0); print <<EOF; /* * WARNING: do not edit! diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c index 7b127d2092fa..2094963036fe 100644 --- a/crypto/asn1/d2i_pr.c +++ b/crypto/asn1/d2i_pr.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -78,13 +78,53 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, * type */ +static EVP_PKEY *key_as_pkcs8(const unsigned char **pp, long length, int *carry_on) +{ + const unsigned char *p = *pp; + PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); + EVP_PKEY *ret; + + if (p8 == NULL) + return NULL; + + ret = EVP_PKCS82PKEY(p8); + if (ret == NULL) + *carry_on = 0; + + PKCS8_PRIV_KEY_INFO_free(p8); + + if (ret != NULL) + *pp = p; + + return ret; +} + EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, long length) { STACK_OF(ASN1_TYPE) *inkey; const unsigned char *p; int keytype; + EVP_PKEY *ret = NULL; + int carry_on = 1; + + ERR_set_mark(); + ret = key_as_pkcs8(pp, length, &carry_on); + if (ret != NULL) { + ERR_clear_last_mark(); + if (a != NULL) + *a = ret; + return ret; + } + + if (carry_on == 0) { + ERR_clear_last_mark(); + ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY, + ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return NULL; + } p = *pp; + /* * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by * analyzing it we can determine the passed structure: this assumes the @@ -100,28 +140,15 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, keytype = EVP_PKEY_DSA; else if (sk_ASN1_TYPE_num(inkey) == 4) keytype = EVP_PKEY_EC; - else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not - * traditional format */ - PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); - EVP_PKEY *ret; - - sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); - if (!p8) { - ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY, - ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return NULL; - } - ret = EVP_PKCS82PKEY(p8); - PKCS8_PRIV_KEY_INFO_free(p8); - if (ret == NULL) - return NULL; - *pp = p; - if (a) { - *a = ret; - } - return ret; - } else + else keytype = EVP_PKEY_RSA; sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); - return d2i_PrivateKey(keytype, a, pp, length); + + ret = d2i_PrivateKey(keytype, a, pp, length); + if (ret != NULL) + ERR_pop_to_mark(); + else + ERR_clear_last_mark(); + + return ret; } diff --git a/crypto/asn1/t_spki.c b/crypto/asn1/t_spki.c index 51b56d0aa9f7..3d4aea8ad9a4 100644 --- a/crypto/asn1/t_spki.c +++ b/crypto/asn1/t_spki.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -38,7 +38,7 @@ int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki) } chal = spki->spkac->challenge; if (chal->length) - BIO_printf(out, " Challenge String: %s\n", chal->data); + BIO_printf(out, " Challenge String: %.*s\n", chal->length, chal->data); i = OBJ_obj2nid(spki->sig_algor.algorithm); BIO_printf(out, " Signature Algorithm: %s", (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); |