@@ -89,289 +89,102 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
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))
{
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)
{
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)))
else
{
/* 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);
X509err(X509_F_X509_PUBKEY_SET,
X509_R_METHOD_NOT_SUPPORTED);
goto error;
}
}
#endif
else if (1)
else
{
X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
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);

*x=pk;

return 1;
err:
error:
if (pk != NULL) X509_PUBKEY_free(pk);
return 0;
}

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->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_UNSUPPORTED_ALGORITHM);
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 @@ int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
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;
}
@@ -18,9 +18,9 @@ APPS=

LIB=$(TOP)/libcrypto.a
LIBSRC= dsa_gen.c dsa_key.c dsa_lib.c dsa_asn1.c dsa_vrf.c dsa_sign.c \
dsa_err.c dsa_ossl.c dsa_depr.c
dsa_err.c dsa_ossl.c dsa_depr.c dsa_ameth.c
LIBOBJ= dsa_gen.o dsa_key.o dsa_lib.o dsa_asn1.o dsa_vrf.o dsa_sign.o \
dsa_err.o dsa_ossl.o dsa_depr.o
dsa_err.o dsa_ossl.o dsa_depr.o dsa_ameth.o

SRC= $(LIBSRC)

@@ -262,6 +262,10 @@ void ERR_load_DSA_strings(void);
#define DSA_F_DSA_NEW_METHOD 103
#define DSA_F_DSA_PRINT 104
#define DSA_F_DSA_PRINT_FP 105
#define DSA_F_DSA_PRIV_DECODE 115
#define DSA_F_DSA_PRIV_ENCODE 116
#define DSA_F_DSA_PUB_DECODE 117
#define DSA_F_DSA_PUB_ENCODE 118
#define DSA_F_DSA_SIGN 106
#define DSA_F_DSA_SIGN_SETUP 107
#define DSA_F_DSA_SIG_NEW 109
@@ -270,8 +274,12 @@ void ERR_load_DSA_strings(void);
#define DSA_F_SIG_CB 114

/* Reason codes. */
#define DSA_R_BN_DECODE_ERROR 102
#define DSA_R_BN_ERROR 103
#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100
#define DSA_R_DECODE_ERROR 104
#define DSA_R_MISSING_PARAMETERS 101
#define DSA_R_PARAMETER_ENCODING_ERROR 105

#ifdef __cplusplus
}
@@ -0,0 +1,376 @@
/* 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/x509.h>
#include <openssl/asn1.h>
#include <openssl/dsa.h>

static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
{
const unsigned char *p, *pm;
int pklen, pmlen;
int ptype;
void *pval;
ASN1_STRING *pstr;
X509_ALGOR *palg;
ASN1_INTEGER *public_key = NULL;

DSA *dsa = NULL;

if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
return 0;
X509_ALGOR_get0(NULL, &ptype, &pval, palg);

if (ptype != V_ASN1_SEQUENCE)
{
DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
goto err;
}

pstr = pval;
pm = pstr->data;
pmlen = pstr->length;

if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
{
DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
goto err;
}

if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
{
DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
goto err;
}

/* We have parameters now set public key */
if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
{
DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
goto err;
}

ASN1_INTEGER_free(public_key);

return 1;

err:
if (pubkey)
ASN1_INTEGER_free(public_key);
if (dsa)
DSA_free(dsa);
return 0;

}

static int dsa_pub_encode(X509_PUBKEY *pk, EVP_PKEY *pkey)
{
DSA *dsa;
void *pval;
int ptype;
unsigned char *penc = NULL;
int penclen;

dsa=pkey->pkey.dsa;
if (pkey->save_parameters)
{
ASN1_STRING *str;
str = ASN1_STRING_new();
str->length = i2d_DSAparams(dsa, &str->data);
if (str->length <= 0)
{
DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
goto err;
}
ptype = V_ASN1_SEQUENCE;
}
else
{
ptype = V_ASN1_UNDEF;
pval = NULL;
}
dsa->write_params=0;

penclen = i2d_DSAPublicKey(dsa, &penc);

if (penclen <= 0)
{
DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
goto err;
}

if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
ptype, pval, penc, penclen))
return 1;

err:
if (penc)
OPENSSL_free(penc);
if (pval)
ASN1_STRING_free(pval);

return 0;
}

/* In PKCS#8 DSA: you just get a private key integer and parameters in the
* AlgorithmIdentifier the pubkey must be recalculated.
*/

static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
{
const unsigned char *p, *pm;
int pklen, pmlen;
int ptype;
void *pval;
ASN1_STRING *pstr;
X509_ALGOR *palg;
ASN1_INTEGER *privkey = NULL;
BN_CTX *ctx = NULL;

STACK_OF(ASN1_TYPE) *ndsa = NULL;
DSA *dsa = NULL;

if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
return 0;
X509_ALGOR_get0(NULL, &ptype, &pval, palg);

/* Check for broken DSA PKCS#8, UGH! */
if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
{
ASN1_TYPE *t1, *t2;
if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pklen,
d2i_ASN1_TYPE,
ASN1_TYPE_free)))
goto decerr;
if (sk_ASN1_TYPE_num(ndsa) != 2)
goto decerr;
/* Handle Two broken types:
* SEQUENCE {parameters, priv_key}
* SEQUENCE {pub_key, priv_key}
*/

t1 = sk_ASN1_TYPE_value(ndsa, 0);
t2 = sk_ASN1_TYPE_value(ndsa, 1);
if (t1->type == V_ASN1_SEQUENCE)
{
p8->broken = PKCS8_EMBEDDED_PARAM;
pval = t1->value.ptr;
}
else if (ptype == V_ASN1_SEQUENCE)
p8->broken = PKCS8_NS_DB;
else
goto decerr;

if (t2->type != V_ASN1_INTEGER)
goto decerr;

privkey = t2->value.integer;
}
else
{
if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
goto decerr;
if (ptype != V_ASN1_SEQUENCE)
goto decerr;
}

pstr = pval;
pm = pstr->data;
pmlen = pstr->length;
if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
goto decerr;
/* We have parameters now set private key */
if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
{
DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
goto dsaerr;
}
/* Calculate public key */
if (!(dsa->pub_key = BN_new()))
{
DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
goto dsaerr;
}
if (!(ctx = BN_CTX_new()))
{
DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
goto dsaerr;
}

if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx))
{
DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
goto dsaerr;
}

EVP_PKEY_assign_DSA(pkey, dsa);
BN_CTX_free (ctx);
if(ndsa)
sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
else
ASN1_INTEGER_free(privkey);

return 1;

decerr:
DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR);
dsaerr:
BN_CTX_free (ctx);
sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
DSA_free(dsa);
EVP_PKEY_free(pkey);
return 0;
}

static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
{
ASN1_STRING *params = NULL;
ASN1_INTEGER *prkey = NULL;
unsigned char *dp = NULL;
int dplen;

params = ASN1_STRING_new();

if (!params)
{
DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
goto err;
}

params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
if (params->length <= 0)
{
DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
goto err;
}
params->type = V_ASN1_SEQUENCE;

/* Get private key into integer */
prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);

if (!prkey)
{
DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_BN_ERROR);
goto err;
}

dplen = i2d_ASN1_INTEGER(prkey, &dp);

ASN1_INTEGER_free(prkey);

if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
V_ASN1_SEQUENCE, params, dp, dplen))
goto err;

return 1;

err:
if (dp != NULL)
OPENSSL_free(dp);
if (params != NULL)
ASN1_STRING_free(params);
if (prkey != NULL)
ASN1_INTEGER_free(prkey);
return 0;
}

/* NB these are sorted in pkey_id order, lowest first */

const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
{

{
EVP_PKEY_DSA2,
EVP_PKEY_DSA,
ASN1_PKEY_ALIAS
},

{
EVP_PKEY_DSA1,
EVP_PKEY_DSA,
ASN1_PKEY_ALIAS
},

{
EVP_PKEY_DSA4,
EVP_PKEY_DSA,
ASN1_PKEY_ALIAS
},

{
EVP_PKEY_DSA3,
EVP_PKEY_DSA,
ASN1_PKEY_ALIAS
},

{
EVP_PKEY_DSA,
EVP_PKEY_DSA,
0,
dsa_pub_decode,
dsa_pub_encode,
0,
dsa_priv_decode,
dsa_priv_encode,
0,
0,
0
}
};

@@ -78,6 +78,10 @@ static ERR_STRING_DATA DSA_str_functs[]=
{ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"},
{ERR_FUNC(DSA_F_DSA_PRINT), "DSA_print"},
{ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"},
{ERR_FUNC(DSA_F_DSA_PRIV_DECODE), "DSA_PRIV_DECODE"},
{ERR_FUNC(DSA_F_DSA_PRIV_ENCODE), "DSA_PRIV_ENCODE"},
{ERR_FUNC(DSA_F_DSA_PUB_DECODE), "DSA_PUB_DECODE"},
{ERR_FUNC(DSA_F_DSA_PUB_ENCODE), "DSA_PUB_ENCODE"},
{ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"},
{ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"},
{ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"},
@@ -89,8 +93,12 @@ static ERR_STRING_DATA DSA_str_functs[]=

static ERR_STRING_DATA DSA_str_reasons[]=
{
{ERR_REASON(DSA_R_BN_DECODE_ERROR) ,"bn decode error"},
{ERR_REASON(DSA_R_BN_ERROR) ,"bn error"},
{ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
{ERR_REASON(DSA_R_DECODE_ERROR) ,"decode error"},
{ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"},
{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
{0,NULL}
};

@@ -19,11 +19,11 @@ APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC= ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c\
ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c\
ec2_smpl.c ec2_mult.c
ec2_smpl.c ec2_mult.c ec_ameth.c

LIBOBJ= ec_lib.o ecp_smpl.o ecp_mont.o ecp_nist.o ec_cvt.o ec_mult.o\
ec_err.o ec_curve.o ec_check.o ec_print.o ec_asn1.o ec_key.o\
ec2_smpl.o ec2_mult.o
ec2_smpl.o ec2_mult.o ec_ameth.o

SRC= $(LIBSRC)

@@ -918,6 +918,12 @@ void ERR_load_EC_strings(void);
#define EC_F_D2I_ECPARAMETERS 144
#define EC_F_D2I_ECPKPARAMETERS 145
#define EC_F_D2I_ECPRIVATEKEY 146
#define EC_F_ECKEY_PARAM2TYPE 211
#define EC_F_ECKEY_PRIV_DECODE 212
#define EC_F_ECKEY_PRIV_ENCODE 213
#define EC_F_ECKEY_PUB_DECODE 214
#define EC_F_ECKEY_PUB_ENCODE 215
#define EC_F_ECKEY_TYPE2PARAM 216
#define EC_F_ECPARAMETERS_PRINT 147
#define EC_F_ECPARAMETERS_PRINT_FP 148
#define EC_F_ECPKPARAMETERS_PRINT 149
@@ -1027,6 +1033,7 @@ void ERR_load_EC_strings(void);
#define EC_R_ASN1_UNKNOWN_FIELD 116
#define EC_R_BUFFER_TOO_SMALL 100
#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
#define EC_R_DECODE_ERROR 137
#define EC_R_DISCRIMINANT_IS_ZERO 118
#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
@@ -0,0 +1,360 @@
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
* project 2006.
*/
/* ====================================================================
* Copyright (c) 2005 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/x509.h>
#include <openssl/ec.h>

static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
{
const EC_GROUP *group;
int nid;
if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL)
{
ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
return 0;
}
if (EC_GROUP_get_asn1_flag(group)
&& (nid = EC_GROUP_get_curve_name(group)))
/* we have a 'named curve' => just set the OID */
{
*ppval = OBJ_nid2obj(nid);
*pptype = V_ASN1_OBJECT;
}
else /* explicit parameters */
{
ASN1_STRING *pstr = NULL;
pstr = ASN1_STRING_new();
if (!pstr)
return 0;
pstr->length = i2d_ECParameters(ec_key, &pstr->data);
if (pstr->length < 0)
{
ASN1_STRING_free(pstr);
ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
return 0;
}
*ppval = pstr;
*pptype = V_ASN1_SEQUENCE;
}
return 1;
}

static int eckey_pub_encode(X509_PUBKEY *pk, EVP_PKEY *pkey)
{
EC_KEY *ec_key = pkey->pkey.ec;
void *pval = NULL;
int ptype;
unsigned char *penc = NULL, *p;
int penclen;

if (!eckey_param2type(&ptype, &pval, ec_key))
{
ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
return 0;
}
penclen = i2o_ECPublicKey(ec_key, NULL);
if (penclen <= 0)
goto err;
penc = OPENSSL_malloc(penclen);
if (!penc)
goto err;
p = penc;
penclen = i2o_ECPublicKey(ec_key, &p);
if (penclen <= 0)
goto err;
if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
ptype, pval, penc, penclen))
return 1;
err:
if (ptype == V_ASN1_OBJECT)
ASN1_OBJECT_free(pval);
else
ASN1_STRING_free(pval);
if (penc)
OPENSSL_free(penc);
return 0;
}

static EC_KEY *eckey_type2param(int ptype, void *pval)
{
EC_KEY *eckey = NULL;
if (ptype == V_ASN1_SEQUENCE)
{
ASN1_STRING *pstr = pval;
const unsigned char *pm = NULL;
int pmlen;
pm = pstr->data;
pmlen = pstr->length;
if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen)))
{
ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
goto ecerr;
}
}
else if (ptype == V_ASN1_OBJECT)
{
ASN1_OBJECT *poid = pval;
EC_GROUP *group;

/* type == V_ASN1_OBJECT => the parameters are given
* by an asn1 OID
*/
if ((eckey = EC_KEY_new()) == NULL)
{
ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
goto ecerr;
}
group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
if (group == NULL)
goto ecerr;
EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
if (EC_KEY_set_group(eckey, group) == 0)
goto ecerr;
EC_GROUP_free(group);
}
else
{
ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
goto ecerr;
}

return eckey;

ecerr:
if (eckey)
EC_KEY_free(eckey);
return NULL;
}

static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
{
const unsigned char *p = NULL;
void *pval;
int ptype, pklen;
EC_KEY *eckey = NULL;
X509_ALGOR *palg;

if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
return 0;
X509_ALGOR_get0(NULL, &ptype, &pval, palg);

eckey = eckey_type2param(ptype, pval);

if (!eckey)
{
ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
return 0;
}

/* We have parameters now set public key */
if (!o2i_ECPublicKey(&eckey, &p, pklen))
{
ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
goto ecerr;
}

EVP_PKEY_assign_EC_KEY(pkey, eckey);
return 1;

ecerr:
if (eckey)
EC_KEY_free(eckey);
return 0;
}

static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
{
const unsigned char *p = NULL;
void *pval;
int ptype, pklen;
EC_KEY *eckey = NULL;
X509_ALGOR *palg;

if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
return 0;
X509_ALGOR_get0(NULL, &ptype, &pval, palg);

eckey = eckey_type2param(ptype, pval);

if (!eckey)
goto ecliberr;

/* We have parameters now set private key */
if (!d2i_ECPrivateKey(&eckey, &p, pklen))
{
ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
goto ecerr;
}

/* calculate public key (if necessary) */
if (EC_KEY_get0_public_key(eckey) == NULL)
{
const BIGNUM *priv_key;
const EC_GROUP *group;
EC_POINT *pub_key;
/* the public key was not included in the SEC1 private
* key => calculate the public key */
group = EC_KEY_get0_group(eckey);
pub_key = EC_POINT_new(group);
if (pub_key == NULL)
{
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
goto ecliberr;
}
if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
{
EC_POINT_free(pub_key);
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
goto ecliberr;
}
priv_key = EC_KEY_get0_private_key(eckey);
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL))
{
EC_POINT_free(pub_key);
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
goto ecliberr;
}
if (EC_KEY_set_public_key(eckey, pub_key) == 0)
{
EC_POINT_free(pub_key);
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
goto ecliberr;
}
EC_POINT_free(pub_key);
}

EVP_PKEY_assign_EC_KEY(pkey, eckey);
return 1;

ecliberr:
ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
ecerr:
if (eckey)
EC_KEY_free(eckey);
return 0;
}

static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
{
EC_KEY *ec_key;
unsigned char *ep, *p;
int eplen, ptype;
void *pval;
unsigned int tmp_flags, old_flags;

ec_key = pkey->pkey.ec;

if (!eckey_param2type(&ptype, &pval, ec_key))
{
ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
return 0;
}

/* set the private key */

/* do not include the parameters in the SEC1 private key
* see PKCS#11 12.11 */
old_flags = EC_KEY_get_enc_flags(ec_key);
tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
EC_KEY_set_enc_flags(ec_key, tmp_flags);
eplen = i2d_ECPrivateKey(ec_key, NULL);
if (!eplen)
{
EC_KEY_set_enc_flags(ec_key, old_flags);
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
return 0;
}
ep = (unsigned char *) OPENSSL_malloc(eplen);
if (!ep)
{
EC_KEY_set_enc_flags(ec_key, old_flags);
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
return 0;
}
p = ep;
if (!i2d_ECPrivateKey(ec_key, &p))
{
EC_KEY_set_enc_flags(ec_key, old_flags);
OPENSSL_free(ep);
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
}
/* restore old encoding flags */
EC_KEY_set_enc_flags(ec_key, old_flags);

if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
ptype, pval, ep, eplen))
return 0;

return 1;
}

EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
{
EVP_PKEY_EC,
0,
0,
eckey_pub_decode,
eckey_pub_encode,
0,
eckey_priv_decode,
eckey_priv_encode,
0,
0,
0
};
@@ -847,6 +847,8 @@ int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
EVP_PBE_KEYGEN *keygen);
void EVP_PBE_cleanup(void);

const EVP_PKEY_ASN1_METHOD *EVP_PKEY_ASN1_find(int type);

/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
@@ -873,6 +875,7 @@ void ERR_load_EVP_strings(void);
#define EVP_F_EVP_PBE_ALG_ADD 115
#define EVP_F_EVP_PBE_CIPHERINIT 116
#define EVP_F_EVP_PKCS82PKEY 111
#define EVP_F_EVP_PKCS82PKEY_BROKEN 136
#define EVP_F_EVP_PKEY2PKCS8_BROKEN 113
#define EVP_F_EVP_PKEY_COPY_PARAMETERS 103
#define EVP_F_EVP_PKEY_DECRYPT 104
@@ -918,13 +921,16 @@ void ERR_load_EVP_strings(void);
#define EVP_R_INVALID_KEY_LENGTH 130
#define EVP_R_IV_TOO_LARGE 102
#define EVP_R_KEYGEN_FAILURE 120
#define EVP_R_METHOD_NOT_SUPPORTED 144
#define EVP_R_MISSING_PARAMETERS 103
#define EVP_R_NO_CIPHER_SET 131
#define EVP_R_NO_DIGEST_SET 139
#define EVP_R_NO_DSA_PARAMETERS 116
#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104
#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105
#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117
#define EVP_R_PRIVATE_KEY_DECODE_ERROR 145
#define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146
#define EVP_R_PUBLIC_KEY_NOT_RSA 106
#define EVP_R_UNKNOWN_PBE_ALGORITHM 121
#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135
@@ -87,6 +87,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
{ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"},
{ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"},
{ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"},
{ERR_FUNC(EVP_F_EVP_PKCS82PKEY_BROKEN), "EVP_PKCS82PKEY_BROKEN"},
{ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN), "EVP_PKEY2PKCS8_broken"},
{ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"},
{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"},
@@ -135,13 +136,16 @@ static ERR_STRING_DATA EVP_str_reasons[]=
{ERR_REASON(EVP_R_INVALID_KEY_LENGTH) ,"invalid key length"},
{ERR_REASON(EVP_R_IV_TOO_LARGE) ,"iv too large"},
{ERR_REASON(EVP_R_KEYGEN_FAILURE) ,"keygen failure"},
{ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED) ,"method not supported"},
{ERR_REASON(EVP_R_MISSING_PARAMETERS) ,"missing parameters"},
{ERR_REASON(EVP_R_NO_CIPHER_SET) ,"no cipher set"},
{ERR_REASON(EVP_R_NO_DIGEST_SET) ,"no digest set"},
{ERR_REASON(EVP_R_NO_DSA_PARAMETERS) ,"no dsa parameters"},
{ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED),"no sign function configured"},
{ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"},
{ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),"pkcs8 unknown broken type"},
{ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR),"private key decode error"},
{ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR),"private key encode error"},
{ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"},
{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},

Large diffs are not rendered by default.

@@ -121,6 +121,8 @@ typedef struct env_md_st EVP_MD;
typedef struct env_md_ctx_st EVP_MD_CTX;
typedef struct evp_pkey_st EVP_PKEY;

typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;

typedef struct dh_st DH;
typedef struct dh_method DH_METHOD;

@@ -139,9 +141,12 @@ typedef struct x509_st X509;
typedef struct X509_algor_st X509_ALGOR;
typedef struct X509_crl_st X509_CRL;
typedef struct X509_name_st X509_NAME;
typedef struct X509_pubkey_st X509_PUBKEY;
typedef struct x509_store_st X509_STORE;
typedef struct x509_store_ctx_st X509_STORE_CTX;

typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;

typedef struct v3_ext_ctx X509V3_CTX;
typedef struct conf_st CONF;

@@ -19,10 +19,10 @@ APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC= rsa_eay.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_saos.c rsa_err.c \
rsa_pk1.c rsa_ssl.c rsa_none.c rsa_oaep.c rsa_chk.c rsa_null.c \
rsa_pss.c rsa_x931.c rsa_asn1.c rsa_depr.c
rsa_pss.c rsa_x931.c rsa_asn1.c rsa_depr.c rsa_ameth.c
LIBOBJ= rsa_eay.o rsa_gen.o rsa_lib.o rsa_sign.o rsa_saos.o rsa_err.o \
rsa_pk1.o rsa_ssl.o rsa_none.o rsa_oaep.o rsa_chk.o rsa_null.o \
rsa_pss.o rsa_x931.o rsa_asn1.o rsa_depr.o
rsa_pss.o rsa_x931.o rsa_asn1.o rsa_depr.o rsa_ameth.o

SRC= $(LIBSRC)

@@ -374,6 +374,9 @@ void ERR_load_RSA_strings(void);
#define RSA_F_RSA_PADDING_CHECK_X931 128
#define RSA_F_RSA_PRINT 115
#define RSA_F_RSA_PRINT_FP 116
#define RSA_F_RSA_PRIV_DECODE 137
#define RSA_F_RSA_PRIV_ENCODE 138
#define RSA_F_RSA_PUB_DECODE 139
#define RSA_F_RSA_SETUP_BLINDING 136
#define RSA_F_RSA_SIGN 117
#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118
@@ -0,0 +1,154 @@
/* 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/rsa.h>

static int rsa_pub_encode(X509_PUBKEY *pk, EVP_PKEY *pkey)
{
unsigned char *penc = NULL;
int penclen;
penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc);
if (penclen <= 0)
return 0;
if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA),
V_ASN1_NULL, NULL, penc, penclen))
return 1;

OPENSSL_free(penc);
return 0;
}

static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
{
const unsigned char *p;
int pklen;
RSA *rsa = NULL;
if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey))
return 0;
if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen)))
{
RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB);
return 0;
}
EVP_PKEY_assign_RSA (pkey, rsa);
return 1;
}

static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
{
const unsigned char *p;
int pklen;
RSA *rsa = NULL;
if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
return 0;
if (!(rsa = d2i_RSAPrivateKey (NULL, &p, pklen)))
{
RSAerr(RSA_F_RSA_PRIV_DECODE, ERR_R_RSA_LIB);
return 0;
}
EVP_PKEY_assign_RSA (pkey, rsa);
return 1;
}

static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
{
unsigned char *rk = NULL;
int rklen;
rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk);

if (rklen <= 0)
{
RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
return 0;
}

if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0,
V_ASN1_NULL, NULL, rk, rklen))
{
RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
return 0;
}

return 1;
}

const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
{
{
EVP_PKEY_RSA,
EVP_PKEY_RSA,
0,
rsa_pub_decode,
rsa_pub_encode,
0,
rsa_priv_decode,
rsa_priv_encode,
0,
0,
0
},

{
EVP_PKEY_RSA2,
EVP_PKEY_RSA,
ASN1_PKEY_ALIAS
}
};
@@ -88,7 +88,7 @@ static ERR_STRING_DATA RSA_str_functs[]=
{ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_ENCRYPT), "RSA_NULL_PUBLIC_ENCRYPT"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE), "RSA_padding_add_none"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP), "RSA_padding_add_PKCS1_OAEP"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS), "RSA_PADDING_ADD_PKCS1_PSS"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS), "RSA_padding_add_PKCS1_PSS"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1), "RSA_padding_add_PKCS1_type_1"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2), "RSA_padding_add_PKCS1_type_2"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23), "RSA_padding_add_SSLv23"},
@@ -101,12 +101,15 @@ static ERR_STRING_DATA RSA_str_functs[]=
{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"},
{ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"},
{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
{ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"},
{ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"},
{ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"},
{ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"},
{ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"},
{ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"},
{ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"},
{ERR_FUNC(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING), "RSA_verify_ASN1_OCTET_STRING"},
{ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS), "RSA_VERIFY_PKCS1_PSS"},
{ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS), "RSA_verify_PKCS1_PSS"},
{0,NULL}
};

@@ -141,17 +144,17 @@ static ERR_STRING_DATA RSA_str_reasons[]=
{ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"},
{ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q) ,"n does not equal p q"},
{ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"},
{ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED) ,"salt length recovery failed"},
{ERR_REASON(RSA_R_PADDING_CHECK_FAILED) ,"padding check failed"},
{ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"},
{ERR_REASON(RSA_R_Q_NOT_PRIME) ,"q not prime"},
{ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED),"rsa operations not supported"},
{ERR_REASON(RSA_R_SLEN_CHECK_FAILED) ,"salt length check failed"},
{ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED) ,"salt length recovery failed"},
{ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK) ,"sslv3 rollback attack"},
{ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
{ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
{ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE) ,"unknown padding type"},
{ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
{ERR_REASON(RSA_R_SLEN_CHECK_FAILED) ,"salt length check failed"},
{0,NULL}
};

@@ -155,12 +155,12 @@ typedef struct X509_val_st
ASN1_TIME *notAfter;
} X509_VAL;

typedef struct X509_pubkey_st
struct X509_pubkey_st
{
X509_ALGOR *algor;
ASN1_BIT_STRING *public_key;
EVP_PKEY *pkey;
} X509_PUBKEY;
};

typedef struct X509_sig_st
{
@@ -545,7 +545,7 @@ X509_ALGOR *prf;

/* PKCS#8 private key info structure */

typedef struct pkcs8_priv_key_info_st
struct pkcs8_priv_key_info_st
{
int broken; /* Flag for various broken formats */
#define PKCS8_OK 0
@@ -556,7 +556,7 @@ typedef struct pkcs8_priv_key_info_st
X509_ALGOR *pkeyalg;
ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
STACK_OF(X509_ATTRIBUTE) *attributes;
} PKCS8_PRIV_KEY_INFO;
};

#ifdef __cplusplus
}
@@ -859,6 +859,10 @@ X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
X509_CRL *X509_CRL_dup(X509_CRL *crl);
X509_REQ *X509_REQ_dup(X509_REQ *req);
X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval);
void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
X509_ALGOR *algor);

X509_NAME *X509_NAME_dup(X509_NAME *xn);
X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);

@@ -1244,6 +1248,22 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);

int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
int version, int ptype, void *pval,
unsigned char *penc, int penclen);
int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
const unsigned char **pk, int *ppklen,
X509_ALGOR **pa,
PKCS8_PRIV_KEY_INFO *p8);

int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
int ptype, void *pval,
unsigned char *penc, int penclen);
int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
const unsigned char **pk, int *ppklen,
X509_ALGOR **pa,
X509_PUBKEY *pub);

int X509_check_trust(X509 *x, int id, int flags);
int X509_TRUST_get_count(void);
X509_TRUST * X509_TRUST_get0(int idx);
@@ -1323,7 +1343,10 @@ void ERR_load_X509_strings(void);
#define X509_R_KEY_VALUES_MISMATCH 116
#define X509_R_LOADING_CERT_DIR 103
#define X509_R_LOADING_DEFAULTS 104
#define X509_R_METHOD_NOT_SUPPORTED 124
#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105
#define X509_R_PUBLIC_KEY_DECODE_ERROR 125
#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126
#define X509_R_SHOULD_RETRY 106
#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107
#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108
@@ -132,7 +132,10 @@ static ERR_STRING_DATA X509_str_reasons[]=
{ERR_REASON(X509_R_KEY_VALUES_MISMATCH) ,"key values mismatch"},
{ERR_REASON(X509_R_LOADING_CERT_DIR) ,"loading cert dir"},
{ERR_REASON(X509_R_LOADING_DEFAULTS) ,"loading defaults"},
{ERR_REASON(X509_R_METHOD_NOT_SUPPORTED) ,"method not supported"},
{ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),"no cert set for us to verify"},
{ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR),"public key decode error"},
{ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR),"public key encode error"},
{ERR_REASON(X509_R_SHOULD_RETRY) ,"should retry"},
{ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),"unable to find parameters in chain"},
{ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),"unable to get certs public key"},