diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2006-06-05 11:52:46 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2006-06-05 11:52:46 +0000 |
commit | 01b8b3c7d2d8f835257ac1cb2512273aa27bfba8 (patch) | |
tree | fb224473dca22be551086f10ed34240c802c6335 /crypto/evp | |
parent | 8fecd4b4f1bd6f066ba0a9f96387f00ac0dd99bf (diff) |
Complete EVP_PKEY_ASN1_METHOD ENGINE support.
Diffstat (limited to 'crypto/evp')
-rw-r--r-- | crypto/evp/evp.h | 11 | ||||
-rw-r--r-- | crypto/evp/evp_err.c | 2 | ||||
-rw-r--r-- | crypto/evp/evp_pkey.c | 38 | ||||
-rw-r--r-- | crypto/evp/p_lib.c | 100 | ||||
-rw-r--r-- | crypto/evp/pmeth_lib.c | 3 |
5 files changed, 114 insertions, 40 deletions
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 833257a937..32a1ebe9f6 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -129,7 +129,7 @@ struct evp_pkey_st int save_type; int references; const EVP_PKEY_ASN1_METHOD *ameth; - const EVP_PKEY_METHOD *pmeth; + ENGINE *engine; union { char *ptr; #ifndef OPENSSL_NO_RSA @@ -770,6 +770,8 @@ int EVP_PKEY_id(const EVP_PKEY *pkey); int EVP_PKEY_base_id(const EVP_PKEY *pkey); int EVP_PKEY_bits(EVP_PKEY *pkey); int EVP_PKEY_size(EVP_PKEY *pkey); +int EVP_PKEY_set_type(EVP_PKEY *pkey,int type); +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); int EVP_PKEY_assign(EVP_PKEY *pkey,int type,void *key); void * EVP_PKEY_get0(EVP_PKEY *pkey); @@ -874,8 +876,9 @@ void EVP_PBE_cleanup(void); int EVP_PKEY_asn1_get_count(void); const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); -const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type); -const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(const char *str, int len); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len); int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); int EVP_PKEY_asn1_add_alias(int to, int from); int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags, @@ -1142,6 +1145,7 @@ void ERR_load_EVP_strings(void); #define EVP_F_PKCS5_PBE_KEYIVGEN 117 #define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 #define EVP_F_PKCS8_SET_BROKEN 112 +#define EVP_F_PKEY_SET_TYPE 158 #define EVP_F_RC2_MAGIC_TO_METH 109 #define EVP_F_RC5_CTRL 125 @@ -1193,6 +1197,7 @@ void ERR_load_EVP_strings(void); #define EVP_R_PUBLIC_KEY_NOT_RSA 106 #define EVP_R_UNKNOWN_PBE_ALGORITHM 121 #define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135 +#define EVP_R_UNSUPPORTED_ALGORITHM 156 #define EVP_R_UNSUPPORTED_CIPHER 107 #define EVP_R_UNSUPPORTED_KEYLENGTH 123 #define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index a2f253cbd0..150bfd0db9 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -125,6 +125,7 @@ static ERR_STRING_DATA EVP_str_functs[]= {ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"}, {ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"}, {ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"}, +{ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"}, {ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"}, {ERR_FUNC(EVP_F_RC5_CTRL), "RC5_CTRL"}, {0,NULL} @@ -179,6 +180,7 @@ static ERR_STRING_DATA EVP_str_reasons[]= {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"}, {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"}, {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"}, +{ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"}, {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"}, {ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH) ,"unsupported keylength"}, {ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),"unsupported key derivation function"}, diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c index e81c4fedb1..19cdbf9666 100644 --- a/crypto/evp/evp_pkey.c +++ b/crypto/evp/evp_pkey.c @@ -69,7 +69,6 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { EVP_PKEY *pkey = NULL; ASN1_OBJECT *algoid; - const EVP_PKEY_ASN1_METHOD *meth; char obj_tmp[80]; if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8)) @@ -80,33 +79,29 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) return NULL; } - meth = EVP_PKEY_asn1_find(OBJ_obj2nid(algoid)); + if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) + { + EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); + i2t_ASN1_OBJECT(obj_tmp, 80, algoid); + ERR_add_error_data(2, "TYPE=", obj_tmp); + goto error; + } - if (meth) + if (pkey->ameth->priv_decode) { - if (meth->priv_decode) - { - if (!meth->priv_decode(pkey, p8)) - { - EVPerr(EVP_F_EVP_PKCS82PKEY, - EVP_R_PRIVATE_KEY_DECODE_ERROR); - goto error; - } - } - else + if (!pkey->ameth->priv_decode(pkey, p8)) { EVPerr(EVP_F_EVP_PKCS82PKEY, - EVP_R_METHOD_NOT_SUPPORTED); + EVP_R_PRIVATE_KEY_DECODE_ERROR); goto error; } } else { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); - i2t_ASN1_OBJECT(obj_tmp, 80, algoid); - ERR_add_error_data(2, "TYPE=", obj_tmp); + EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED); goto error; } + return pkey; error: @@ -124,7 +119,6 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken) { PKCS8_PRIV_KEY_INFO *p8; - const EVP_PKEY_ASN1_METHOD *meth; if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE); @@ -132,13 +126,11 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken) } p8->broken = broken; - meth = EVP_PKEY_asn1_find(pkey->type); - - if (meth) + if (pkey->ameth) { - if (meth->priv_encode) + if (pkey->ameth->priv_encode) { - if (!meth->priv_encode(p8, pkey)) + if (!pkey->ameth->priv_encode(p8, pkey)) { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_PRIVATE_KEY_ENCODE_ERROR); diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 752547d1e6..939857fdb0 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -74,6 +74,10 @@ #include <openssl/dh.h> #endif +#ifndef OPENSSL_NO_ENGINE +#include <openssl/engine.h> +#endif + #include "asn1_locl.h" static void EVP_PKEY_free_it(EVP_PKEY *x); @@ -177,26 +181,79 @@ 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); +#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) @@ -290,11 +347,19 @@ 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) @@ -335,14 +400,21 @@ static void EVP_PKEY_free_it(EVP_PKEY *x) { if (x->ameth && x->ameth->pkey_free) x->ameth->pkey_free(x); +#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; } diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 8108d448cb..49a8ee99cb 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -140,7 +140,10 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) pmeth = EVP_PKEY_meth_find(id); if (pmeth == NULL) + { + EVPerr(EVP_F_INT_CTX_NEW,EVP_R_UNSUPPORTED_ALGORITHM); return NULL; + } ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); if (!ret) |