X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fevp%2Fp_lib.c;h=42a8be1bb8afd6c4bc94d9936309e92abb133bdc;hp=1a1e61a64e00425a6f6f83cb32b6dbb0ff4f8659;hb=2514fa79acba998c2a8d4e5a8288a5b3ae990377;hpb=732a40e107f056a6678602ab869f2ba9230e0d24 diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 1a1e61a64e..42a8be1bb8 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -74,6 +74,10 @@ #include #endif +#ifndef OPENSSL_NO_ENGINE +#include +#endif + #include "asn1_locl.h" static void EVP_PKEY_free_it(EVP_PKEY *x); @@ -85,6 +89,15 @@ int EVP_PKEY_bits(EVP_PKEY *pkey) return 0; } +int EVP_PKEY_security_bits(const EVP_PKEY *pkey) + { + if (pkey == NULL) + return 0; + if (!pkey->ameth || !pkey->ameth->pkey_security_bits) + return -2; + return pkey->ameth->pkey_security_bits(pkey); + } + int EVP_PKEY_size(EVP_PKEY *pkey) { if (pkey && pkey->ameth && pkey->ameth->pkey_size) @@ -149,7 +162,7 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) return -1; if (a->ameth && a->ameth->param_cmp) return a->ameth->param_cmp(a, b); - return -1; + return -2; } int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) @@ -157,11 +170,20 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) if (a->type != b->type) return -1; - if (EVP_PKEY_cmp_parameters(a, b) == 0) - return 0; - - if (a->ameth && a->ameth->pub_cmp) - return a->ameth->pub_cmp(a, b); + if (a->ameth) + { + int ret; + /* Compare parameters if the algorithm has them */ + if (a->ameth->param_cmp) + { + ret = a->ameth->param_cmp(a, b); + if (ret <= 0) + return ret; + } + + if (a->ameth->pub_cmp) + return a->ameth->pub_cmp(a, b); + } return -2; } @@ -177,26 +199,82 @@ EVP_PKEY *EVP_PKEY_new(void) return(NULL); } ret->type=EVP_PKEY_NONE; + ret->save_type=EVP_PKEY_NONE; ret->references=1; ret->ameth=NULL; + ret->engine=NULL; ret->pkey.ptr=NULL; ret->attributes=NULL; ret->save_parameters=1; return(ret); } -int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) +/* Setup a public key ASN1 method and ENGINE from a NID or a string. + * If pkey is NULL just return 1 or 0 if the algorithm exists. + */ + +static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len) { const EVP_PKEY_ASN1_METHOD *ameth; - if (pkey == NULL) return(0); - if (pkey->pkey.ptr != NULL) - EVP_PKEY_free_it(pkey); - ameth = EVP_PKEY_asn1_find(type); - pkey->ameth = ameth; - pkey->type = ameth->pkey_id; - pkey->save_type=type; + ENGINE *e = NULL; + if (pkey) + { + if (pkey->pkey.ptr) + EVP_PKEY_free_it(pkey); + /* If key type matches and a method exists then this + * lookup has succeeded once so just indicate success. + */ + if ((type == pkey->save_type) && pkey->ameth) + return 1; +#ifndef OPENSSL_NO_ENGINE + /* If we have an ENGINE release it */ + if (pkey->engine) + { + ENGINE_finish(pkey->engine); + pkey->engine = NULL; + } +#endif + } + if (str) + ameth = EVP_PKEY_asn1_find_str(&e, str, len); + else + ameth = EVP_PKEY_asn1_find(&e, type); +#ifndef OPENSSL_NO_ENGINE + if (!pkey && e) + ENGINE_finish(e); +#endif + if (!ameth) + { + EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + if (pkey) + { + pkey->ameth = ameth; + pkey->engine = e; + + pkey->type = pkey->ameth->pkey_id; + pkey->save_type=type; + } + return 1; + } + +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) + { + return pkey_set_type(pkey, type, NULL, -1); + } + +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) + { + return pkey_set_type(pkey, EVP_PKEY_NONE, str, len); + } + +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) + { + if (!EVP_PKEY_set_type(pkey, type)) + return 0; pkey->pkey.ptr=key; - return(key != NULL); + return (key != NULL); } void *EVP_PKEY_get0(EVP_PKEY *pkey) @@ -279,7 +357,7 @@ int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) { - if(pkey->type != EVP_PKEY_DH) { + if(pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) { EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY); return NULL; } @@ -290,11 +368,29 @@ DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) int EVP_PKEY_type(int type) { + int ret; const EVP_PKEY_ASN1_METHOD *ameth; - ameth = EVP_PKEY_asn1_find(type); + ENGINE *e; + ameth = EVP_PKEY_asn1_find(&e, type); if (ameth) - return ameth->pkey_id; - return NID_undef; + ret = ameth->pkey_id; + else + ret = NID_undef; +#ifndef OPENSSL_NO_ENGINE + if (e) + ENGINE_finish(e); +#endif + return ret; + } + +int EVP_PKEY_id(const EVP_PKEY *pkey) + { + return pkey->type; + } + +int EVP_PKEY_base_id(const EVP_PKEY *pkey) + { + return EVP_PKEY_type(pkey->type); } void EVP_PKEY_free(EVP_PKEY *x) @@ -324,15 +420,25 @@ void EVP_PKEY_free(EVP_PKEY *x) static void EVP_PKEY_free_it(EVP_PKEY *x) { if (x->ameth && x->ameth->pkey_free) + { x->ameth->pkey_free(x); + x->pkey.ptr = NULL; + } +#ifndef OPENSSL_NO_ENGINE + if (x->engine) + { + ENGINE_finish(x->engine); + x->engine = NULL; + } +#endif } static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr) { BIO_indent(out, indent, 128); - BIO_printf(out, "%s %s, algorithm, unsupported\n", - OBJ_nid2ln(pkey->type), kstr); + BIO_printf(out, "%s algorithm \"%s\" unsupported\n", + kstr, OBJ_nid2ln(pkey->type)); return 1; } @@ -361,3 +467,12 @@ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, return pkey->ameth->param_print(out, pkey, indent, pctx); return unsup_alg(out, pkey, indent, "Parameters"); } + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid) + { + if (!pkey->ameth || !pkey->ameth->pkey_ctrl) + return -2; + return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, + 0, pnid); + } +