Skip to content
Permalink
Browse files
Initial support for pluggable public key ASN1 support. Process most p…
…ublic

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.
  • Loading branch information
snhenson committed Mar 20, 2006
1 parent 1a5a1a9 commit 448be74
Show file tree
Hide file tree
Showing 24 changed files with 1,366 additions and 826 deletions.
@@ -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]
@@ -25,7 +25,7 @@ LIBSRC= a_object.c a_bitstr.c a_utctm.c a_gentm.c a_time.c a_int.c a_octet.c \
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 @@ LIBOBJ= a_object.o a_bitstr.o a_utctm.o a_gentm.o a_time.o a_int.o a_octet.o \
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 \
@@ -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;
}

@@ -282,6 +282,26 @@ typedef struct ASN1_TLC_st ASN1_TLC;
/* 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)
@@ -83,3 +83,73 @@ ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
} 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;
}

@@ -71,3 +71,55 @@ IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR)

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;
}
}

0 comments on commit 448be74

Please sign in to comment.