OpenSSL CVS Repository
http://cvs.openssl.org/
____________________________________________________________
________________
Server: cvs.openssl.org Name: Dr.
Stephen Henson
Root: /v/openssl/cvs Email: steve openssl.org
Module: openssl Date:
20-Mar-2006 13:22:24
Branch: HEAD Handle:
2006032012221806
Added files:
openssl/crypto/asn1 ameth_lib.c
openssl/crypto/dsa dsa_ameth.c
openssl/crypto/ec ec_ameth.c
openssl/crypto/rsa rsa_ameth.c
Modified files:
openssl CHANGES
openssl/crypto ossl_typ.h
openssl/crypto/asn1 Makefile asn1.h p8_pkey.c
x_algor.c x_pubkey.c
openssl/crypto/dsa Makefile dsa.h dsa_err.c
openssl/crypto/ec Makefile ec.h
openssl/crypto/evp evp.h evp_err.c evp_pkey.c
openssl/crypto/rsa Makefile rsa.h rsa_err.c
openssl/crypto/x509 x509.h x509_err.c
Log:
Initial support for pluggable public key ASN1 support.
Process most public
key ASN1 handling through a single EVP_PKEY_ASN1_METHOD
structure and move
the spaghetti algorithm specific code to a single ASN1
module for each
algorithm.
Summary:
Revision Changes Path
1.1292 +8 -0 openssl/CHANGES
1.9 +2 -2 openssl/crypto/asn1/Makefile
1.1 +113 -0 openssl/crypto/asn1/ameth_lib.c
1.140 +20 -0 openssl/crypto/asn1/asn1.h
1.14 +70 -0 openssl/crypto/asn1/p8_pkey.c
1.12 +52 -0 openssl/crypto/asn1/x_algor.c
1.41 +75 -226 openssl/crypto/asn1/x_pubkey.c
1.6 +2 -2 openssl/crypto/dsa/Makefile
1.40 +8 -0 openssl/crypto/dsa/dsa.h
1.1 +376 -0 openssl/crypto/dsa/dsa_ameth.c
1.14 +8 -0 openssl/crypto/dsa/dsa_err.c
1.7 +2 -2 openssl/crypto/ec/Makefile
1.82 +7 -0 openssl/crypto/ec/ec.h
1.1 +360 -0 openssl/crypto/ec/ec_ameth.c
1.115 +6 -0 openssl/crypto/evp/evp.h
1.29 +4 -0 openssl/crypto/evp/evp_err.c
1.40 +52 -584 openssl/crypto/evp/evp_pkey.c
1.11 +5 -0 openssl/crypto/ossl_typ.h
1.8 +2 -2 openssl/crypto/rsa/Makefile
1.60 +3 -0 openssl/crypto/rsa/rsa.h
1.1 +154 -0 openssl/crypto/rsa/rsa_ameth.c
1.20 +7 -4 openssl/crypto/rsa/rsa_err.c
1.140 +27 -4 openssl/crypto/x509/x509.h
1.26 +3 -0 openssl/crypto/x509/x509_err.c
____________________________________________________________
________________
patch -p0 <<' .'
Index: openssl/CHANGES
============================================================
================
$ cvs diff -u -r1.1291 -r1.1292 CHANGES
--- openssl/CHANGES 11 Mar 2006 23:46:33 -0000 1.1291
+++ openssl/CHANGES 20 Mar 2006 12:22:18 -0000 1.1292
 -4,6 +4,14 
Changes between 0.9.8a and 0.9.9 [xx XXX xxxx]
+ *) Initial support for pluggable public key ASN1.
+ De-spaghettify the public key ASN1 handling. Move
public and private
+ key ASN1 handling to a new EVP_PKEY_ASN1_METHOD
structure. Relocate
+ algorithm specific handling to a single module
within the relevant
+ algorithm directory. Add functions to allow (near)
opaque processing
+ of public and private key structures.
+ [Steve Henson]
+
*) Implement the Supported Point Formats Extension for
ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
[Douglas Stebila]
 .
patch -p0 <<' .'
Index: openssl/crypto/asn1/Makefile
============================================================
================
$ cvs diff -u -r1.8 -r1.9 Makefile
--- openssl/crypto/asn1/Makefile 12 Feb 2006 23:21:46
-0000 1.8
+++ openssl/crypto/asn1/Makefile 20 Mar 2006 12:22:19
-0000 1.9
 -25,7 +25,7 
x_nx509.c d2i_pu.c d2i_pr.c i2d_pu.c i2d_pr.c\
t_req.c t_x509.c t_x509a.c t_crl.c t_pkey.c t_spki.c
t_bitst.c \
tasn_new.c tasn_fre.c tasn_enc.c tasn_dec.c tasn_utl.c
tasn_typ.c \
- tasn_prn.c \
+ tasn_prn.c ameth_lib.c \
f_int.c f_string.c n_pkey.c \
f_enum.c x_pkey.c a_bool.c x_exten.c \
asn1_gen.c asn1_par.c asn1_lib.c asn1_err.c a_bytes.c
a_strnid.c \
 -38,7 +38,7 
x_nx509.o d2i_pu.o d2i_pr.o i2d_pu.o i2d_pr.o \
t_req.o t_x509.o t_x509a.o t_crl.o t_pkey.o t_spki.o
t_bitst.o \
tasn_new.o tasn_fre.o tasn_enc.o tasn_dec.o tasn_utl.o
tasn_typ.o \
- tasn_prn.o \
+ tasn_prn.o ameth_lib.o \
f_int.o f_string.o n_pkey.o \
f_enum.o x_pkey.o a_bool.o x_exten.o \
asn1_gen.o asn1_par.o asn1_lib.o asn1_err.o a_bytes.o
a_strnid.o \
 .
patch -p0 <<' .'
Index: openssl/crypto/asn1/ameth_lib.c
============================================================
================
$ cvs diff -u -r0 -r1.1 ameth_lib.c
--- /dev/null 2006-03-20 13:22:14 +0100
+++ ameth_lib.c 2006-03-20 13:22:20 +0100
 -0,0 +1,113 
+/* Written by Dr Stephen N Henson (shenson bigfoot.com) for the OpenSSL
+ * project 2006.
+ */
+/*
============================================================
========
+ * Copyright (c) 2006 The OpenSSL Project. All rights
reserved.
+ *
+ * Redistribution and use in source and binary forms,
with or without
+ * modification, are permitted provided that the
following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the
above copyright
+ * notice, this list of conditions and the following
disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the
above copyright
+ * notice, this list of conditions and the following
disclaimer in
+ * the documentation and/or other materials provided
with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or
use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by
the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)
"
+ *
+ * 4. The names "OpenSSL Toolkit" and
"OpenSSL Project" must not be used to
+ * endorse or promote products derived from this
software without
+ * prior written permission. For written permission,
please contact
+ * licensing OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be
called "OpenSSL"
+ * nor may "OpenSSL" appear in their names
without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain
the following
+ * acknowledgment:
+ * "This product includes software developed by
the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)
"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS
IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL
PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
============================================================
========
+ *
+ * This product includes cryptographic software written
by Eric Young
+ * (eay cryptsoft.com). This product includes software
written by Tim
+ * Hudson (tjh cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/ec.h>
+#include "asn1_locl.h"
+
+extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
+
+/* Keep this sorted in type order !! */
+const EVP_PKEY_ASN1_METHOD *standard_methods[] =
+ {
+ &rsa_asn1_meths[0],
+ &rsa_asn1_meths[1],
+ &dsa_asn1_meths[0],
+ &dsa_asn1_meths[1],
+ &dsa_asn1_meths[2],
+ &dsa_asn1_meths[3],
+ &dsa_asn1_meths[4],
+ &eckey_asn1_meth
+ };
+
+#ifdef TEST
+void main()
+ {
+ int i;
+ for (i = 0;
+ i <
sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+ i++)
+ fprintf(stderr, "Number %d id=%d\n", i,
+ standard_methods[i]->pkey_id);
+ }
+#endif
+
+static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const
*a,
+ const EVP_PKEY_ASN1_METHOD * const *b)
+ {
+ return ((*a)->pkey_id - (*b)->pkey_id);
+ }
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_ASN1_find(int type)
+ {
+ EVP_PKEY_ASN1_METHOD tmp, *t = &tmp, **ret;
+ tmp.pkey_id = type;
+ ret = (EVP_PKEY_ASN1_METHOD **) OBJ_bsearch((char
*)&t,
+ (char *)standard_methods,
+ sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD
*),
+ sizeof(EVP_PKEY_ASN1_METHOD *),
+ (int (*)(const void *, const void *))ameth_cmp);
+ if ((*ret)->pkey_flags & ASN1_PKEY_ALIAS)
+ return EVP_PKEY_ASN1_find((*ret)->pkey_base_id);
+ return *ret;
+ }
+
 .
patch -p0 <<' .'
Index: openssl/crypto/asn1/asn1.h
============================================================
================
$ cvs diff -u -r1.139 -r1.140 asn1.h
--- openssl/crypto/asn1/asn1.h 5 Mar 2006 20:18:59
-0000 1.139
+++ openssl/crypto/asn1/asn1.h 20 Mar 2006 12:22:19
-0000 1.140
 -282,6 +282,26 
/* This is just an opaque pointer */
typedef struct ASN1_VALUE_st ASN1_VALUE;
+/* ASN1 public key method structure */
+
+#define ASN1_PKEY_ALIAS 0x1
+
+struct evp_pkey_asn1_method_st
+ {
+ int pkey_id;
+ int pkey_base_id;
+ unsigned long pkey_flags;
+ int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
+ int (*pub_encode)(X509_PUBKEY *pub, EVP_PKEY *pk);
+ int (*pub_print)(BIO *out, EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx);
+ int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO
*p8inf);
+ int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY
*pk);
+ int (*priv_print)(BIO *out, EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx);
+ void (*pkey_free)(EVP_PKEY *pkey);
+ void (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1,
void *arg2);
+ } /* EVP_PKEY_ASN1_METHOD */;
+
/* Declare ASN1 functions: the implement macro in in
asn1t.h */
#define DECLARE_ASN1_FUNCTIONS(type)
DECLARE_ASN1_FUNCTIONS_name(type, type)
 .
patch -p0 <<' .'
Index: openssl/crypto/asn1/p8_pkey.c
============================================================
================
$ cvs diff -u -r1.13 -r1.14 p8_pkey.c
--- openssl/crypto/asn1/p8_pkey.c 1 Sep 2005 20:42:49
-0000 1.13
+++ openssl/crypto/asn1/p8_pkey.c 20 Mar 2006 12:22:20
-0000 1.14
 -83,3 +83,73 
} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO,
PKCS8_PRIV_KEY_INFO)
IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv,
ASN1_OBJECT *aobj,
+ int version,
+ int ptype, void *pval,
+ unsigned char *penc, int penclen)
+ {
+ unsigned char **ppenc = NULL;
+ if (version >= 0)
+ {
+ if (!ASN1_INTEGER_set(priv->version, version))
+ return 0;
+ }
+ if (penc)
+ {
+ int pmtype;
+ ASN1_OCTET_STRING *oct;
+ oct = ASN1_OCTET_STRING_new();
+ if (!oct)
+ return 0;
+ oct->data = penc;
+ ppenc = &oct->data;
+ oct->length = penclen;
+ if (priv->broken == PKCS8_NO_OCTET)
+ pmtype = V_ASN1_SEQUENCE;
+ else
+ pmtype = V_ASN1_OCTET_STRING;
+ ASN1_TYPE_set(priv->pkey, pmtype, oct);
+ }
+ if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype,
pval))
+ {
+ /* If call fails do not swallow 'enc' */
+ if (ppenc)
+ *ppenc = NULL;
+ return 0;
+ }
+ return 1;
+ }
+
+int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
+ const unsigned char **pk, int *ppklen,
+ X509_ALGOR **pa,
+ PKCS8_PRIV_KEY_INFO *p8)
+ {
+ if (ppkalg)
+ *ppkalg = p8->pkeyalg->algorithm;
+ if(p8->pkey->type == V_ASN1_OCTET_STRING)
+ {
+ p8->broken = PKCS8_OK;
+ if (pk)
+ {
+ *pk = p8->pkey->value.octet_string->data;
+ *ppklen =
p8->pkey->value.octet_string->length;
+ }
+ }
+ else if (p8->pkey->type == V_ASN1_SEQUENCE)
+ {
+ p8->broken = PKCS8_NO_OCTET;
+ if (pk)
+ {
+ *pk = p8->pkey->value.sequence->data;
+ *ppklen = p8->pkey->value.sequence->length;
+ }
+ }
+ else
+ return 0;
+ if (pa)
+ *pa = p8->pkeyalg;
+ return 1;
+ }
+
 .
patch -p0 <<' .'
Index: openssl/crypto/asn1/x_algor.c
============================================================
================
$ cvs diff -u -r1.11 -r1.12 x_algor.c
--- openssl/crypto/asn1/x_algor.c 27 Jul 2001 02:22:23
-0000 1.11
+++ openssl/crypto/asn1/x_algor.c 20 Mar 2006 12:22:20
-0000 1.12
 -71,3 +71,55 
IMPLEMENT_STACK_OF(X509_ALGOR)
IMPLEMENT_ASN1_SET_OF(X509_ALGOR)
+
+int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj,
int ptype, void *pval)
+ {
+ if (!alg)
+ return 0;
+ if (ptype != V_ASN1_UNDEF)
+ {
+ if (alg->parameter == NULL)
+ alg->parameter = ASN1_TYPE_new();
+ if (alg->parameter == NULL)
+ return 0;
+ }
+ if (alg)
+ {
+ if (alg->algorithm)
+ ASN1_OBJECT_free(alg->algorithm);
+ alg->algorithm = aobj;
+ }
+ if (ptype == 0)
+ return 1;
+ if (ptype == V_ASN1_UNDEF)
+ {
+ if (alg->parameter)
+ {
+ ASN1_TYPE_free(alg->parameter);
+ alg->parameter = NULL;
+ }
+ }
+ else
+ ASN1_TYPE_set(alg->parameter, ptype, pval);
+ return 1;
+ }
+
+void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype,
void **ppval,
+ X509_ALGOR *algor)
+ {
+ if (paobj)
+ *paobj = algor->algorithm;
+ if (*pptype)
+ {
+ if (algor->parameter == NULL)
+ {
+ *pptype = V_ASN1_UNDEF;
+ return;
+ }
+ else
+ *pptype = algor->parameter->type;
+ if (ppval)
+ *ppval = algor->parameter->value.ptr;
+ }
+ }
+
 .
patch -p0 <<' .'
Index: openssl/crypto/asn1/x_pubkey.c
============================================================
================
$ cvs diff -u -r1.40 -r1.41 x_pubkey.c
--- openssl/crypto/asn1/x_pubkey.c 1 Sep 2005 20:42:49
-0000 1.40
+++ openssl/crypto/asn1/x_pubkey.c 20 Mar 2006 12:22:20
-0000 1.41
 -89,161 +89,37 
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;
+ const EVP_PKEY_ASN1_METHOD *meth;
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;
+ meth = EVP_PKEY_ASN1_find(pkey->type);
- /* Set the parameter list */
- if (!pkey->save_parameters || (pkey->type ==
EVP_PKEY_RSA))
+ if (meth)
{
- if ((a->parameter == NULL) ||
- (a->parameter->type != V_ASN1_NULL))
+ if (meth->pub_encode)
{
- ASN1_TYPE_free(a->parameter);
- if (!(a->parameter=ASN1_TYPE_new()))
+ if (!meth->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)))
- {
- X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- 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))
+ else
{
- OPENSSL_free(p);
- 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;
}
- OPENSSL_free(p);
}
-#endif
-#ifndef OPENSSL_NO_EC
- else if (pkey->type == EVP_PKEY_EC)
- {
- 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)
+ else
{
X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITH
M);
- goto err;
- }
-
- 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;
+ goto error;
}
- /* 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);
 -251,7 +127,7 
*x=pk;
return 1;
-err:
+error:
if (pk != NULL) X509_PUBKEY_free(pk);
return 0;
}
 -259,119 +135,56 
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
+ const EVP_PKEY_ASN1_METHOD *meth;
- 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
+ meth =
EVP_PKEY_ASN1_find(OBJ_obj2nid(key->algor->algorithm))
;
- if (0)
- ;
-#ifndef OPENSSL_NO_DSA
- else if (ret->type == EVP_PKEY_DSA)
+ if (meth)
{
- if (a->parameter &&
(a->parameter->type == V_ASN1_SEQUENCE))
+ if (meth->pub_decode)
{
- if ((ret->pkey.dsa = DSA_new()) == NULL)
+ if (!meth->pub_decode(ret, key))
{
- X509err(X509_F_X509_PUBKEY_GET,
ERR_R_MALLOC_FAILURE);
- goto err;
+ X509err(X509_F_X509_PUBKEY_GET,
+ X509_R_PUBLIC_KEY_DECODE_ERROR);
+ goto error;
}
- 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;
- }
-#endif
-#ifndef OPENSSL_NO_EC
- else if (ret->type == EVP_PKEY_EC)
- {
- if (a->parameter &&
(a->parameter->type == V_ASN1_SEQUENCE))
+ else
{
- /* 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_METHOD_NOT_SUPPORTED);
+ 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->v
alue.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_UNSUPPORTED_ALGORIT
HM);
+ 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);
 -530,3 +343,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 = pu |