summaryrefslogtreecommitdiffstats
path: root/crypto/evp
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2006-06-05 11:52:46 +0000
committerDr. Stephen Henson <steve@openssl.org>2006-06-05 11:52:46 +0000
commit01b8b3c7d2d8f835257ac1cb2512273aa27bfba8 (patch)
treefb224473dca22be551086f10ed34240c802c6335 /crypto/evp
parent8fecd4b4f1bd6f066ba0a9f96387f00ac0dd99bf (diff)
Complete EVP_PKEY_ASN1_METHOD ENGINE support.
Diffstat (limited to 'crypto/evp')
-rw-r--r--crypto/evp/evp.h11
-rw-r--r--crypto/evp/evp_err.c2
-rw-r--r--crypto/evp/evp_pkey.c38
-rw-r--r--crypto/evp/p_lib.c100
-rw-r--r--crypto/evp/pmeth_lib.c3
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)