summaryrefslogtreecommitdiffstats
path: root/crypto/x509/x_pubkey.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-05-27 16:24:00 +0100
committerMatt Caswell <matt@openssl.org>2021-06-08 18:53:28 +0100
commit2b049e933a8d017fa667e69b5b0ec4437eb8d68c (patch)
treefa5b4e59991907be8f6275b7f0e548611a5ebda3 /crypto/x509/x_pubkey.c
parent7834d50fa92c622e3a1b29a38abbbec2afd1290d (diff)
Use the right class/tag when decoding an embedded key
When a key (SubjectPublicKeyInfo) is embedded in some other structure it may use an implicit tag. However the decoders can only handle the universal class and don't know how to interpret the implicit tag. Therefore we modify the data into a form the decoders can handle. Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15504)
Diffstat (limited to 'crypto/x509/x_pubkey.c')
-rw-r--r--crypto/x509/x_pubkey.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c
index 2fe5724743..9ba63788bc 100644
--- a/crypto/x509/x_pubkey.c
+++ b/crypto/x509/x_pubkey.c
@@ -111,9 +111,11 @@ static int x509_pubkey_ex_d2i_ex(ASN1_VALUE **pval,
const char *propq)
{
const unsigned char *in_saved = *in;
+ size_t publen;
X509_PUBKEY *pubkey;
int ret;
OSSL_DECODER_CTX *dctx = NULL;
+ unsigned char *tmpbuf = NULL;
if (*pval == NULL && !x509_pubkey_ex_new_ex(pval, it, libctx, propq))
return 0;
@@ -128,6 +130,12 @@ static int x509_pubkey_ex_d2i_ex(ASN1_VALUE **pval,
tag, aclass, opt, ctx)) <= 0)
return ret;
+ publen = *in - in_saved;
+ if (!ossl_assert(publen > 0)) {
+ ERR_raise(ERR_LIB_ASN1, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
pubkey = (X509_PUBKEY *)*pval;
EVP_PKEY_free(pubkey->pkey);
pubkey->pkey = NULL;
@@ -151,9 +159,24 @@ static int x509_pubkey_ex_d2i_ex(ASN1_VALUE **pval,
/* Try to decode it into an EVP_PKEY with OSSL_DECODER */
if (ret <= 0 && !pubkey->flag_force_legacy) {
- const unsigned char *p = in_saved;
+ const unsigned char *p;
char txtoidname[OSSL_MAX_NAME_SIZE];
+ /*
+ * The decoders don't know how to handle anything other than Universal
+ * class so we modify the data accordingly.
+ */
+ if (aclass != V_ASN1_UNIVERSAL) {
+ tmpbuf = OPENSSL_memdup(in_saved, publen);
+ if (tmpbuf == NULL) {
+ ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ in_saved = tmpbuf;
+ *tmpbuf = V_ASN1_CONSTRUCTED | V_ASN1_SEQUENCE;
+ }
+ p = in_saved;
+
if (OBJ_obj2txt(txtoidname, sizeof(txtoidname),
pubkey->algor->algorithm, 0) <= 0) {
ERR_clear_last_mark();
@@ -176,6 +199,7 @@ static int x509_pubkey_ex_d2i_ex(ASN1_VALUE **pval,
ret = 1;
end:
OSSL_DECODER_CTX_free(dctx);
+ OPENSSL_free(tmpbuf);
return ret;
}