Commit 448be743 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

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.
parent 1a5a1a93
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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]
+2 −2
Original line number Diff line number Diff line
@@ -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 \
+113 −0
Original line number Diff line number Diff line
/* 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;
	}
+20 −0
Original line number Diff line number Diff line
@@ -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)
+70 −0
Original line number Diff line number Diff line
@@ -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;
	}
Loading