Index: openssl/crypto/asn1/x_pubkey.c |
=================================================================== |
--- openssl/crypto/asn1/x_pubkey.c (revision 105093) |
+++ openssl/crypto/asn1/x_pubkey.c (working copy) |
@@ -60,6 +60,7 @@ |
#include "cryptlib.h" |
#include <openssl/asn1t.h> |
#include <openssl/x509.h> |
+#include "asn1_locl.h" |
#ifndef OPENSSL_NO_RSA |
#include <openssl/rsa.h> |
#endif |
@@ -68,7 +69,8 @@ |
#endif |
/* Minor tweak to operation: free up EVP_PKEY */ |
-static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) |
+static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, |
+ void *exarg) |
{ |
if (operation == ASN1_OP_FREE_POST) |
{ |
@@ -88,169 +90,42 @@ |
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) |
{ |
X509_PUBKEY *pk=NULL; |
- X509_ALGOR *a; |
- ASN1_OBJECT *o; |
- unsigned char *s,*p = NULL; |
- int i; |
if (x == NULL) return(0); |
- if ((pk=X509_PUBKEY_new()) == NULL) goto err; |
- a=pk->algor; |
+ if ((pk=X509_PUBKEY_new()) == NULL) goto error; |
- /* set the algorithm id */ |
- if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err; |
- ASN1_OBJECT_free(a->algorithm); |
- a->algorithm=o; |
- |
- /* Set the parameter list */ |
- if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA)) |
+ if (pkey->ameth) |
{ |
- if ((a->parameter == NULL) || |
- (a->parameter->type != V_ASN1_NULL)) |
+ if (pkey->ameth->pub_encode) |
{ |
- ASN1_TYPE_free(a->parameter); |
- if (!(a->parameter=ASN1_TYPE_new())) |
+ if (!pkey->ameth->pub_encode(pk, pkey)) |
{ |
- X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); |
- goto err; |
+ X509err(X509_F_X509_PUBKEY_SET, |
+ X509_R_PUBLIC_KEY_ENCODE_ERROR); |
+ goto error; |
} |
- a->parameter->type=V_ASN1_NULL; |
} |
- } |
-#ifndef OPENSSL_NO_DSA |
- else if (pkey->type == EVP_PKEY_DSA) |
- { |
- unsigned char *pp; |
- DSA *dsa; |
- |
- dsa=pkey->pkey.dsa; |
- dsa->write_params=0; |
- ASN1_TYPE_free(a->parameter); |
- if ((i=i2d_DSAparams(dsa,NULL)) <= 0) |
- goto err; |
- if (!(p=(unsigned char *)OPENSSL_malloc(i))) |
+ else |
{ |
- X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); |
- goto err; |
+ X509err(X509_F_X509_PUBKEY_SET, |
+ X509_R_METHOD_NOT_SUPPORTED); |
+ goto error; |
} |
- pp=p; |
- i2d_DSAparams(dsa,&pp); |
- if (!(a->parameter=ASN1_TYPE_new())) |
- { |
- OPENSSL_free(p); |
- X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); |
- goto err; |
- } |
- a->parameter->type=V_ASN1_SEQUENCE; |
- if (!(a->parameter->value.sequence=ASN1_STRING_new())) |
- { |
- OPENSSL_free(p); |
- X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); |
- goto err; |
- } |
- if (!ASN1_STRING_set(a->parameter->value.sequence,p,i)) |
- { |
- OPENSSL_free(p); |
- X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); |
- goto err; |
- } |
- OPENSSL_free(p); |
} |
-#endif |
-#ifndef OPENSSL_NO_EC |
- else if (pkey->type == EVP_PKEY_EC) |
+ else |
{ |
- int nid=0; |
- unsigned char *pp; |
- EC_KEY *ec_key; |
- const EC_GROUP *group; |
- |
- ec_key = pkey->pkey.ec; |
- ASN1_TYPE_free(a->parameter); |
- |
- if ((a->parameter = ASN1_TYPE_new()) == NULL) |
- { |
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB); |
- goto err; |
- } |
- |
- group = EC_KEY_get0_group(ec_key); |
- if (EC_GROUP_get_asn1_flag(group) |
- && (nid = EC_GROUP_get_curve_name(group))) |
- { |
- /* just set the OID */ |
- a->parameter->type = V_ASN1_OBJECT; |
- a->parameter->value.object = OBJ_nid2obj(nid); |
- } |
- else /* explicit parameters */ |
- { |
- if ((i = i2d_ECParameters(ec_key, NULL)) == 0) |
- { |
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB); |
- goto err; |
- } |
- if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL) |
- { |
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE); |
- goto err; |
- } |
- pp = p; |
- if (!i2d_ECParameters(ec_key, &pp)) |
- { |
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB); |
- OPENSSL_free(p); |
- goto err; |
- } |
- a->parameter->type = V_ASN1_SEQUENCE; |
- if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL) |
- { |
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB); |
- OPENSSL_free(p); |
- goto err; |
- } |
- ASN1_STRING_set(a->parameter->value.sequence, p, i); |
- OPENSSL_free(p); |
- } |
- } |
-#endif |
- else if (1) |
- { |
X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM); |
- goto err; |
+ goto error; |
} |
- if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err; |
- if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL) |
- { |
- X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); |
- goto err; |
- } |
- p=s; |
- i2d_PublicKey(pkey,&p); |
- if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i)) |
- { |
- X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); |
- goto err; |
- } |
- /* Set number of unused bits to zero */ |
- pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); |
- pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT; |
- |
- OPENSSL_free(s); |
- |
-#if 0 |
- CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY); |
- pk->pkey=pkey; |
-#endif |
- |
if (*x != NULL) |
X509_PUBKEY_free(*x); |
*x=pk; |
return 1; |
-err: |
+error: |
if (pk != NULL) X509_PUBKEY_free(pk); |
return 0; |
} |
@@ -258,119 +133,50 @@ |
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) |
{ |
EVP_PKEY *ret=NULL; |
- long j; |
- int type; |
- const unsigned char *p; |
-#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) |
- const unsigned char *cp; |
- X509_ALGOR *a; |
-#endif |
- if (key == NULL) goto err; |
+ if (key == NULL) goto error; |
if (key->pkey != NULL) |
{ |
CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); |
- return(key->pkey); |
+ return key->pkey; |
} |
- if (key->public_key == NULL) goto err; |
+ if (key->public_key == NULL) goto error; |
- type=OBJ_obj2nid(key->algor->algorithm); |
if ((ret = EVP_PKEY_new()) == NULL) |
{ |
X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); |
- goto err; |
+ goto error; |
} |
- ret->type = EVP_PKEY_type(type); |
- /* the parameters must be extracted before the public key (ECDSA!) */ |
- |
-#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) |
- a=key->algor; |
-#endif |
- |
- if (0) |
- ; |
-#ifndef OPENSSL_NO_DSA |
- else if (ret->type == EVP_PKEY_DSA) |
+ if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm))) |
{ |
- if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) |
- { |
- if ((ret->pkey.dsa = DSA_new()) == NULL) |
- { |
- X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); |
- goto err; |
- } |
- ret->pkey.dsa->write_params=0; |
- cp=p=a->parameter->value.sequence->data; |
- j=a->parameter->value.sequence->length; |
- if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j)) |
- goto err; |
- } |
- ret->save_parameters=1; |
+ X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM); |
+ goto error; |
} |
-#endif |
-#ifndef OPENSSL_NO_EC |
- else if (ret->type == EVP_PKEY_EC) |
+ |
+ if (ret->ameth->pub_decode) |
{ |
- if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) |
+ if (!ret->ameth->pub_decode(ret, key)) |
{ |
- /* type == V_ASN1_SEQUENCE => we have explicit parameters |
- * (e.g. parameters in the X9_62_EC_PARAMETERS-structure ) |
- */ |
- if ((ret->pkey.ec= EC_KEY_new()) == NULL) |
- { |
- X509err(X509_F_X509_PUBKEY_GET, |
- ERR_R_MALLOC_FAILURE); |
- goto err; |
- } |
- cp = p = a->parameter->value.sequence->data; |
- j = a->parameter->value.sequence->length; |
- if (!d2i_ECParameters(&ret->pkey.ec, &cp, (long)j)) |
- { |
- X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB); |
- goto err; |
- } |
+ X509err(X509_F_X509_PUBKEY_GET, |
+ X509_R_PUBLIC_KEY_DECODE_ERROR); |
+ goto error; |
} |
- else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT)) |
- { |
- /* type == V_ASN1_OBJECT => the parameters are given |
- * by an asn1 OID |
- */ |
- EC_KEY *ec_key; |
- EC_GROUP *group; |
- |
- if (ret->pkey.ec == NULL) |
- ret->pkey.ec = EC_KEY_new(); |
- ec_key = ret->pkey.ec; |
- if (ec_key == NULL) |
- goto err; |
- group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object)); |
- if (group == NULL) |
- goto err; |
- EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); |
- if (EC_KEY_set_group(ec_key, group) == 0) |
- goto err; |
- EC_GROUP_free(group); |
- } |
- /* the case implicitlyCA is currently not implemented */ |
- ret->save_parameters = 1; |
} |
-#endif |
- |
- p=key->public_key->data; |
- j=key->public_key->length; |
- if (!d2i_PublicKey(type, &ret, &p, (long)j)) |
+ else |
{ |
- X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB); |
- goto err; |
+ X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED); |
+ goto error; |
} |
key->pkey = ret; |
CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY); |
- return(ret); |
-err: |
+ |
+ return ret; |
+ |
+ error: |
if (ret != NULL) |
EVP_PKEY_free(ret); |
return(NULL); |
@@ -529,3 +335,39 @@ |
return(ret); |
} |
#endif |
+ |
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, |
+ int ptype, void *pval, |
+ unsigned char *penc, int penclen) |
+ { |
+ if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval)) |
+ return 0; |
+ if (penc) |
+ { |
+ if (pub->public_key->data) |
+ OPENSSL_free(pub->public_key->data); |
+ pub->public_key->data = penc; |
+ pub->public_key->length = penclen; |
+ /* Set number of unused bits to zero */ |
+ pub->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); |
+ pub->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT; |
+ } |
+ return 1; |
+ } |
+ |
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, |
+ const unsigned char **pk, int *ppklen, |
+ X509_ALGOR **pa, |
+ X509_PUBKEY *pub) |
+ { |
+ if (ppkalg) |
+ *ppkalg = pub->algor->algorithm; |
+ if (pk) |
+ { |
+ *pk = pub->public_key->data; |
+ *ppklen = pub->public_key->length; |
+ } |
+ if (pa) |
+ *pa = pub->algor; |
+ return 1; |
+ } |