mirror of
https://github.com/openssl/openssl.git
synced 2025-02-17 14:32:04 +08:00
Add support getting raw private/public keys
Only applies to algorithms that support it. Both raw private and public keys can be obtained for X25519, Ed25519, X448, Ed448. Raw private keys only can be obtained for HMAC, Poly1305 and SipHash Fixes #6259 Reviewed-by: Rich Salz <rsalz@openssl.org> Reviewed-by: Tim Hudson <tjh@openssl.org> (Merged from https://github.com/openssl/openssl/pull/6394)
This commit is contained in:
parent
c0a58e034d
commit
0d124b0a51
@ -354,6 +354,47 @@ static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
|
||||
KEY_OP_PUBLIC);
|
||||
}
|
||||
|
||||
static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
size_t *len)
|
||||
{
|
||||
const ECX_KEY *key = pkey->pkey.ecx;
|
||||
|
||||
if (priv == NULL) {
|
||||
*len = KEYLENID(pkey->ameth->pkey_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (key == NULL
|
||||
|| key->privkey == NULL
|
||||
|| *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
|
||||
return 0;
|
||||
|
||||
*len = KEYLENID(pkey->ameth->pkey_id);
|
||||
memcpy(priv, key->privkey, *len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
|
||||
size_t *len)
|
||||
{
|
||||
const ECX_KEY *key = pkey->pkey.ecx;
|
||||
|
||||
if (pub == NULL) {
|
||||
*len = KEYLENID(pkey->ameth->pkey_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (key == NULL
|
||||
|| *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
|
||||
return 0;
|
||||
|
||||
*len = KEYLENID(pkey->ameth->pkey_id);
|
||||
memcpy(pub, key->pubkey, *len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
|
||||
EVP_PKEY_X25519,
|
||||
EVP_PKEY_X25519,
|
||||
@ -393,6 +434,8 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
|
||||
|
||||
ecx_set_priv_key,
|
||||
ecx_set_pub_key,
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
};
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
|
||||
@ -434,6 +477,8 @@ const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
|
||||
|
||||
ecx_set_priv_key,
|
||||
ecx_set_pub_key,
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
};
|
||||
|
||||
static int ecd_size25519(const EVP_PKEY *pkey)
|
||||
@ -547,6 +592,8 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
|
||||
|
||||
ecx_set_priv_key,
|
||||
ecx_set_pub_key,
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
};
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
|
||||
@ -587,6 +634,8 @@ const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
|
||||
|
||||
ecx_set_priv_key,
|
||||
ecx_set_pub_key,
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
};
|
||||
|
||||
static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
|
@ -757,6 +757,8 @@ EVP_F_EVP_PKEY_GET0_HMAC:183:EVP_PKEY_get0_hmac
|
||||
EVP_F_EVP_PKEY_GET0_POLY1305:184:EVP_PKEY_get0_poly1305
|
||||
EVP_F_EVP_PKEY_GET0_RSA:121:EVP_PKEY_get0_RSA
|
||||
EVP_F_EVP_PKEY_GET0_SIPHASH:172:EVP_PKEY_get0_siphash
|
||||
EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY:202:EVP_PKEY_get_raw_private_key
|
||||
EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY:203:EVP_PKEY_get_raw_public_key
|
||||
EVP_F_EVP_PKEY_KEYGEN:146:EVP_PKEY_keygen
|
||||
EVP_F_EVP_PKEY_KEYGEN_INIT:147:EVP_PKEY_keygen_init
|
||||
EVP_F_EVP_PKEY_METH_ADD0:194:EVP_PKEY_meth_add0
|
||||
@ -2199,6 +2201,7 @@ EVP_R_EXPECTING_A_EC_KEY:142:expecting a ec key
|
||||
EVP_R_EXPECTING_A_POLY1305_KEY:164:expecting a poly1305 key
|
||||
EVP_R_EXPECTING_A_SIPHASH_KEY:175:expecting a siphash key
|
||||
EVP_R_FIPS_MODE_NOT_SUPPORTED:167:fips mode not supported
|
||||
EVP_R_GET_RAW_KEY_FAILED:182:get raw key failed
|
||||
EVP_R_ILLEGAL_SCRYPT_PARAMETERS:171:illegal scrypt parameters
|
||||
EVP_R_INITIALIZATION_ERROR:134:initialization error
|
||||
EVP_R_INPUT_NOT_INITIALIZED:111:input not initialized
|
||||
|
@ -93,6 +93,10 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_RSA, 0), "EVP_PKEY_get0_RSA"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_SIPHASH, 0),
|
||||
"EVP_PKEY_get0_siphash"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, 0),
|
||||
"EVP_PKEY_get_raw_private_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, 0),
|
||||
"EVP_PKEY_get_raw_public_key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN, 0), "EVP_PKEY_keygen"},
|
||||
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN_INIT, 0),
|
||||
"EVP_PKEY_keygen_init"},
|
||||
@ -185,6 +189,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
"expecting a siphash key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FIPS_MODE_NOT_SUPPORTED),
|
||||
"fips mode not supported"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GET_RAW_KEY_FAILED), "get raw key failed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ILLEGAL_SCRYPT_PARAMETERS),
|
||||
"illegal scrypt parameters"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INITIALIZATION_ERROR),
|
||||
|
@ -280,6 +280,40 @@ EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
size_t *len)
|
||||
{
|
||||
if (pkey->ameth->get_priv_key == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pkey->ameth->get_priv_key(pkey, priv, len)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, EVP_R_GET_RAW_KEY_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
|
||||
size_t *len)
|
||||
{
|
||||
if (pkey->ameth->get_pub_key == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pkey->ameth->get_pub_key(pkey, pub, len)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, EVP_R_GET_RAW_KEY_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
size_t len, const EVP_CIPHER *cipher)
|
||||
{
|
||||
|
@ -72,6 +72,25 @@ static int hmac_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int hmac_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
size_t *len)
|
||||
{
|
||||
ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
|
||||
|
||||
if (priv == NULL) {
|
||||
*len = ASN1_STRING_length(os);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (os == NULL || *len < (size_t)ASN1_STRING_length(os))
|
||||
return 0;
|
||||
|
||||
*len = ASN1_STRING_length(os);
|
||||
memcpy(priv, ASN1_STRING_get0_data(os), *len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
|
||||
EVP_PKEY_HMAC,
|
||||
EVP_PKEY_HMAC,
|
||||
@ -103,4 +122,6 @@ const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
|
||||
|
||||
hmac_set_priv_key,
|
||||
NULL,
|
||||
hmac_get_priv_key,
|
||||
NULL,
|
||||
};
|
||||
|
@ -61,6 +61,8 @@ struct evp_pkey_asn1_method_st {
|
||||
/* Get/set raw private/public key data */
|
||||
int (*set_priv_key) (EVP_PKEY *pk, const unsigned char *priv, size_t len);
|
||||
int (*set_pub_key) (EVP_PKEY *pk, const unsigned char *pub, size_t len);
|
||||
int (*get_priv_key) (const EVP_PKEY *pk, unsigned char *priv, size_t *len);
|
||||
int (*get_pub_key) (const EVP_PKEY *pk, unsigned char *pub, size_t *len);
|
||||
} /* EVP_PKEY_ASN1_METHOD */ ;
|
||||
|
||||
DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD)
|
||||
|
@ -67,6 +67,25 @@ static int poly1305_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int poly1305_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
size_t *len)
|
||||
{
|
||||
ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
|
||||
|
||||
if (priv == NULL) {
|
||||
*len = POLY1305_KEY_SIZE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (os == NULL || *len < POLY1305_KEY_SIZE)
|
||||
return 0;
|
||||
|
||||
memcpy(priv, ASN1_STRING_get0_data(os), ASN1_STRING_length(os));
|
||||
*len = POLY1305_KEY_SIZE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD poly1305_asn1_meth = {
|
||||
EVP_PKEY_POLY1305,
|
||||
EVP_PKEY_POLY1305,
|
||||
@ -98,4 +117,6 @@ const EVP_PKEY_ASN1_METHOD poly1305_asn1_meth = {
|
||||
|
||||
poly1305_set_priv_key,
|
||||
NULL,
|
||||
poly1305_get_priv_key,
|
||||
NULL,
|
||||
};
|
||||
|
@ -68,6 +68,25 @@ static int siphash_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int siphash_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
size_t *len)
|
||||
{
|
||||
ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
|
||||
|
||||
if (priv == NULL) {
|
||||
*len = SIPHASH_KEY_SIZE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (os == NULL || *len < SIPHASH_KEY_SIZE)
|
||||
return 0;
|
||||
|
||||
memcpy(priv, ASN1_STRING_get0_data(os), ASN1_STRING_length(os));
|
||||
*len = SIPHASH_KEY_SIZE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD siphash_asn1_meth = {
|
||||
EVP_PKEY_SIPHASH,
|
||||
EVP_PKEY_SIPHASH,
|
||||
@ -99,4 +118,6 @@ const EVP_PKEY_ASN1_METHOD siphash_asn1_meth = {
|
||||
|
||||
siphash_set_priv_key,
|
||||
NULL,
|
||||
siphash_get_priv_key,
|
||||
NULL,
|
||||
};
|
||||
|
@ -1352,6 +1352,11 @@ EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
|
||||
EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
|
||||
const unsigned char *pub,
|
||||
size_t len);
|
||||
int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
size_t *len);
|
||||
int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
|
||||
size_t *len);
|
||||
|
||||
EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
size_t len, const EVP_CIPHER *cipher);
|
||||
|
||||
|
@ -79,6 +79,8 @@ int ERR_load_EVP_strings(void);
|
||||
# define EVP_F_EVP_PKEY_GET0_POLY1305 184
|
||||
# define EVP_F_EVP_PKEY_GET0_RSA 121
|
||||
# define EVP_F_EVP_PKEY_GET0_SIPHASH 172
|
||||
# define EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY 202
|
||||
# define EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY 203
|
||||
# define EVP_F_EVP_PKEY_KEYGEN 146
|
||||
# define EVP_F_EVP_PKEY_KEYGEN_INIT 147
|
||||
# define EVP_F_EVP_PKEY_METH_ADD0 194
|
||||
@ -139,6 +141,7 @@ int ERR_load_EVP_strings(void);
|
||||
# define EVP_R_EXPECTING_A_POLY1305_KEY 164
|
||||
# define EVP_R_EXPECTING_A_SIPHASH_KEY 175
|
||||
# define EVP_R_FIPS_MODE_NOT_SUPPORTED 167
|
||||
# define EVP_R_GET_RAW_KEY_FAILED 182
|
||||
# define EVP_R_ILLEGAL_SCRYPT_PARAMETERS 171
|
||||
# define EVP_R_INITIALIZATION_ERROR 134
|
||||
# define EVP_R_INPUT_NOT_INITIALIZED 111
|
||||
|
@ -4563,3 +4563,5 @@ X509_OBJECT_set1_X509 4514 1_1_0i EXIST::FUNCTION:
|
||||
X509_LOOKUP_meth_get_get_by_issuer_serial 4515 1_1_0i EXIST::FUNCTION:
|
||||
X509_LOOKUP_meth_set_init 4516 1_1_0i EXIST::FUNCTION:
|
||||
X509_OBJECT_set1_X509_CRL 4517 1_1_0i EXIST::FUNCTION:
|
||||
EVP_PKEY_get_raw_public_key 4518 1_1_1 EXIST::FUNCTION:
|
||||
EVP_PKEY_get_raw_private_key 4519 1_1_1 EXIST::FUNCTION:
|
||||
|
Loading…
Reference in New Issue
Block a user