From 6f81892e6ba0bf0840d12e27f695817230dd42c1 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 20 Mar 2006 17:56:05 +0000 Subject: [PATCH] Transfer parameter handling and key comparison to algorithm methods. --- crypto/asn1/ameth_lib.c | 10 +- crypto/asn1/asn1.h | 22 +++- crypto/asn1/d2i_pr.c | 1 + crypto/dh/Makefile | 6 +- crypto/dsa/dsa_ameth.c | 83 +++++++++++++- crypto/ec/ec_ameth.c | 92 ++++++++++++++- crypto/evp/evp.h | 1 + crypto/evp/p_lib.c | 244 ++++++---------------------------------- crypto/rsa/rsa_ameth.c | 38 ++++++- 9 files changed, 271 insertions(+), 226 deletions(-) diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c index ddb6333913..f2c4166f1d 100644 --- a/crypto/asn1/ameth_lib.c +++ b/crypto/asn1/ameth_lib.c @@ -64,6 +64,7 @@ extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[]; extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth; /* Keep this sorted in type order !! */ @@ -71,6 +72,7 @@ const EVP_PKEY_ASN1_METHOD *standard_methods[] = { &rsa_asn1_meths[0], &rsa_asn1_meths[1], + &dh_asn1_meth, &dsa_asn1_meths[0], &dsa_asn1_meths[1], &dsa_asn1_meths[2], @@ -86,14 +88,16 @@ void main() for (i = 0; i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *); i++) - fprintf(stderr, "Number %d id=%d\n", i, - standard_methods[i]->pkey_id); + fprintf(stderr, "Number %d id=%d (%s)\n", i, + standard_methods[i]->pkey_id, + OBJ_nid2sn(standard_methods[i]->pkey_id)); } #endif static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a, const EVP_PKEY_ASN1_METHOD * const *b) { +/*fprintf(stderr, "Comparing %d with %d\n", (*a)->pkey_id, (*b)->pkey_id);*/ return ((*a)->pkey_id - (*b)->pkey_id); } @@ -106,6 +110,8 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_ASN1_find(int type) sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *), sizeof(EVP_PKEY_ASN1_METHOD *), (int (*)(const void *, const void *))ameth_cmp); + if (!ret || !*ret) + return NULL; if ((*ret)->pkey_flags & ASN1_PKEY_ALIAS) return EVP_PKEY_ASN1_find((*ret)->pkey_base_id); return *ret; diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h index 32653eb1f0..f0756b10cd 100644 --- a/crypto/asn1/asn1.h +++ b/crypto/asn1/asn1.h @@ -291,13 +291,29 @@ struct evp_pkey_asn1_method_st int pkey_id; int pkey_base_id; unsigned long pkey_flags; + int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub); - int (*pub_encode)(X509_PUBKEY *pub, EVP_PKEY *pk); - int (*pub_print)(BIO *out, EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); + int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk); + int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf); - int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pk); + int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk); int (*priv_print)(BIO *out, EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); + + int (*pkey_size)(const EVP_PKEY *pk); + int (*pkey_bits)(const EVP_PKEY *pk); + + int (*param_decode)(const EVP_PKEY *pk, X509_PUBKEY *pub); + int (*param_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk); + 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); + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + void (*pkey_free)(EVP_PKEY *pkey); void (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2); } /* EVP_PKEY_ASN1_METHOD */; diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c index 207ccda5ac..512d11d6f6 100644 --- a/crypto/asn1/d2i_pr.c +++ b/crypto/asn1/d2i_pr.c @@ -89,6 +89,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, ret->save_type=type; ret->type=EVP_PKEY_type(type); + ret->ameth = EVP_PKEY_ASN1_find(type); switch (ret->type) { #ifndef OPENSSL_NO_RSA diff --git a/crypto/dh/Makefile b/crypto/dh/Makefile index d368e33b4c..75bd7056f9 100644 --- a/crypto/dh/Makefile +++ b/crypto/dh/Makefile @@ -17,8 +17,10 @@ TEST= dhtest.c APPS= LIB=$(TOP)/libcrypto.a -LIBSRC= dh_asn1.c dh_gen.c dh_key.c dh_lib.c dh_check.c dh_err.c dh_depr.c -LIBOBJ= dh_asn1.o dh_gen.o dh_key.o dh_lib.o dh_check.o dh_err.o dh_depr.o +LIBSRC= dh_asn1.c dh_gen.c dh_key.c dh_lib.c dh_check.c dh_err.c dh_depr.c \ + dh_ameth.c +LIBOBJ= dh_asn1.o dh_gen.o dh_key.o dh_lib.o dh_check.o dh_err.o dh_depr.o \ + dh_ameth.o SRC= $(LIBSRC) diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index 8763eb93bc..4940bfa0b9 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -119,7 +119,7 @@ static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) } -static int dsa_pub_encode(X509_PUBKEY *pk, EVP_PKEY *pkey) +static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { DSA *dsa; void *pval; @@ -168,6 +168,14 @@ static int dsa_pub_encode(X509_PUBKEY *pk, EVP_PKEY *pkey) return 0; } +static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) + { + if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0) + return 0; + else + return 1; + } + /* In PKCS#8 DSA: you just get a private key integer and parameters in the * AlgorithmIdentifier the pubkey must be recalculated. */ @@ -278,7 +286,7 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) return 0; } -static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) +static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { ASN1_STRING *params = NULL; ASN1_INTEGER *prkey = NULL; @@ -330,6 +338,64 @@ err: return 0; } +static int int_dsa_size(const EVP_PKEY *pkey) + { + return(DSA_size(pkey->pkey.dsa)); + } + +static int dsa_bits(const EVP_PKEY *pkey) + { + return BN_num_bits(pkey->pkey.dsa->p); + } + +static int dsa_missing_parameters(const EVP_PKEY *pkey) + { + DSA *dsa; + dsa=pkey->pkey.dsa; + if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL)) + return 1; + return 0; + } + +static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) + { + BIGNUM *a; + + if ((a=BN_dup(from->pkey.dsa->p)) == NULL) + return 0; + if (to->pkey.dsa->p != NULL) + BN_free(to->pkey.dsa->p); + to->pkey.dsa->p=a; + + if ((a=BN_dup(from->pkey.dsa->q)) == NULL) + return 0; + if (to->pkey.dsa->q != NULL) + BN_free(to->pkey.dsa->q); + to->pkey.dsa->q=a; + + if ((a=BN_dup(from->pkey.dsa->g)) == NULL) + return 0; + if (to->pkey.dsa->g != NULL) + BN_free(to->pkey.dsa->g); + to->pkey.dsa->g=a; + return 1; + } + +static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) + { + if ( BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) || + BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) || + BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g)) + return 0; + else + return 1; + } + +static void int_dsa_free(EVP_PKEY *pkey) + { + DSA_free(pkey->pkey.dsa); + } + /* NB these are sorted in pkey_id order, lowest first */ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = @@ -363,13 +429,26 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = EVP_PKEY_DSA, EVP_PKEY_DSA, 0, + dsa_pub_decode, dsa_pub_encode, + dsa_pub_cmp, 0, + dsa_priv_decode, dsa_priv_encode, 0, + + int_dsa_size, + dsa_bits, + + 0,0, + dsa_missing_parameters, + dsa_copy_parameters, + dsa_cmp_parameters, 0, + + int_dsa_free, 0 } }; diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index 11aa432d33..e6a0d20faa 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -95,7 +95,7 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) return 1; } -static int eckey_pub_encode(X509_PUBKEY *pk, EVP_PKEY *pkey) +static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { EC_KEY *ec_key = pkey->pkey.ec; void *pval = NULL; @@ -218,6 +218,20 @@ static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) return 0; } +static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) + { + int r; + const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); + const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), + *pb = EC_KEY_get0_public_key(b->pkey.ec); + r = EC_POINT_cmp(group, pa, pb, NULL); + if (r == 0) + return 1; + if (r == 1) + return 0; + return -2; + } + static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { const unsigned char *p = NULL; @@ -290,7 +304,7 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) return 0; } -static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) +static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { EC_KEY *ec_key; unsigned char *ep, *p; @@ -344,17 +358,91 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) return 1; } +static int int_ec_size(const EVP_PKEY *pkey) + { + return ECDSA_size(pkey->pkey.ec); + } + +static int ec_bits(const EVP_PKEY *pkey) + { + BIGNUM *order = BN_new(); + const EC_GROUP *group; + int ret; + + if (!order) + { + ERR_clear_error(); + return 0; + } + group = EC_KEY_get0_group(pkey->pkey.ec); + if (!EC_GROUP_get_order(group, order, NULL)) + { + ERR_clear_error(); + return 0; + } + + ret = BN_num_bits(order); + BN_free(order); + return ret; + } + +static int ec_missing_parameters(const EVP_PKEY *pkey) + { + if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) + return 1; + return 0; + } + +int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) + { + EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); + if (group == NULL) + return 0; + if (EC_KEY_set_group(to->pkey.ec, group) == 0) + return 0; + EC_GROUP_free(group); + return 1; + } + +int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) + { + const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), + *group_b = EC_KEY_get0_group(b->pkey.ec); + if (EC_GROUP_cmp(group_a, group_b, NULL)) + return 0; + else + return 1; + } + +static void int_ec_free(EVP_PKEY *pkey) + { + EC_KEY_free(pkey->pkey.ec); + } + EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { EVP_PKEY_EC, 0, 0, + eckey_pub_decode, eckey_pub_encode, + eckey_pub_cmp, 0, + eckey_priv_decode, eckey_priv_encode, 0, + + int_ec_size, + ec_bits, + + 0,0, + ec_missing_parameters, + ec_copy_parameters, + ec_cmp_parameters, 0, + + int_ec_free, 0 }; diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index a13acaf308..be8762d392 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -128,6 +128,7 @@ struct evp_pkey_st int type; int save_type; int references; + const EVP_PKEY_ASN1_METHOD *ameth; union { char *ptr; #ifndef OPENSSL_NO_RSA diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 22155ecf62..f22a3fe6bc 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -78,62 +78,16 @@ static void EVP_PKEY_free_it(EVP_PKEY *x); int EVP_PKEY_bits(EVP_PKEY *pkey) { - if (0) - return 0; -#ifndef OPENSSL_NO_RSA - else if (pkey->type == EVP_PKEY_RSA) - return(BN_num_bits(pkey->pkey.rsa->n)); -#endif -#ifndef OPENSSL_NO_DSA - else if (pkey->type == EVP_PKEY_DSA) - return(BN_num_bits(pkey->pkey.dsa->p)); -#endif -#ifndef OPENSSL_NO_EC - else if (pkey->type == EVP_PKEY_EC) - { - BIGNUM *order = BN_new(); - const EC_GROUP *group; - int ret; - - if (!order) - { - ERR_clear_error(); - return 0; - } - group = EC_KEY_get0_group(pkey->pkey.ec); - if (!EC_GROUP_get_order(group, order, NULL)) - { - ERR_clear_error(); - return 0; - } - - ret = BN_num_bits(order); - BN_free(order); - return ret; - } -#endif - return(0); + if (pkey && pkey->ameth && pkey->ameth->pkey_bits) + return pkey->ameth->pkey_bits(pkey); + return 0; } int EVP_PKEY_size(EVP_PKEY *pkey) { - if (pkey == NULL) - return(0); -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) - return(RSA_size(pkey->pkey.rsa)); - else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) - return(DSA_size(pkey->pkey.dsa)); -#endif -#ifndef OPENSSL_NO_ECDSA - if (pkey->type == EVP_PKEY_EC) - return(ECDSA_size(pkey->pkey.ec)); -#endif - - return(0); + if (pkey && pkey->ameth && pkey->ameth->pkey_size) + return pkey->ameth->pkey_size(pkey); + return 0; } int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) @@ -174,88 +128,26 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS); goto err; } -#ifndef OPENSSL_NO_DSA - if (to->type == EVP_PKEY_DSA) - { - BIGNUM *a; - - if ((a=BN_dup(from->pkey.dsa->p)) == NULL) goto err; - if (to->pkey.dsa->p != NULL) BN_free(to->pkey.dsa->p); - to->pkey.dsa->p=a; - - if ((a=BN_dup(from->pkey.dsa->q)) == NULL) goto err; - if (to->pkey.dsa->q != NULL) BN_free(to->pkey.dsa->q); - to->pkey.dsa->q=a; - - if ((a=BN_dup(from->pkey.dsa->g)) == NULL) goto err; - if (to->pkey.dsa->g != NULL) BN_free(to->pkey.dsa->g); - to->pkey.dsa->g=a; - } -#endif -#ifndef OPENSSL_NO_EC - if (to->type == EVP_PKEY_EC) - { - EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); - if (group == NULL) - goto err; - if (EC_KEY_set_group(to->pkey.ec, group) == 0) - goto err; - EC_GROUP_free(group); - } -#endif - return(1); + if (from->ameth && from->ameth->param_copy) + return from->ameth->param_copy(to, from); err: - return(0); + return 0; } int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) { -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) - { - DSA *dsa; - - dsa=pkey->pkey.dsa; - if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL)) - return(1); - } -#endif -#ifndef OPENSSL_NO_EC - if (pkey->type == EVP_PKEY_EC) - { - if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) - return(1); - } -#endif - - return(0); + if (pkey->ameth && pkey->ameth->param_missing) + return pkey->ameth->param_missing(pkey); + return 0; } int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { -#ifndef OPENSSL_NO_DSA - if ((a->type == EVP_PKEY_DSA) && (b->type == EVP_PKEY_DSA)) - { - if ( BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) || - BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) || - BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g)) - return(0); - else - return(1); - } -#endif -#ifndef OPENSSL_NO_EC - if (a->type == EVP_PKEY_EC && b->type == EVP_PKEY_EC) - { - const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), - *group_b = EC_KEY_get0_group(b->pkey.ec); - if (EC_GROUP_cmp(group_a, group_b, NULL)) - return 0; - else - return 1; - } -#endif - return(-1); + if (a->type != b->type) + return -1; + if (a->ameth && a->ameth->param_cmp) + return a->ameth->param_cmp(a, b); + return -1; } int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) @@ -266,48 +158,10 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) if (EVP_PKEY_cmp_parameters(a, b) == 0) return 0; - switch (a->type) - { -#ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0 - || BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0) - return 0; - break; -#endif -#ifndef OPENSSL_NO_DSA - case EVP_PKEY_DSA: - if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0) - return 0; - break; -#endif -#ifndef OPENSSL_NO_EC - case EVP_PKEY_EC: - { - int r; - const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); - const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), - *pb = EC_KEY_get0_public_key(b->pkey.ec); - r = EC_POINT_cmp(group, pa, pb, NULL); - if (r != 0) - { - if (r == 1) - return 0; - else - return -2; - } - } - break; -#endif -#ifndef OPENSSL_NO_DH - case EVP_PKEY_DH: - return -2; -#endif - default: - return -2; - } + if (a->ameth && a->ameth->pub_cmp) + return a->ameth->pub_cmp(a, b); - return 1; + return -2; } EVP_PKEY *EVP_PKEY_new(void) @@ -322,6 +176,7 @@ EVP_PKEY *EVP_PKEY_new(void) } ret->type=EVP_PKEY_NONE; ret->references=1; + ret->ameth=NULL; ret->pkey.ptr=NULL; ret->attributes=NULL; ret->save_parameters=1; @@ -330,10 +185,13 @@ EVP_PKEY *EVP_PKEY_new(void) int EVP_PKEY_assign(EVP_PKEY *pkey, int type, char *key) { + const EVP_PKEY_ASN1_METHOD *ameth; if (pkey == NULL) return(0); if (pkey->pkey.ptr != NULL) EVP_PKEY_free_it(pkey); - pkey->type=EVP_PKEY_type(type); + ameth = EVP_PKEY_ASN1_find(type); + pkey->ameth = ameth; + pkey->type = ameth->pkey_id; pkey->save_type=type; pkey->pkey.ptr=key; return(key != NULL); @@ -425,24 +283,11 @@ DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) int EVP_PKEY_type(int type) { - switch (type) - { - case EVP_PKEY_RSA: - case EVP_PKEY_RSA2: - return(EVP_PKEY_RSA); - case EVP_PKEY_DSA: - case EVP_PKEY_DSA1: - case EVP_PKEY_DSA2: - case EVP_PKEY_DSA3: - case EVP_PKEY_DSA4: - return(EVP_PKEY_DSA); - case EVP_PKEY_DH: - return(EVP_PKEY_DH); - case EVP_PKEY_EC: - return(EVP_PKEY_EC); - default: - return(NID_undef); - } + const EVP_PKEY_ASN1_METHOD *ameth; + ameth = EVP_PKEY_ASN1_find(type); + if (ameth) + return ameth->pkey_id; + return NID_undef; } void EVP_PKEY_free(EVP_PKEY *x) @@ -471,32 +316,7 @@ void EVP_PKEY_free(EVP_PKEY *x) static void EVP_PKEY_free_it(EVP_PKEY *x) { - switch (x->type) - { -#ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - case EVP_PKEY_RSA2: - RSA_free(x->pkey.rsa); - break; -#endif -#ifndef OPENSSL_NO_DSA - case EVP_PKEY_DSA: - case EVP_PKEY_DSA2: - case EVP_PKEY_DSA3: - case EVP_PKEY_DSA4: - DSA_free(x->pkey.dsa); - break; -#endif -#ifndef OPENSSL_NO_EC - case EVP_PKEY_EC: - EC_KEY_free(x->pkey.ec); - break; -#endif -#ifndef OPENSSL_NO_DH - case EVP_PKEY_DH: - DH_free(x->pkey.dh); - break; -#endif - } + if (x->ameth && x->ameth->pkey_free) + x->ameth->pkey_free(x); } diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 96e537571c..370e3d28c7 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -61,7 +61,7 @@ #include #include -static int rsa_pub_encode(X509_PUBKEY *pk, EVP_PKEY *pkey) +static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { unsigned char *penc = NULL; int penclen; @@ -92,6 +92,14 @@ static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) return 1; } +static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) + { + if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0 + || BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0) + return 0; + return 1; + } + static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { const unsigned char *p; @@ -108,7 +116,7 @@ static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) return 1; } -static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) +static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { unsigned char *rk = NULL; int rklen; @@ -130,19 +138,43 @@ static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) return 1; } +static int int_rsa_size(const EVP_PKEY *pkey) + { + return RSA_size(pkey->pkey.rsa); + } + +static int rsa_bits(const EVP_PKEY *pkey) + { + return BN_num_bits(pkey->pkey.rsa->n); + } + +static void int_rsa_free(EVP_PKEY *pkey) + { + RSA_free(pkey->pkey.rsa); + } + const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = { { EVP_PKEY_RSA, EVP_PKEY_RSA, 0, + rsa_pub_decode, rsa_pub_encode, + rsa_pub_cmp, 0, + rsa_priv_decode, rsa_priv_encode, 0, - 0, + + int_rsa_size, + rsa_bits, + + 0,0,0,0,0,0, + + int_rsa_free, 0 }, -- 2.34.1