diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c index b1268f22c9..37fe2d3435 100644 --- a/crypto/x509/x_pubkey.c +++ b/crypto/x509/x_pubkey.c @@ -512,7 +512,7 @@ int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp) RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length) { EVP_PKEY *pkey; - RSA *key; + RSA *key = NULL; const unsigned char *q; q = *pp; @@ -549,11 +549,95 @@ int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp) return ret; } +#ifndef OPENSSL_NO_DH +DH *ossl_d2i_DH_PUBKEY(DH **a, const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + DH *key = NULL; + const unsigned char *q; + + q = *pp; + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) + return NULL; + if (EVP_PKEY_id(pkey) == EVP_PKEY_DH) + key = EVP_PKEY_get1_DH(pkey); + EVP_PKEY_free(pkey); + if (key == NULL) + return NULL; + *pp = q; + if (a != NULL) { + DH_free(*a); + *a = key; + } + return key; +} + +int ossl_i2d_DH_PUBKEY(const DH *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return 0; + pktmp = EVP_PKEY_new(); + if (pktmp == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + (void)EVP_PKEY_assign_DH(pktmp, (DH *)a); + ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; + EVP_PKEY_free(pktmp); + return ret; +} + +DH *ossl_d2i_DHx_PUBKEY(DH **a, const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + DH *key = NULL; + const unsigned char *q; + + q = *pp; + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) + return NULL; + if (EVP_PKEY_id(pkey) == EVP_PKEY_DHX) + key = EVP_PKEY_get1_DH(pkey); + EVP_PKEY_free(pkey); + if (key == NULL) + return NULL; + *pp = q; + if (a != NULL) { + DH_free(*a); + *a = key; + } + return key; +} + +int ossl_i2d_DHx_PUBKEY(const DH *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return 0; + pktmp = EVP_PKEY_new(); + if (pktmp == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + (void)EVP_PKEY_assign(pktmp, EVP_PKEY_DHX, (DH *)a); + ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; + EVP_PKEY_free(pktmp); + return ret; +} +#endif + #ifndef OPENSSL_NO_DSA DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length) { EVP_PKEY *pkey; - DSA *key; + DSA *key = NULL; const unsigned char *q; q = *pp; @@ -595,14 +679,15 @@ int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp) EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length) { EVP_PKEY *pkey; - EC_KEY *key; + EC_KEY *key = NULL; const unsigned char *q; q = *pp; pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); if (pkey == NULL) return NULL; - key = EVP_PKEY_get1_EC_KEY(pkey); + if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) + key = EVP_PKEY_get1_EC_KEY(pkey); EVP_PKEY_free(pkey); if (key == NULL) return NULL; @@ -631,6 +716,174 @@ int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp) EVP_PKEY_free(pktmp); return ret; } + +ECX_KEY *ossl_d2i_ED25519_PUBKEY(ECX_KEY **a, + const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + ECX_KEY *key = NULL; + const unsigned char *q; + + q = *pp; + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) + return NULL; + key = ossl_evp_pkey_get1_ED25519(pkey); + EVP_PKEY_free(pkey); + if (key == NULL) + return NULL; + *pp = q; + if (a != NULL) { + ossl_ecx_key_free(*a); + *a = key; + } + return key; +} + +int ossl_i2d_ED25519_PUBKEY(const ECX_KEY *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + + if (a == NULL) + return 0; + if ((pktmp = EVP_PKEY_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + (void)EVP_PKEY_assign(pktmp, EVP_PKEY_ED25519, (ECX_KEY *)a); + ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; + EVP_PKEY_free(pktmp); + return ret; +} + +ECX_KEY *ossl_d2i_ED448_PUBKEY(ECX_KEY **a, + const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + ECX_KEY *key = NULL; + const unsigned char *q; + + q = *pp; + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) + return NULL; + if (EVP_PKEY_id(pkey) == EVP_PKEY_ED448) + key = ossl_evp_pkey_get1_ED448(pkey); + EVP_PKEY_free(pkey); + if (key == NULL) + return NULL; + *pp = q; + if (a != NULL) { + ossl_ecx_key_free(*a); + *a = key; + } + return key; +} + +int ossl_i2d_ED448_PUBKEY(const ECX_KEY *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + + if (a == NULL) + return 0; + if ((pktmp = EVP_PKEY_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + (void)EVP_PKEY_assign(pktmp, EVP_PKEY_ED448, (ECX_KEY *)a); + ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; + EVP_PKEY_free(pktmp); + return ret; +} + +ECX_KEY *ossl_d2i_X25519_PUBKEY(ECX_KEY **a, + const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + ECX_KEY *key = NULL; + const unsigned char *q; + + q = *pp; + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) + return NULL; + if (EVP_PKEY_id(pkey) == EVP_PKEY_X25519) + key = ossl_evp_pkey_get1_X25519(pkey); + EVP_PKEY_free(pkey); + if (key == NULL) + return NULL; + *pp = q; + if (a != NULL) { + ossl_ecx_key_free(*a); + *a = key; + } + return key; +} + +int ossl_i2d_X25519_PUBKEY(const ECX_KEY *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + + if (a == NULL) + return 0; + if ((pktmp = EVP_PKEY_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + (void)EVP_PKEY_assign(pktmp, EVP_PKEY_X25519, (ECX_KEY *)a); + ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; + EVP_PKEY_free(pktmp); + return ret; +} + +ECX_KEY *ossl_d2i_X448_PUBKEY(ECX_KEY **a, + const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + ECX_KEY *key = NULL; + const unsigned char *q; + + q = *pp; + pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); + if (pkey == NULL) + return NULL; + if (EVP_PKEY_id(pkey) == EVP_PKEY_X448) + key = ossl_evp_pkey_get1_X448(pkey); + EVP_PKEY_free(pkey); + if (key == NULL) + return NULL; + *pp = q; + if (a != NULL) { + ossl_ecx_key_free(*a); + *a = key; + } + return key; +} + +int ossl_i2d_X448_PUBKEY(const ECX_KEY *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + + if (a == NULL) + return 0; + if ((pktmp = EVP_PKEY_new()) == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); + return -1; + } + (void)EVP_PKEY_assign(pktmp, EVP_PKEY_X448, (ECX_KEY *)a); + ret = i2d_PUBKEY(pktmp, pp); + pktmp->pkey.ptr = NULL; + EVP_PKEY_free(pktmp); + return ret; +} + #endif int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, diff --git a/include/crypto/x509.h b/include/crypto/x509.h index 623b880959..e0997a4712 100644 --- a/include/crypto/x509.h +++ b/include/crypto/x509.h @@ -14,6 +14,7 @@ # include "internal/refcount.h" # include # include +# include "crypto/ecx.h" /* Internal X509 structures and functions: not for application use */ @@ -328,4 +329,27 @@ ASN1_OCTET_STRING *ossl_x509_pubkey_hash(X509_PUBKEY *pubkey); /* A variant of d2i_PUBKEY() that is guaranteed to only return legacy keys */ EVP_PKEY *ossl_d2i_PUBKEY_legacy(EVP_PKEY **a, const unsigned char **in, long length); + +RSA *ossl_d2i_RSA_PSS_PUBKEY(RSA **a, const unsigned char **pp, long length); +int ossl_i2d_RSA_PSS_PUBKEY(const RSA *a, unsigned char **pp); +# ifndef OPENSSL_NO_DH +DH *ossl_d2i_DH_PUBKEY(DH **a, const unsigned char **pp, long length); +int ossl_i2d_DH_PUBKEY(const DH *a, unsigned char **pp); +DH *ossl_d2i_DHx_PUBKEY(DH **a, const unsigned char **pp, long length); +int ossl_i2d_DHx_PUBKEY(const DH *a, unsigned char **pp); +# endif +# ifndef OPENSSL_NO_EC +ECX_KEY *ossl_d2i_ED25519_PUBKEY(ECX_KEY **a, + const unsigned char **pp, long length); +int ossl_i2d_ED25519_PUBKEY(const ECX_KEY *a, unsigned char **pp); +ECX_KEY *ossl_d2i_ED448_PUBKEY(ECX_KEY **a, + const unsigned char **pp, long length); +int ossl_i2d_ED448_PUBKEY(const ECX_KEY *a, unsigned char **pp); +ECX_KEY *ossl_d2i_X25519_PUBKEY(ECX_KEY **a, + const unsigned char **pp, long length); +int ossl_i2d_X25519_PUBKEY(const ECX_KEY *a, unsigned char **pp); +ECX_KEY *ossl_d2i_X448_PUBKEY(ECX_KEY **a, + const unsigned char **pp, long length); +int ossl_i2d_X448_PUBKEY(const ECX_KEY *a, unsigned char **pp); +# endif #endif diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c index 47fe2bad6b..74f462794a 100644 --- a/providers/implementations/encode_decode/decode_der2key.c +++ b/providers/implementations/encode_decode/decode_der2key.c @@ -137,9 +137,10 @@ struct keytype_desc_st { int selection_mask; /* For type specific decoders, we use the corresponding d2i */ - d2i_of_void *d2i_private_key; - d2i_of_void *d2i_public_key; - d2i_of_void *d2i_key_params; + d2i_of_void *d2i_private_key; /* From type-specific DER */ + d2i_of_void *d2i_public_key; /* From type-specific DER */ + d2i_of_void *d2i_key_params; /* From type-specific DER */ + d2i_of_void *d2i_PUBKEY; /* Wrapped in a SubjectPublicKeyInfo */ /* * For PKCS#8 decoders, we use EVP_PKEY extractors, EVP_PKEY_get1_{TYPE}() @@ -301,11 +302,14 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, goto next; } if (key == NULL - && ctx->desc->d2i_public_key != NULL + && (ctx->desc->d2i_PUBKEY != NULL || ctx->desc->d2i_public_key != NULL) && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { RESET_ERR_MARK(); derp = der; - key = ctx->desc->d2i_public_key(NULL, &derp, der_len); + if (ctx->desc->d2i_PUBKEY != NULL) + key = ctx->desc->d2i_PUBKEY(NULL, &derp, der_len); + else + key = ctx->desc->d2i_public_key(NULL, &derp, der_len); if (key == NULL && orig_selection != 0) goto next; } @@ -342,6 +346,10 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, &derp, der_len, libctx, NULL); } + /* + * As long as we have algos without a specific d2i__PUBKEY, + * this code must remain... + */ if (pkey == NULL && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { RESET_ERR_MARK(); @@ -449,6 +457,7 @@ static int der2key_export_object(void *vctx, # define dh_d2i_private_key NULL # define dh_d2i_public_key NULL # define dh_d2i_key_params (d2i_of_void *)d2i_DHparams +# define dh_d2i_PUBKEY (d2i_of_void *)ossl_d2i_DH_PUBKEY # define dh_free (free_key_fn *)DH_free # define dh_check NULL @@ -462,6 +471,7 @@ static void dh_adjust(void *key, struct der2key_ctx_st *ctx) # define dhx_d2i_private_key NULL # define dhx_d2i_public_key NULL # define dhx_d2i_key_params (d2i_of_void *)d2i_DHxparams +# define dhx_d2i_PUBKEY (d2i_of_void *)ossl_d2i_DHx_PUBKEY # define dhx_free (free_key_fn *)DH_free # define dhx_check NULL # define dhx_adjust dh_adjust @@ -475,6 +485,7 @@ static void dh_adjust(void *key, struct der2key_ctx_st *ctx) # define dsa_d2i_private_key (d2i_of_void *)d2i_DSAPrivateKey # define dsa_d2i_public_key (d2i_of_void *)d2i_DSAPublicKey # define dsa_d2i_key_params (d2i_of_void *)d2i_DSAparams +# define dsa_d2i_PUBKEY (d2i_of_void *)d2i_DSA_PUBKEY # define dsa_free (free_key_fn *)DSA_free # define dsa_check NULL @@ -492,6 +503,7 @@ static void dsa_adjust(void *key, struct der2key_ctx_st *ctx) # define ec_d2i_private_key (d2i_of_void *)d2i_ECPrivateKey # define ec_d2i_public_key NULL # define ec_d2i_key_params (d2i_of_void *)d2i_ECParameters +# define ec_d2i_PUBKEY (d2i_of_void *)d2i_EC_PUBKEY # define ec_free (free_key_fn *)EC_KEY_free static int ec_check(void *key, struct der2key_ctx_st *ctx) @@ -523,6 +535,7 @@ static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx) # define ed25519_d2i_private_key NULL # define ed25519_d2i_public_key NULL # define ed25519_d2i_key_params NULL +# define ed25519_d2i_PUBKEY (d2i_of_void *)ossl_d2i_ED25519_PUBKEY # define ed25519_free (free_key_fn *)ossl_ecx_key_free # define ed25519_check NULL # define ed25519_adjust ecx_key_adjust @@ -532,6 +545,7 @@ static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx) # define ed448_d2i_private_key NULL # define ed448_d2i_public_key NULL # define ed448_d2i_key_params NULL +# define ed448_d2i_PUBKEY (d2i_of_void *)ossl_d2i_ED448_PUBKEY # define ed448_free (free_key_fn *)ossl_ecx_key_free # define ed448_check NULL # define ed448_adjust ecx_key_adjust @@ -541,6 +555,7 @@ static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx) # define x25519_d2i_private_key NULL # define x25519_d2i_public_key NULL # define x25519_d2i_key_params NULL +# define x25519_d2i_PUBKEY (d2i_of_void *)ossl_d2i_X25519_PUBKEY # define x25519_free (free_key_fn *)ossl_ecx_key_free # define x25519_check NULL # define x25519_adjust ecx_key_adjust @@ -550,6 +565,7 @@ static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx) # define x448_d2i_private_key NULL # define x448_d2i_public_key NULL # define x448_d2i_key_params NULL +# define x448_d2i_PUBKEY (d2i_of_void *)ossl_d2i_X448_PUBKEY # define x448_free (free_key_fn *)ossl_ecx_key_free # define x448_check NULL # define x448_adjust ecx_key_adjust @@ -560,6 +576,7 @@ static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx) # define sm2_d2i_private_key (d2i_of_void *)d2i_ECPrivateKey # define sm2_d2i_public_key NULL # define sm2_d2i_key_params (d2i_of_void *)d2i_ECParameters +# define sm2_d2i_PUBKEY (d2i_of_void *)d2i_EC_PUBKEY # define sm2_free (free_key_fn *)EC_KEY_free # define sm2_check ec_check # define sm2_adjust ec_adjust @@ -573,6 +590,7 @@ static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx) #define rsa_d2i_private_key (d2i_of_void *)d2i_RSAPrivateKey #define rsa_d2i_public_key (d2i_of_void *)d2i_RSAPublicKey #define rsa_d2i_key_params NULL +#define rsa_d2i_PUBKEY (d2i_of_void *)d2i_RSA_PUBKEY #define rsa_free (free_key_fn *)RSA_free static int rsa_check(void *key, struct der2key_ctx_st *ctx) @@ -598,6 +616,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) #define rsapss_d2i_private_key (d2i_of_void *)d2i_RSAPrivateKey #define rsapss_d2i_public_key (d2i_of_void *)d2i_RSAPublicKey #define rsapss_d2i_key_params NULL +#define rsapss_d2i_PUBKEY (d2i_of_void *)d2i_RSA_PUBKEY #define rsapss_free (free_key_fn *)RSA_free #define rsapss_check rsa_check #define rsapss_adjust rsa_adjust @@ -615,6 +634,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) keytype##_d2i_public_key, \ NULL, \ NULL, \ + NULL, \ keytype##_check, \ keytype##_adjust, \ keytype##_free @@ -626,6 +646,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) keytype##_d2i_public_key, \ NULL, \ NULL, \ + NULL, \ keytype##_check, \ keytype##_adjust, \ keytype##_free @@ -637,6 +658,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) NULL, \ NULL, \ NULL, \ + NULL, \ keytype##_check, \ keytype##_adjust, \ keytype##_free @@ -648,6 +670,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) NULL, \ keytype##_d2i_key_params, \ NULL, \ + NULL, \ keytype##_check, \ keytype##_adjust, \ keytype##_free @@ -659,6 +682,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) keytype##_d2i_public_key, \ keytype##_d2i_key_params, \ NULL, \ + NULL, \ keytype##_check, \ keytype##_adjust, \ keytype##_free @@ -671,6 +695,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) NULL, \ keytype##_d2i_key_params, \ NULL, \ + NULL, \ keytype##_check, \ keytype##_adjust, \ keytype##_free @@ -681,6 +706,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) NULL, \ NULL, \ NULL, \ + NULL, \ keytype##_evp_extract, \ keytype##_check, \ keytype##_adjust, \ @@ -692,6 +718,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) NULL, \ NULL, \ NULL, \ + keytype##_d2i_PUBKEY, \ keytype##_evp_extract, \ keytype##_check, \ keytype##_adjust, \ @@ -704,6 +731,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) NULL, \ keytype##_d2i_key_params, \ NULL, \ + NULL, \ keytype##_check, \ keytype##_adjust, \ keytype##_free @@ -715,6 +743,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) NULL, \ keytype##_d2i_key_params, \ NULL, \ + NULL, \ keytype##_check, \ keytype##_adjust, \ keytype##_free @@ -726,6 +755,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) keytype##_d2i_public_key, \ keytype##_d2i_key_params, \ NULL, \ + NULL, \ keytype##_check, \ keytype##_adjust, \ keytype##_free @@ -738,6 +768,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) NULL, \ keytype##_d2i_key_params, \ NULL, \ + NULL, \ keytype##_check, \ keytype##_adjust, \ keytype##_free @@ -749,6 +780,7 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) keytype##_d2i_public_key, \ NULL, \ NULL, \ + NULL, \ keytype##_check, \ keytype##_adjust, \ keytype##_free