Skip to content

Commit

Permalink
Revert "Remove param_decode and param_encode EVP_PKEY hooks."
Browse files Browse the repository at this point in the history
This reverts part of  commit 32fdc51.
  • Loading branch information
samuel40791765 committed Sep 6, 2024
1 parent 3662fc1 commit 5790adb
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 21 deletions.
17 changes: 17 additions & 0 deletions crypto/evp_extra/p_dsa_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,21 @@ static int dsa_bits(const EVP_PKEY *pkey) {
return BN_num_bits(pkey->pkey.dsa->p);
}

static int dsa_param_decode(EVP_PKEY *pkey, const uint8_t **pder, long derlen) {
DSA *dsa;
dsa = d2i_DSAparams(NULL, pder, derlen);
if (dsa == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_DSA_LIB);
return 0;
}
EVP_PKEY_assign_DSA(pkey, dsa);
return 1;
}

static int dsa_param_encode(const EVP_PKEY *pkey, uint8_t **pder) {
return i2d_DSAparams(pkey->pkey.dsa, pder);
}

static int dsa_missing_parameters(const EVP_PKEY *pkey) {
DSA *dsa;
dsa = pkey->pkey.dsa;
Expand Down Expand Up @@ -281,6 +296,8 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
int_dsa_size,
dsa_bits,

dsa_param_decode,
dsa_param_encode,
dsa_missing_parameters,
dsa_copy_parameters,
dsa_cmp_parameters,
Expand Down
17 changes: 17 additions & 0 deletions crypto/evp_extra/p_ec_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,21 @@ static int ec_bits(const EVP_PKEY *pkey) {
return EC_GROUP_order_bits(group);
}

static int eckey_param_decode(EVP_PKEY *pkey, const uint8_t **pder,
long derlen) {
EC_KEY *eckey = d2i_ECParameters(NULL, pder, derlen);
if (eckey == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
return 0;
}
EVP_PKEY_assign_EC_KEY(pkey, eckey);
return 1;
}

static int eckey_param_encode(const EVP_PKEY *pkey, uint8_t **pder) {
return i2d_ECParameters(pkey->pkey.ec, pder);
}

static int ec_missing_parameters(const EVP_PKEY *pkey) {
return pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL;
}
Expand Down Expand Up @@ -274,6 +289,8 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
int_ec_size,
ec_bits,

eckey_param_decode,
eckey_param_encode,
ec_missing_parameters,
ec_copy_parameters,
ec_cmp_parameters,
Expand Down
2 changes: 2 additions & 0 deletions crypto/evp_extra/p_ed25519_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
NULL /* pkey_opaque */,
ed25519_size,
ed25519_bits,
NULL /* param_decode */,
NULL /* param_encode */,
NULL /* param_missing */,
NULL /* param_copy */,
NULL /* param_cmp */,
Expand Down
40 changes: 21 additions & 19 deletions crypto/evp_extra/p_hmac_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,27 +119,29 @@ static int hmac_get_key(const EVP_PKEY *pkey, uint8_t *priv, size_t *len) {

const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
EVP_PKEY_HMAC,
{0xff} /* placeholder oid */,
0 /* oid_len */,
{0xff}, // placeholder oid
0, // oid_len

"HMAC",
"OpenSSL HMAC method",

NULL /* pub_decode */,
NULL /* pub_encode */,
NULL /* pub_cmp */,
NULL /*priv_decode */,
NULL /* priv_encode */,
NULL /* priv_encode_v2 */,
hmac_set_key /* set_priv_raw */,
NULL /* set_pub_raw */,
hmac_get_key /* get_priv_raw */,
NULL /* get_pub_raw */,
NULL /* pkey_opaque */,
hmac_size /* pkey_size */,
NULL /* pkey_bits */,
NULL /* param_missing */,
NULL /* param_copy */,
NULL /* param_cmp */,
hmac_key_free /* pkey_free */
NULL, // pub_decode
NULL, // pub_encode
NULL, // pub_cmp
NULL, // priv_decode
NULL, // priv_encode
NULL, // priv_encode_v2
hmac_set_key, // set_priv_raw
NULL, // set_pub_raw
hmac_get_key, // get_priv_raw
NULL, // get_pub_raw
NULL, // pkey_opaque
hmac_size, // pkey_size
NULL, // pkey_bits
NULL, // param_decode
NULL, // param_encode
NULL, // param_missing
NULL, // param_copy
NULL, // param_cmp
hmac_key_free, // pkey_free
};
2 changes: 2 additions & 0 deletions crypto/evp_extra/p_kem_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ const EVP_PKEY_ASN1_METHOD kem_asn1_meth = {
NULL, // pkey_opaque
NULL, // kem_size
NULL, // kem_bits
NULL, // param_decode
NULL, // param_encode
NULL, // missing_parameters
NULL, // param_copy
kem_cmp_parameters,
Expand Down
4 changes: 2 additions & 2 deletions crypto/evp_extra/p_rsa_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
int_rsa_size,
rsa_bits,

0,0,0,
0,0,0,0,0,

int_rsa_free,
};
Expand Down Expand Up @@ -276,7 +276,7 @@ const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth = {
int_rsa_size,
rsa_bits,

0,0,0,
0,0,0,0,0,

int_rsa_free,
};
2 changes: 2 additions & 0 deletions crypto/evp_extra/p_x25519_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ const EVP_PKEY_ASN1_METHOD x25519_asn1_meth = {
NULL /* pkey_opaque */,
x25519_size,
x25519_bits,
NULL /* param_decode */,
NULL /* param_encode */,
NULL /* param_missing */,
NULL /* param_copy */,
NULL /* param_cmp */,
Expand Down
5 changes: 5 additions & 0 deletions crypto/fipsmodule/evp/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ struct evp_pkey_asn1_method_st {
int (*pkey_size)(const EVP_PKEY *pk);
int (*pkey_bits)(const EVP_PKEY *pk);

// TODO: Do we even need function pointers if only 3 types of `EVP_PKEY`s
// consume these? Considering if we can just pull the logic into the API
// instead of adding a function pointer for each `EVP_PKEY`.
int (*param_decode)(EVP_PKEY *pkey, const uint8_t **pder, long derlen);
int (*param_encode)(const EVP_PKEY *pkey, uint8_t **pder);
int (*param_missing)(const EVP_PKEY *pk);
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
Expand Down
8 changes: 8 additions & 0 deletions crypto/pem/pem_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
#include <openssl/x509.h>

#include "../internal.h"
#include "../fipsmodule/evp/internal.h"


#define MIN_LENGTH 4
Expand Down Expand Up @@ -146,6 +147,13 @@ static int check_pem(const char *nm, const char *name) {
!strcmp(nm, PEM_STRING_DSA);
}

// These correspond with the PEM strings that have "PARAMETERS".
if (!strcmp(name, PEM_STRING_PARAMETERS)) {
return !strcmp(nm, PEM_STRING_ECPARAMETERS) ||
!strcmp(nm, PEM_STRING_DSAPARAMS) ||
!strcmp(nm, PEM_STRING_DHPARAMS);
}

// Permit older strings

if (!strcmp(nm, PEM_STRING_X509_OLD) && !strcmp(name, PEM_STRING_X509)) {
Expand Down
61 changes: 61 additions & 0 deletions crypto/pem/pem_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include <openssl/pkcs8.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include "../fipsmodule/evp/internal.h"

EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
void *u) {
Expand Down Expand Up @@ -156,6 +157,66 @@ int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, (char *)kstr, klen, cb, u);
}

EVP_PKEY *PEM_read_bio_Parameters(BIO *bio, EVP_PKEY **pkey) {
char *nm = NULL;
unsigned char *data = NULL;
long len;
if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS, bio, 0,
NULL)) {
return NULL;
}
const unsigned char *p = data;

EVP_PKEY *ret = EVP_PKEY_new();
if (strcmp(nm, PEM_STRING_ECPARAMETERS) == 0 ||
!EVP_PKEY_set_type(ret, EVP_PKEY_EC)) {
goto err;
} else if (strcmp(nm, PEM_STRING_DSAPARAMS) == 0 ||
!EVP_PKEY_set_type(ret, EVP_PKEY_DSA)) {
// TODO: This should work, we only support serializing DSA?
goto err;
} else if (strcmp(nm, PEM_STRING_DHPARAMS) == 0 ||
!EVP_PKEY_set_type(ret, EVP_PKEY_DH)) {
// TODO: EVP_PKEY_DH ASN1 support is missing. Work on this once we have it.
goto err;
}

if (!ret->ameth->param_decode || !ret->ameth->param_decode(ret, &p, len)) {
EVP_PKEY_free(ret);
OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
goto err;
}


if (pkey != NULL) {
if (*pkey != NULL) {
EVP_PKEY_free(*pkey);
}
*pkey = ret;
}

OPENSSL_free(nm);
OPENSSL_free(data);
return ret;

err:
EVP_PKEY_free(ret);
OPENSSL_free(nm);
OPENSSL_free(data);
return NULL;
}

int PEM_write_bio_Parameters(BIO *bio, EVP_PKEY *pkey) {
char pem_str[80];
if (!pkey->ameth || !pkey->ameth->param_encode) {
return 0;
}

BIO_snprintf(pem_str, 80, "%s PARAMETERS", pkey->ameth->pem_str);
return PEM_ASN1_write_bio((i2d_of_void *)pkey->ameth->param_encode, pem_str,
bio, pkey, NULL, NULL, 0, 0, NULL);
}

EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
void *u) {
BIO *b = BIO_new_fp(fp, BIO_NOCLOSE);
Expand Down
4 changes: 4 additions & 0 deletions include/openssl/pem.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ extern "C" {
#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
#define PEM_STRING_PARAMETERS "PARAMETERS"
#define PEM_STRING_CMS "CMS"

// enc_type is one off
Expand Down Expand Up @@ -473,6 +474,9 @@ OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x,
int klen, pem_password_cb *cd,
void *u);

OPENSSL_EXPORT EVP_PKEY *PEM_read_bio_Parameters(BIO *bio, EVP_PKEY **pkey);
OPENSSL_EXPORT int PEM_write_bio_Parameters(BIO *bio, EVP_PKEY *pkey);

// PEM_read_bio_ECPKParameters deserializes the PEM file written in |bio|
// according to |ECPKParameters| in RFC 3279. It returns the |EC_GROUP|
// corresponding to deserialized output and also writes it to |out_group|. Only
Expand Down

0 comments on commit 5790adb

Please sign in to comment.