diff options
author | Tomas Mraz <tomas@openssl.org> | 2021-04-27 16:01:13 +0200 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-05-13 13:30:07 +0200 |
commit | b4c4a2c68817ea0b2df8012673fa4e0712681704 (patch) | |
tree | 0e9ef2698c96e048dda681af0aadc9f7daac384a /crypto | |
parent | e9fe0f7e9df7e0909ca52a024b889e48616a29d9 (diff) |
Implement pem_read_key directly through OSSL_DECODER
Using OSSL_STORE is too heavy and breaks things.
There were also needed various fixes mainly for missing proper
handling of the SM2 keys in the OSSL_DECODER.
Fixes #14788
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15045)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/ec/ec_asn1.c | 7 | ||||
-rw-r--r-- | crypto/ec/ec_key.c | 3 | ||||
-rw-r--r-- | crypto/pem/pem_pkey.c | 84 | ||||
-rw-r--r-- | crypto/x509/x_pubkey.c | 4 |
4 files changed, 40 insertions, 58 deletions
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index ed30d1b3a9..0e37b21ac3 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -965,6 +965,9 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) goto err; } + if (EC_GROUP_get_curve_name(ret->group) == NID_sm2) + EC_KEY_set_flags(ret, EC_FLAG_SM2_RANGE); + EC_POINT_clear_free(ret->pub_key); ret->pub_key = EC_POINT_new(ret->group); if (ret->pub_key == NULL) { @@ -1109,6 +1112,10 @@ EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) ret->dirty_cnt++; return NULL; } + + if (EC_GROUP_get_curve_name(ret->group) == NID_sm2) + EC_KEY_set_flags(ret, EC_FLAG_SM2_RANGE); + ret->dirty_cnt++; if (a) diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index f06715fa6b..ea2bad3e26 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -678,6 +678,9 @@ int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) return 0; EC_GROUP_free(key->group); key->group = EC_GROUP_dup(group); + if (key->group != NULL && EC_GROUP_get_curve_name(key->group) == NID_sm2) + EC_KEY_set_flags(key, EC_FLAG_SM2_RANGE); + key->dirty_cnt++; return (key->group == NULL) ? 0 : 1; } diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c index 3faca8d0ec..cbb07a1356 100644 --- a/crypto/pem/pem_pkey.c +++ b/crypto/pem/pem_pkey.c @@ -7,7 +7,7 @@ * https://www.openssl.org/source/license.html */ -/* We need to use some STORE deprecated APIs */ +/* We need to use some deprecated APIs */ #define OPENSSL_SUPPRESS_DEPRECATED #include <stdio.h> @@ -20,9 +20,8 @@ #include <openssl/pem.h> #include <openssl/engine.h> #include <openssl/dh.h> -#include <openssl/store.h> +#include <openssl/decoder.h> #include <openssl/ui.h> -#include "crypto/store.h" #include "crypto/asn1.h" #include "crypto/evp.h" #include "pem_local.h" @@ -32,71 +31,42 @@ int ossl_pem_check_suffix(const char *pem_str, const char *suffix); static EVP_PKEY *pem_read_bio_key(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u, OSSL_LIB_CTX *libctx, const char *propq, - int expected_store_info_type, - int try_secure) + int selection) { - EVP_PKEY *ret = NULL; - OSSL_STORE_CTX *ctx = NULL; - OSSL_STORE_INFO *info = NULL; - const UI_METHOD *ui_method = NULL; - UI_METHOD *allocated_ui_method = NULL; - - if (expected_store_info_type != OSSL_STORE_INFO_PKEY - && expected_store_info_type != OSSL_STORE_INFO_PUBKEY - && expected_store_info_type != OSSL_STORE_INFO_PARAMS) { - ERR_raise(ERR_LIB_PEM, ERR_R_PASSED_INVALID_ARGUMENT); + EVP_PKEY *pkey = NULL; + OSSL_DECODER_CTX *dctx = NULL; + + dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "PEM", NULL, NULL, + selection, libctx, propq); + + if (dctx == NULL) return NULL; - } if (cb == NULL) cb = PEM_def_callback; - ui_method = allocated_ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0); - if (ui_method == NULL) - return NULL; - if ((ctx = OSSL_STORE_attach(bp, "file", libctx, propq, ui_method, u, - NULL, NULL, NULL)) == NULL) + if (!OSSL_DECODER_CTX_set_pem_password_cb(dctx, cb, u)) goto err; -#ifndef OPENSSL_NO_SECURE_HEAP -# ifndef OPENSSL_NO_DEPRECATED_3_0 - if (try_secure) { - int on = 1; - if (!OSSL_STORE_ctrl(ctx, OSSL_STORE_C_USE_SECMEM, &on)) + + while (!OSSL_DECODER_from_bio(dctx, bp) || pkey == NULL) + if (BIO_eof(bp) != 0) goto err; - } -# endif -#endif - if (!OSSL_STORE_expect(ctx, expected_store_info_type)) + if (!evp_keymgmt_util_has(pkey, selection)) { + EVP_PKEY_free(pkey); + pkey = NULL; + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS); goto err; - - while (!OSSL_STORE_eof(ctx) - && (info = OSSL_STORE_load(ctx)) != NULL) { - if (OSSL_STORE_INFO_get_type(info) == expected_store_info_type) { - switch (expected_store_info_type) { - case OSSL_STORE_INFO_PKEY: - ret = OSSL_STORE_INFO_get1_PKEY(info); - break; - case OSSL_STORE_INFO_PUBKEY: - ret = OSSL_STORE_INFO_get1_PUBKEY(info); - break; - case OSSL_STORE_INFO_PARAMS: - ret = OSSL_STORE_INFO_get1_PARAMS(info); - break; - } - } - OSSL_STORE_INFO_free(info); - info = NULL; } - if (ret != NULL && x != NULL) - *x = ret; + if (x != NULL) { + EVP_PKEY_free(*x); + *x = pkey; + } err: - OSSL_STORE_close(ctx); - UI_destroy_method(allocated_ui_method); - OSSL_STORE_INFO_free(info); - return ret; + OSSL_DECODER_CTX_free(dctx); + return pkey; } EVP_PKEY *PEM_read_bio_PUBKEY_ex(BIO *bp, EVP_PKEY **x, @@ -104,7 +74,7 @@ EVP_PKEY *PEM_read_bio_PUBKEY_ex(BIO *bp, EVP_PKEY **x, OSSL_LIB_CTX *libctx, const char *propq) { return pem_read_bio_key(bp, x, cb, u, libctx, propq, - OSSL_STORE_INFO_PUBKEY, 0); + EVP_PKEY_PUBLIC_KEY); } EVP_PKEY *PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, @@ -142,7 +112,7 @@ EVP_PKEY *PEM_read_bio_PrivateKey_ex(BIO *bp, EVP_PKEY **x, OSSL_LIB_CTX *libctx, const char *propq) { return pem_read_bio_key(bp, x, cb, u, libctx, propq, - OSSL_STORE_INFO_PKEY, 1); + EVP_PKEY_KEYPAIR); } EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, @@ -207,7 +177,7 @@ EVP_PKEY *PEM_read_bio_Parameters_ex(BIO *bp, EVP_PKEY **x, OSSL_LIB_CTX *libctx, const char *propq) { return pem_read_bio_key(bp, x, NULL, NULL, libctx, propq, - OSSL_STORE_INFO_PARAMS, 0); + EVP_PKEY_KEY_PARAMETERS); } EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c index 9b846a8bc2..966a1a534b 100644 --- a/crypto/x509/x_pubkey.c +++ b/crypto/x509/x_pubkey.c @@ -678,12 +678,14 @@ EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length) EVP_PKEY *pkey; EC_KEY *key = NULL; const unsigned char *q; + int type; q = *pp; pkey = d2i_PUBKEY_legacy(NULL, &q, length); if (pkey == NULL) return NULL; - if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) + type = EVP_PKEY_id(pkey); + if (type == EVP_PKEY_EC || type == EVP_PKEY_SM2) key = EVP_PKEY_get1_EC_KEY(pkey); EVP_PKEY_free(pkey); if (key == NULL) |