aboutsummaryrefslogtreecommitdiff
path: root/crypto/asn1
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/asn1')
-rw-r--r--crypto/asn1/a_object.c15
-rw-r--r--crypto/asn1/a_strex.c4
-rw-r--r--crypto/asn1/asn1_lib.c14
-rw-r--r--crypto/asn1/asn1_par.c3
-rw-r--r--crypto/asn1/bio_asn1.c7
-rw-r--r--crypto/asn1/bio_ndef.c7
-rw-r--r--crypto/asn1/d2i_pr.c73
-rw-r--r--crypto/asn1/t_spki.c4
8 files changed, 90 insertions, 37 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_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..3d99d1383d42 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);
+#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,13 @@ 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 :-) */
+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+ /*
+ * Add a NUL terminator. This should not be necessary - but we add it as
+ * a safety precaution
+ */
str->data[len] = '\0';
+#endif
}
return 1;
}
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/bio_asn1.c b/crypto/asn1/bio_asn1.c
index 86ee56632305..914d77c866c6 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);
diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c
index 6222c99074de..760e4846a474 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-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
@@ -113,6 +113,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 +142,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/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));