#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
+#include "asn1_locl.h"
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#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)
{
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
{
- int ok=0;
- X509_PUBKEY *pk;
- X509_ALGOR *a;
- ASN1_OBJECT *o;
- unsigned char *s,*p;
- int i;
+ X509_PUBKEY *pk=NULL;
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))
- {
- ASN1_TYPE_free(a->parameter);
- a->parameter=ASN1_TYPE_new();
- 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);
- i=i2d_DSAparams(dsa,NULL);
- p=(unsigned char *)OPENSSL_malloc(i);
- pp=p;
- i2d_DSAparams(dsa,&pp);
- a->parameter=ASN1_TYPE_new();
- a->parameter->type=V_ASN1_SEQUENCE;
- a->parameter->value.sequence=ASN1_STRING_new();
- ASN1_STRING_set(a->parameter->value.sequence,p,i);
- OPENSSL_free(p);
- }
-#endif
-#ifndef OPENSSL_NO_ECDSA
- else if (pkey->type == EVP_PKEY_ECDSA)
- {
- unsigned char *pp;
- ECDSA *ecdsa;
-
- ecdsa = pkey->pkey.ecdsa;
- ecdsa->write_params=0;
- ASN1_TYPE_free(a->parameter);
- if ((i = i2d_ECDSAParameters(ecdsa, NULL)) == 0)
- {
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_ECDSA_LIB);
- goto err;
- }
- if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
+ if (pkey->ameth->pub_encode)
{
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- pp = p;
- if (!i2d_ECDSAParameters(ecdsa, &pp))
- {
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_ECDSA_LIB);
- OPENSSL_free(p);
- goto err;
- }
- if ((a->parameter = ASN1_TYPE_new()) == NULL)
- {
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
- OPENSSL_free(p);
- goto err;
+ if (!pkey->ameth->pub_encode(pk, pkey))
+ {
+ X509err(X509_F_X509_PUBKEY_SET,
+ X509_R_PUBLIC_KEY_ENCODE_ERROR);
+ goto error;
+ }
}
- a->parameter->type = V_ASN1_SEQUENCE;
- if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL)
+ else
{
- X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
- OPENSSL_free(p);
- goto err;
+ X509err(X509_F_X509_PUBKEY_SET,
+ X509_R_METHOD_NOT_SUPPORTED);
+ goto error;
}
- ASN1_STRING_set(a->parameter->value.sequence, p, i);
- OPENSSL_free(p);
}
-#endif
- else if (1)
+ else
{
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) goto err;
- p=s;
- i2d_PublicKey(pkey,&p);
- if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i)) 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;
- pk=NULL;
- ok=1;
-err:
+ return 1;
+error:
if (pk != NULL) X509_PUBKEY_free(pk);
- return(ok);
+ return 0;
}
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
{
EVP_PKEY *ret=NULL;
- long j;
- int type;
- 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_ECDSA
- else if (ret->type == EVP_PKEY_ECDSA)
+
+ if (ret->ameth->pub_decode)
{
- if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
+ if (!ret->ameth->pub_decode(ret, key))
{
- if ((ret->pkey.ecdsa= ECDSA_new()) == NULL)
- {
- X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- ret->pkey.ecdsa->write_params = 0;
- cp = p = a->parameter->value.sequence->data;
- j = a->parameter->value.sequence->length;
- if (!d2i_ECDSAParameters(&ret->pkey.ecdsa, &cp, (long)j))
- {
- X509err(X509_F_X509_PUBKEY_GET, ERR_R_ECDSA_LIB);
- goto err;
- }
+ X509err(X509_F_X509_PUBKEY_GET,
+ X509_R_PUBLIC_KEY_DECODE_ERROR);
+ goto error;
}
- ret->save_parameters = 1;
}
-#endif
-
- p=key->public_key->data;
- j=key->public_key->length;
- if ((ret = d2i_PublicKey(type, &ret, &p, (long)j)) == NULL)
+ 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);
* and encode or decode as X509_PUBKEY
*/
-EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, unsigned char **pp,
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp,
long length)
{
X509_PUBKEY *xpk;
* keys
*/
#ifndef OPENSSL_NO_RSA
-RSA *d2i_RSA_PUBKEY(RSA **a, unsigned char **pp,
+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp,
long length)
{
EVP_PKEY *pkey;
RSA *key;
- unsigned char *q;
+ const unsigned char *q;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey) return NULL;
#endif
#ifndef OPENSSL_NO_DSA
-DSA *d2i_DSA_PUBKEY(DSA **a, unsigned char **pp,
+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp,
long length)
{
EVP_PKEY *pkey;
DSA *key;
- unsigned char *q;
+ const unsigned char *q;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey) return NULL;
}
#endif
-#ifndef OPENSSL_NO_ECDSA
-ECDSA *d2i_ECDSA_PUBKEY(ECDSA **a, unsigned char **pp, long length)
+#ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
{
EVP_PKEY *pkey;
- ECDSA *key;
- unsigned char *q;
+ EC_KEY *key;
+ const unsigned char *q;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey) return(NULL);
- key = EVP_PKEY_get1_ECDSA(pkey);
+ key = EVP_PKEY_get1_EC_KEY(pkey);
EVP_PKEY_free(pkey);
if (!key) return(NULL);
*pp = q;
if (a)
{
- ECDSA_free(*a);
+ EC_KEY_free(*a);
*a = key;
}
return(key);
}
-int i2d_ECDSA_PUBKEY(ECDSA *a, unsigned char **pp)
+int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
{
EVP_PKEY *pktmp;
int ret;
if (!a) return(0);
if ((pktmp = EVP_PKEY_new()) == NULL)
{
- ASN1err(ASN1_F_I2D_ECDSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
return(0);
}
- EVP_PKEY_set1_ECDSA(pktmp, a);
+ EVP_PKEY_set1_EC_KEY(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
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;
+ }