diff options
author | Matt Caswell <matt@openssl.org> | 2021-05-27 17:24:00 +0200 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2021-06-08 19:53:28 +0200 |
commit | 2b049e933a8d017fa667e69b5b0ec4437eb8d68c (patch) | |
tree | fa5b4e59991907be8f6275b7f0e548611a5ebda3 /crypto | |
parent | Fix CTLOG_new_from_base64_ex() (diff) | |
download | openssl-2b049e933a8d017fa667e69b5b0ec4437eb8d68c.tar.xz openssl-2b049e933a8d017fa667e69b5b0ec4437eb8d68c.zip |
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')
-rw-r--r-- | crypto/x509/x_pubkey.c | 26 |
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; } |