diff options
author | Matt Caswell <matt@openssl.org> | 2021-06-08 11:49:06 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2021-06-14 09:43:01 +0100 |
commit | 8c7c1c84cbaa38a4053404883d666ea8dff81b3a (patch) | |
tree | e775c97857d6cf816b94573bcbad11e68ed691fb /crypto | |
parent | 1c49be8673713d2ceb03a63be03531d9b28a46bd (diff) |
Add a generic SubjectPublicKeyInfo decoder
Previously all the SubjectPublicKeyInfo decoders were specific to a key
type. We would iterate over all them until a match was found for the correct
key type. Each one would fully decode the key before then testing whether
it was a match or not - throwing it away if not. This was very inefficient.
Instead we introduce a generic SubjectPublicKeyInfo decoder which figures
out what type of key is contained within it, before subsequently passing on
the data to a key type specific SubjectPublicKeyInfo decoder.
Fixes #15646
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15662)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/ec/ec_backend.c | 29 | ||||
-rw-r--r-- | crypto/x509/x_pubkey.c | 17 |
2 files changed, 46 insertions, 0 deletions
diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c index defcb649fb..9b4467f2be 100644 --- a/crypto/ec/ec_backend.c +++ b/crypto/ec/ec_backend.c @@ -726,6 +726,35 @@ int ossl_ec_pt_format_param2id(const OSSL_PARAM *p, int *id) } #ifndef FIPS_MODULE +int ossl_x509_algor_is_sm2(const X509_ALGOR *palg) +{ + int ptype = 0; + const void *pval = NULL; + + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype == V_ASN1_OBJECT) + return OBJ_obj2nid((ASN1_OBJECT *)pval) == NID_sm2; + + if (ptype == V_ASN1_SEQUENCE) { + const ASN1_STRING *str = pval; + const unsigned char *der = str->data; + int derlen = str->length; + EC_GROUP *group; + int ret; + + if ((group = d2i_ECPKParameters(NULL, &der, derlen)) == NULL) + ret = 0; + else + ret = (EC_GROUP_get_curve_name(group) == NID_sm2); + + EC_GROUP_free(group); + return ret; + } + + return 0; +} + EC_KEY *ossl_ec_key_param_from_x509_algor(const X509_ALGOR *palg, OSSL_LIB_CTX *libctx, const char *propq) { diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c index 3f447c4c12..e669ae3574 100644 --- a/crypto/x509/x_pubkey.c +++ b/crypto/x509/x_pubkey.c @@ -65,6 +65,23 @@ ASN1_SEQUENCE(X509_PUBKEY_INTERNAL) = { ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) } static_ASN1_SEQUENCE_END_name(X509_PUBKEY, X509_PUBKEY_INTERNAL) +X509_PUBKEY *ossl_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp, + long len, OSSL_LIB_CTX *libctx) +{ + X509_PUBKEY *xpub = OPENSSL_zalloc(sizeof(*xpub)); + + if (xpub == NULL) + return NULL; + return (X509_PUBKEY *)ASN1_item_d2i_ex((ASN1_VALUE **)&xpub, pp, len, + ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL), + libctx, NULL); +} + +void ossl_X509_PUBKEY_INTERNAL_free(X509_PUBKEY *xpub) +{ + ASN1_item_free((ASN1_VALUE *)xpub, ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL)); +} + static void x509_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; |