mirror of
https://github.com/QuasarApp/openssl.git
synced 2025-04-28 18:54:36 +00:00
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.
This commit is contained in:
parent
1a5a1a93f6
commit
448be74335
8
CHANGES
8
CHANGES
@ -4,6 +4,14 @@
|
|||||||
|
|
||||||
Changes between 0.9.8a and 0.9.9 [xx XXX xxxx]
|
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
|
*) Implement the Supported Point Formats Extension for
|
||||||
ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
|
ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
|
||||||
[Douglas Stebila]
|
[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\
|
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 \
|
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_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_int.c f_string.c n_pkey.c \
|
||||||
f_enum.c x_pkey.c a_bool.c x_exten.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 \
|
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 \
|
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 \
|
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_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_int.o f_string.o n_pkey.o \
|
||||||
f_enum.o x_pkey.o a_bool.o x_exten.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 \
|
asn1_gen.o asn1_par.o asn1_lib.o asn1_err.o a_bytes.o a_strnid.o \
|
||||||
|
113
crypto/asn1/ameth_lib.c
Normal file
113
crypto/asn1/ameth_lib.c
Normal file
@ -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 */
|
/* This is just an opaque pointer */
|
||||||
typedef struct ASN1_VALUE_st ASN1_VALUE;
|
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 */
|
/* Declare ASN1 functions: the implement macro in in asn1t.h */
|
||||||
|
|
||||||
#define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)
|
#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)
|
} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
|
||||||
|
|
||||||
IMPLEMENT_ASN1_FUNCTIONS(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_STACK_OF(X509_ALGOR)
|
||||||
IMPLEMENT_ASN1_SET_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -89,169 +89,45 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
|
|||||||
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
|
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
|
||||||
{
|
{
|
||||||
X509_PUBKEY *pk=NULL;
|
X509_PUBKEY *pk=NULL;
|
||||||
X509_ALGOR *a;
|
const EVP_PKEY_ASN1_METHOD *meth;
|
||||||
ASN1_OBJECT *o;
|
|
||||||
unsigned char *s,*p = NULL;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (x == NULL) return(0);
|
if (x == NULL) return(0);
|
||||||
|
|
||||||
if ((pk=X509_PUBKEY_new()) == NULL) goto err;
|
if ((pk=X509_PUBKEY_new()) == NULL) goto error;
|
||||||
a=pk->algor;
|
|
||||||
|
|
||||||
/* set the algorithm id */
|
meth = EVP_PKEY_ASN1_find(pkey->type);
|
||||||
if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
|
|
||||||
ASN1_OBJECT_free(a->algorithm);
|
|
||||||
a->algorithm=o;
|
|
||||||
|
|
||||||
/* Set the parameter list */
|
if (meth)
|
||||||
if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA))
|
|
||||||
{
|
{
|
||||||
if ((a->parameter == NULL) ||
|
if (meth->pub_encode)
|
||||||
(a->parameter->type != V_ASN1_NULL))
|
|
||||||
{
|
{
|
||||||
ASN1_TYPE_free(a->parameter);
|
if (!meth->pub_encode(pk, pkey))
|
||||||
if (!(a->parameter=ASN1_TYPE_new()))
|
|
||||||
{
|
{
|
||||||
X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
|
X509err(X509_F_X509_PUBKEY_SET,
|
||||||
goto err;
|
X509_R_PUBLIC_KEY_ENCODE_ERROR);
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
a->parameter->type=V_ASN1_NULL;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
X509err(X509_F_X509_PUBKEY_SET,
|
||||||
|
X509_R_METHOD_NOT_SUPPORTED);
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef OPENSSL_NO_DSA
|
else
|
||||||
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)))
|
|
||||||
{
|
|
||||||
/* 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)
|
|
||||||
{
|
{
|
||||||
X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
|
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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
/* 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)
|
if (*x != NULL)
|
||||||
X509_PUBKEY_free(*x);
|
X509_PUBKEY_free(*x);
|
||||||
|
|
||||||
*x=pk;
|
*x=pk;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
err:
|
error:
|
||||||
if (pk != NULL) X509_PUBKEY_free(pk);
|
if (pk != NULL) X509_PUBKEY_free(pk);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -259,119 +135,56 @@ err:
|
|||||||
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
|
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
|
||||||
{
|
{
|
||||||
EVP_PKEY *ret=NULL;
|
EVP_PKEY *ret=NULL;
|
||||||
long j;
|
const EVP_PKEY_ASN1_METHOD *meth;
|
||||||
int type;
|
|
||||||
const 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)
|
if (key->pkey != NULL)
|
||||||
{
|
{
|
||||||
CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
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)
|
if ((ret = EVP_PKEY_new()) == NULL)
|
||||||
{
|
{
|
||||||
X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
|
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!) */
|
meth = EVP_PKEY_ASN1_find(OBJ_obj2nid(key->algor->algorithm));
|
||||||
|
|
||||||
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
|
|
||||||
a=key->algor;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (0)
|
if (meth)
|
||||||
;
|
|
||||||
#ifndef OPENSSL_NO_DSA
|
|
||||||
else if (ret->type == EVP_PKEY_DSA)
|
|
||||||
{
|
{
|
||||||
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);
|
X509err(X509_F_X509_PUBKEY_GET,
|
||||||
goto err;
|
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))
|
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT))
|
else
|
||||||
{
|
{
|
||||||
/* type == V_ASN1_OBJECT => the parameters are given
|
X509err(X509_F_X509_PUBKEY_GET,
|
||||||
* by an asn1 OID
|
X509_R_METHOD_NOT_SUPPORTED);
|
||||||
*/
|
goto error;
|
||||||
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
|
else
|
||||||
|
|
||||||
p=key->public_key->data;
|
|
||||||
j=key->public_key->length;
|
|
||||||
if (!d2i_PublicKey(type, &ret, &p, (long)j))
|
|
||||||
{
|
{
|
||||||
X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB);
|
X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM);
|
||||||
goto err;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
key->pkey = ret;
|
key->pkey = ret;
|
||||||
CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
||||||
return(ret);
|
|
||||||
err:
|
return ret;
|
||||||
|
|
||||||
|
error:
|
||||||
if (ret != NULL)
|
if (ret != NULL)
|
||||||
EVP_PKEY_free(ret);
|
EVP_PKEY_free(ret);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@ -530,3 +343,39 @@ int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
LIB=$(TOP)/libcrypto.a
|
||||||
LIBSRC= dsa_gen.c dsa_key.c dsa_lib.c dsa_asn1.c dsa_vrf.c dsa_sign.c \
|
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 \
|
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)
|
SRC= $(LIBSRC)
|
||||||
|
|
||||||
|
@ -262,6 +262,10 @@ void ERR_load_DSA_strings(void);
|
|||||||
#define DSA_F_DSA_NEW_METHOD 103
|
#define DSA_F_DSA_NEW_METHOD 103
|
||||||
#define DSA_F_DSA_PRINT 104
|
#define DSA_F_DSA_PRINT 104
|
||||||
#define DSA_F_DSA_PRINT_FP 105
|
#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 106
|
||||||
#define DSA_F_DSA_SIGN_SETUP 107
|
#define DSA_F_DSA_SIGN_SETUP 107
|
||||||
#define DSA_F_DSA_SIG_NEW 109
|
#define DSA_F_DSA_SIG_NEW 109
|
||||||
@ -270,8 +274,12 @@ void ERR_load_DSA_strings(void);
|
|||||||
#define DSA_F_SIG_CB 114
|
#define DSA_F_SIG_CB 114
|
||||||
|
|
||||||
/* Reason codes. */
|
/* 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_DATA_TOO_LARGE_FOR_KEY_SIZE 100
|
||||||
|
#define DSA_R_DECODE_ERROR 104
|
||||||
#define DSA_R_MISSING_PARAMETERS 101
|
#define DSA_R_MISSING_PARAMETERS 101
|
||||||
|
#define DSA_R_PARAMETER_ENCODING_ERROR 105
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
376
crypto/dsa/dsa_ameth.c
Normal file
376
crypto/dsa/dsa_ameth.c
Normal file
@ -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, ¶ms->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_NEW_METHOD), "DSA_new_method"},
|
||||||
{ERR_FUNC(DSA_F_DSA_PRINT), "DSA_print"},
|
{ERR_FUNC(DSA_F_DSA_PRINT), "DSA_print"},
|
||||||
{ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"},
|
{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), "DSA_sign"},
|
||||||
{ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"},
|
{ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"},
|
||||||
{ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"},
|
{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[]=
|
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_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_MISSING_PARAMETERS) ,"missing parameters"},
|
||||||
|
{ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
|
||||||
{0,NULL}
|
{0,NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,11 +19,11 @@ APPS=
|
|||||||
LIB=$(TOP)/libcrypto.a
|
LIB=$(TOP)/libcrypto.a
|
||||||
LIBSRC= ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c\
|
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\
|
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\
|
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\
|
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)
|
SRC= $(LIBSRC)
|
||||||
|
|
||||||
|
@ -918,6 +918,12 @@ void ERR_load_EC_strings(void);
|
|||||||
#define EC_F_D2I_ECPARAMETERS 144
|
#define EC_F_D2I_ECPARAMETERS 144
|
||||||
#define EC_F_D2I_ECPKPARAMETERS 145
|
#define EC_F_D2I_ECPKPARAMETERS 145
|
||||||
#define EC_F_D2I_ECPRIVATEKEY 146
|
#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 147
|
||||||
#define EC_F_ECPARAMETERS_PRINT_FP 148
|
#define EC_F_ECPARAMETERS_PRINT_FP 148
|
||||||
#define EC_F_ECPKPARAMETERS_PRINT 149
|
#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_ASN1_UNKNOWN_FIELD 116
|
||||||
#define EC_R_BUFFER_TOO_SMALL 100
|
#define EC_R_BUFFER_TOO_SMALL 100
|
||||||
#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
|
#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
|
||||||
|
#define EC_R_DECODE_ERROR 137
|
||||||
#define EC_R_DISCRIMINANT_IS_ZERO 118
|
#define EC_R_DISCRIMINANT_IS_ZERO 118
|
||||||
#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
|
#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
|
||||||
#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
|
#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
|
||||||
|
360
crypto/ec/ec_ameth.c
Normal file
360
crypto/ec/ec_ameth.c
Normal file
@ -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);
|
EVP_PBE_KEYGEN *keygen);
|
||||||
void EVP_PBE_cleanup(void);
|
void EVP_PBE_cleanup(void);
|
||||||
|
|
||||||
|
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_ASN1_find(int type);
|
||||||
|
|
||||||
/* BEGIN ERROR CODES */
|
/* BEGIN ERROR CODES */
|
||||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
/* 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.
|
* 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_ALG_ADD 115
|
||||||
#define EVP_F_EVP_PBE_CIPHERINIT 116
|
#define EVP_F_EVP_PBE_CIPHERINIT 116
|
||||||
#define EVP_F_EVP_PKCS82PKEY 111
|
#define EVP_F_EVP_PKCS82PKEY 111
|
||||||
|
#define EVP_F_EVP_PKCS82PKEY_BROKEN 136
|
||||||
#define EVP_F_EVP_PKEY2PKCS8_BROKEN 113
|
#define EVP_F_EVP_PKEY2PKCS8_BROKEN 113
|
||||||
#define EVP_F_EVP_PKEY_COPY_PARAMETERS 103
|
#define EVP_F_EVP_PKEY_COPY_PARAMETERS 103
|
||||||
#define EVP_F_EVP_PKEY_DECRYPT 104
|
#define EVP_F_EVP_PKEY_DECRYPT 104
|
||||||
@ -918,6 +921,7 @@ void ERR_load_EVP_strings(void);
|
|||||||
#define EVP_R_INVALID_KEY_LENGTH 130
|
#define EVP_R_INVALID_KEY_LENGTH 130
|
||||||
#define EVP_R_IV_TOO_LARGE 102
|
#define EVP_R_IV_TOO_LARGE 102
|
||||||
#define EVP_R_KEYGEN_FAILURE 120
|
#define EVP_R_KEYGEN_FAILURE 120
|
||||||
|
#define EVP_R_METHOD_NOT_SUPPORTED 144
|
||||||
#define EVP_R_MISSING_PARAMETERS 103
|
#define EVP_R_MISSING_PARAMETERS 103
|
||||||
#define EVP_R_NO_CIPHER_SET 131
|
#define EVP_R_NO_CIPHER_SET 131
|
||||||
#define EVP_R_NO_DIGEST_SET 139
|
#define EVP_R_NO_DIGEST_SET 139
|
||||||
@ -925,6 +929,8 @@ void ERR_load_EVP_strings(void);
|
|||||||
#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104
|
#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104
|
||||||
#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105
|
#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105
|
||||||
#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117
|
#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_PUBLIC_KEY_NOT_RSA 106
|
||||||
#define EVP_R_UNKNOWN_PBE_ALGORITHM 121
|
#define EVP_R_UNKNOWN_PBE_ALGORITHM 121
|
||||||
#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135
|
#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_ALG_ADD), "EVP_PBE_alg_add"},
|
||||||
{ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"},
|
{ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"},
|
||||||
{ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"},
|
{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_PKEY2PKCS8_BROKEN), "EVP_PKEY2PKCS8_broken"},
|
||||||
{ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"},
|
{ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"},
|
||||||
{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"},
|
{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"},
|
||||||
@ -135,6 +136,7 @@ static ERR_STRING_DATA EVP_str_reasons[]=
|
|||||||
{ERR_REASON(EVP_R_INVALID_KEY_LENGTH) ,"invalid key length"},
|
{ERR_REASON(EVP_R_INVALID_KEY_LENGTH) ,"invalid key length"},
|
||||||
{ERR_REASON(EVP_R_IV_TOO_LARGE) ,"iv too large"},
|
{ERR_REASON(EVP_R_IV_TOO_LARGE) ,"iv too large"},
|
||||||
{ERR_REASON(EVP_R_KEYGEN_FAILURE) ,"keygen failure"},
|
{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_MISSING_PARAMETERS) ,"missing parameters"},
|
||||||
{ERR_REASON(EVP_R_NO_CIPHER_SET) ,"no cipher set"},
|
{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_DIGEST_SET) ,"no digest set"},
|
||||||
@ -142,6 +144,8 @@ static ERR_STRING_DATA EVP_str_reasons[]=
|
|||||||
{ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED),"no sign function configured"},
|
{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_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"},
|
||||||
{ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),"pkcs8 unknown broken type"},
|
{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_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"},
|
||||||
{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
|
{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
|
||||||
{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
|
{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* project 1999.
|
* project 1999.
|
||||||
*/
|
*/
|
||||||
/* ====================================================================
|
/* ====================================================================
|
||||||
* Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
|
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@ -69,275 +69,57 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_DSA
|
#include "../asn1/asn1_locl.h"
|
||||||
static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
|
|
||||||
#endif
|
|
||||||
#ifndef OPENSSL_NO_EC
|
|
||||||
static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Extract a private key from a PKCS8 structure */
|
/* Extract a private key from a PKCS8 structure */
|
||||||
|
|
||||||
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
|
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
|
||||||
{
|
{
|
||||||
EVP_PKEY *pkey = NULL;
|
EVP_PKEY *pkey = NULL;
|
||||||
#ifndef OPENSSL_NO_RSA
|
ASN1_OBJECT *algoid;
|
||||||
RSA *rsa = NULL;
|
const EVP_PKEY_ASN1_METHOD *meth;
|
||||||
#endif
|
|
||||||
#ifndef OPENSSL_NO_DSA
|
|
||||||
DSA *dsa = NULL;
|
|
||||||
ASN1_TYPE *t1, *t2;
|
|
||||||
ASN1_INTEGER *privkey;
|
|
||||||
STACK_OF(ASN1_TYPE) *ndsa = NULL;
|
|
||||||
#endif
|
|
||||||
#ifndef OPENSSL_NO_EC
|
|
||||||
EC_KEY *eckey = NULL;
|
|
||||||
const unsigned char *p_tmp;
|
|
||||||
#endif
|
|
||||||
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
|
|
||||||
ASN1_TYPE *param = NULL;
|
|
||||||
BN_CTX *ctx = NULL;
|
|
||||||
int plen;
|
|
||||||
#endif
|
|
||||||
X509_ALGOR *a;
|
|
||||||
const unsigned char *p;
|
|
||||||
const unsigned char *cp;
|
|
||||||
int pkeylen;
|
|
||||||
int nid;
|
|
||||||
char obj_tmp[80];
|
char obj_tmp[80];
|
||||||
|
|
||||||
if(p8->pkey->type == V_ASN1_OCTET_STRING) {
|
if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
|
||||||
p8->broken = PKCS8_OK;
|
return NULL;
|
||||||
p = p8->pkey->value.octet_string->data;
|
|
||||||
pkeylen = p8->pkey->value.octet_string->length;
|
|
||||||
} else {
|
|
||||||
p8->broken = PKCS8_NO_OCTET;
|
|
||||||
p = p8->pkey->value.sequence->data;
|
|
||||||
pkeylen = p8->pkey->value.sequence->length;
|
|
||||||
}
|
|
||||||
if (!(pkey = EVP_PKEY_new())) {
|
if (!(pkey = EVP_PKEY_new())) {
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
|
EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
a = p8->pkeyalg;
|
|
||||||
nid = OBJ_obj2nid(a->algorithm);
|
|
||||||
switch(nid)
|
|
||||||
{
|
|
||||||
#ifndef OPENSSL_NO_RSA
|
|
||||||
case NID_rsaEncryption:
|
|
||||||
cp = p;
|
|
||||||
if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) {
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
EVP_PKEY_assign_RSA (pkey, rsa);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifndef OPENSSL_NO_DSA
|
|
||||||
case NID_dsa:
|
|
||||||
/* PKCS#8 DSA is weird: you just get a private key integer
|
|
||||||
* and parameters in the AlgorithmIdentifier the pubkey must
|
|
||||||
* be recalculated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Check for broken DSA PKCS#8, UGH! */
|
|
||||||
if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
|
|
||||||
if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen,
|
|
||||||
d2i_ASN1_TYPE,
|
|
||||||
ASN1_TYPE_free))) {
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
|
||||||
goto dsaerr;
|
|
||||||
}
|
|
||||||
if(sk_ASN1_TYPE_num(ndsa) != 2 ) {
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
|
||||||
goto dsaerr;
|
|
||||||
}
|
|
||||||
/* Handle Two broken types:
|
|
||||||
* SEQUENCE {parameters, priv_key}
|
|
||||||
* SEQUENCE {pub_key, priv_key}
|
|
||||||
*/
|
|
||||||
|
|
||||||
t1 = sk_ASN1_TYPE_value(ndsa, 0);
|
meth = EVP_PKEY_ASN1_find(OBJ_obj2nid(algoid));
|
||||||
t2 = sk_ASN1_TYPE_value(ndsa, 1);
|
|
||||||
if(t1->type == V_ASN1_SEQUENCE) {
|
|
||||||
p8->broken = PKCS8_EMBEDDED_PARAM;
|
|
||||||
param = t1;
|
|
||||||
} else if(a->parameter->type == V_ASN1_SEQUENCE) {
|
|
||||||
p8->broken = PKCS8_NS_DB;
|
|
||||||
param = a->parameter;
|
|
||||||
} else {
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
|
||||||
goto dsaerr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(t2->type != V_ASN1_INTEGER) {
|
if (meth)
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
|
||||||
goto dsaerr;
|
|
||||||
}
|
|
||||||
privkey = t2->value.integer;
|
|
||||||
} else {
|
|
||||||
if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
|
||||||
goto dsaerr;
|
|
||||||
}
|
|
||||||
param = p8->pkeyalg->parameter;
|
|
||||||
}
|
|
||||||
if (!param || (param->type != V_ASN1_SEQUENCE)) {
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
|
||||||
goto dsaerr;
|
|
||||||
}
|
|
||||||
cp = p = param->value.sequence->data;
|
|
||||||
plen = param->value.sequence->length;
|
|
||||||
if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) {
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
|
||||||
goto dsaerr;
|
|
||||||
}
|
|
||||||
/* We have parameters now set private key */
|
|
||||||
if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR);
|
|
||||||
goto dsaerr;
|
|
||||||
}
|
|
||||||
/* Calculate public key (ouch!) */
|
|
||||||
if (!(dsa->pub_key = BN_new())) {
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto dsaerr;
|
|
||||||
}
|
|
||||||
if (!(ctx = BN_CTX_new())) {
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto dsaerr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!BN_mod_exp(dsa->pub_key, dsa->g,
|
|
||||||
dsa->priv_key, dsa->p, ctx)) {
|
|
||||||
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_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);
|
|
||||||
break;
|
|
||||||
dsaerr:
|
|
||||||
BN_CTX_free (ctx);
|
|
||||||
sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
|
|
||||||
DSA_free(dsa);
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
return NULL;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifndef OPENSSL_NO_EC
|
|
||||||
case NID_X9_62_id_ecPublicKey:
|
|
||||||
p_tmp = p;
|
|
||||||
/* extract the ec parameters */
|
|
||||||
param = p8->pkeyalg->parameter;
|
|
||||||
|
|
||||||
if (!param || ((param->type != V_ASN1_SEQUENCE) &&
|
|
||||||
(param->type != V_ASN1_OBJECT)))
|
|
||||||
{
|
{
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
|
if (meth->priv_decode)
|
||||||
goto ecerr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param->type == V_ASN1_SEQUENCE)
|
|
||||||
{
|
|
||||||
cp = p = param->value.sequence->data;
|
|
||||||
plen = param->value.sequence->length;
|
|
||||||
|
|
||||||
if (!(eckey = d2i_ECParameters(NULL, &cp, plen)))
|
|
||||||
{
|
{
|
||||||
|
if (!meth->priv_decode(pkey, p8))
|
||||||
|
{
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY,
|
EVPerr(EVP_F_EVP_PKCS82PKEY,
|
||||||
EVP_R_DECODE_ERROR);
|
EVP_R_PRIVATE_KEY_DECODE_ERROR);
|
||||||
goto ecerr;
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
EC_GROUP *group;
|
|
||||||
cp = p = param->value.object->data;
|
|
||||||
plen = param->value.object->length;
|
|
||||||
|
|
||||||
/* type == V_ASN1_OBJECT => the parameters are given
|
|
||||||
* by an asn1 OID
|
|
||||||
*/
|
|
||||||
if ((eckey = EC_KEY_new()) == NULL)
|
|
||||||
{
|
{
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY,
|
EVPerr(EVP_F_EVP_PKCS82PKEY,
|
||||||
ERR_R_MALLOC_FAILURE);
|
EVP_R_METHOD_NOT_SUPPORTED);
|
||||||
goto ecerr;
|
goto error;
|
||||||
}
|
}
|
||||||
group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
|
|
||||||
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
|
||||||
/* We have parameters now set private key */
|
|
||||||
if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen))
|
|
||||||
{
|
{
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_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)
|
|
||||||
{
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
|
|
||||||
goto ecerr;
|
|
||||||
}
|
|
||||||
if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
|
|
||||||
{
|
|
||||||
EC_POINT_free(pub_key);
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
|
|
||||||
goto ecerr;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
|
|
||||||
goto ecerr;
|
|
||||||
}
|
|
||||||
if (EC_KEY_set_public_key(eckey, pub_key) == 0)
|
|
||||||
{
|
|
||||||
EC_POINT_free(pub_key);
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
|
|
||||||
goto ecerr;
|
|
||||||
}
|
|
||||||
EC_POINT_free(pub_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
EVP_PKEY_assign_EC_KEY(pkey, eckey);
|
|
||||||
break;
|
|
||||||
ecerr:
|
|
||||||
if (eckey)
|
|
||||||
EC_KEY_free(eckey);
|
|
||||||
if (pkey)
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
|
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
|
||||||
if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
|
i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
|
||||||
else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm);
|
|
||||||
ERR_add_error_data(2, "TYPE=", obj_tmp);
|
ERR_add_error_data(2, "TYPE=", obj_tmp);
|
||||||
EVP_PKEY_free (pkey);
|
goto error;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
return pkey;
|
return pkey;
|
||||||
|
|
||||||
|
error:
|
||||||
|
EVP_PKEY_free (pkey);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
|
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
|
||||||
@ -350,65 +132,46 @@ 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 *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
|
||||||
{
|
{
|
||||||
PKCS8_PRIV_KEY_INFO *p8;
|
PKCS8_PRIV_KEY_INFO *p8;
|
||||||
|
const EVP_PKEY_ASN1_METHOD *meth;
|
||||||
|
|
||||||
if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
|
if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
|
||||||
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
|
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
p8->broken = broken;
|
p8->broken = broken;
|
||||||
if (!ASN1_INTEGER_set(p8->version, 0)) {
|
|
||||||
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
|
|
||||||
PKCS8_PRIV_KEY_INFO_free (p8);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) {
|
|
||||||
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
|
|
||||||
PKCS8_PRIV_KEY_INFO_free (p8);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
p8->pkey->type = V_ASN1_OCTET_STRING;
|
|
||||||
switch (EVP_PKEY_type(pkey->type)) {
|
|
||||||
#ifndef OPENSSL_NO_RSA
|
|
||||||
case EVP_PKEY_RSA:
|
|
||||||
|
|
||||||
if(p8->broken == PKCS8_NO_OCTET) p8->pkey->type = V_ASN1_SEQUENCE;
|
meth = EVP_PKEY_ASN1_find(pkey->type);
|
||||||
|
|
||||||
p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
|
if (meth)
|
||||||
p8->pkeyalg->parameter->type = V_ASN1_NULL;
|
|
||||||
if (!ASN1_pack_string_of (EVP_PKEY,pkey, i2d_PrivateKey,
|
|
||||||
&p8->pkey->value.octet_string)) {
|
|
||||||
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
|
|
||||||
PKCS8_PRIV_KEY_INFO_free (p8);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifndef OPENSSL_NO_DSA
|
|
||||||
case EVP_PKEY_DSA:
|
|
||||||
if(!dsa_pkey2pkcs8(p8, pkey)) {
|
|
||||||
PKCS8_PRIV_KEY_INFO_free (p8);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifndef OPENSSL_NO_EC
|
|
||||||
case EVP_PKEY_EC:
|
|
||||||
if (!eckey_pkey2pkcs8(p8, pkey))
|
|
||||||
{
|
{
|
||||||
PKCS8_PRIV_KEY_INFO_free(p8);
|
if (meth->priv_encode)
|
||||||
return(NULL);
|
{
|
||||||
|
if (!meth->priv_encode(p8, pkey))
|
||||||
|
{
|
||||||
|
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
|
||||||
|
EVP_R_PRIVATE_KEY_ENCODE_ERROR);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
|
||||||
|
EVP_R_METHOD_NOT_SUPPORTED);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
|
||||||
|
EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
|
|
||||||
PKCS8_PRIV_KEY_INFO_free (p8);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
RAND_add(p8->pkey->value.octet_string->data,
|
RAND_add(p8->pkey->value.octet_string->data,
|
||||||
p8->pkey->value.octet_string->length, 0.0);
|
p8->pkey->value.octet_string->length, 0.0);
|
||||||
return p8;
|
return p8;
|
||||||
|
error:
|
||||||
|
PKCS8_PRIV_KEY_INFO_free(p8);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
|
PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
|
||||||
@ -432,301 +195,6 @@ PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_DSA
|
|
||||||
static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
|
|
||||||
{
|
|
||||||
ASN1_STRING *params = NULL;
|
|
||||||
ASN1_INTEGER *prkey = NULL;
|
|
||||||
ASN1_TYPE *ttmp = NULL;
|
|
||||||
STACK_OF(ASN1_TYPE) *ndsa = NULL;
|
|
||||||
unsigned char *p = NULL, *q;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
|
|
||||||
len = i2d_DSAparams (pkey->pkey.dsa, NULL);
|
|
||||||
if (!(p = OPENSSL_malloc(len))) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
q = p;
|
|
||||||
i2d_DSAparams (pkey->pkey.dsa, &q);
|
|
||||||
if (!(params = ASN1_STRING_new())) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (!ASN1_STRING_set(params, p, len)) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
OPENSSL_free(p);
|
|
||||||
p = NULL;
|
|
||||||
/* Get private key into integer */
|
|
||||||
if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(p8->broken) {
|
|
||||||
|
|
||||||
case PKCS8_OK:
|
|
||||||
case PKCS8_NO_OCTET:
|
|
||||||
|
|
||||||
if (!ASN1_pack_string_of(ASN1_INTEGER,prkey, i2d_ASN1_INTEGER,
|
|
||||||
&p8->pkey->value.octet_string)) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
M_ASN1_INTEGER_free (prkey);
|
|
||||||
prkey = NULL;
|
|
||||||
p8->pkeyalg->parameter->value.sequence = params;
|
|
||||||
params = NULL;
|
|
||||||
p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PKCS8_NS_DB:
|
|
||||||
|
|
||||||
p8->pkeyalg->parameter->value.sequence = params;
|
|
||||||
params = NULL;
|
|
||||||
p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
|
|
||||||
if (!(ndsa = sk_ASN1_TYPE_new_null())) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (!(ttmp = ASN1_TYPE_new())) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (!(ttmp->value.integer =
|
|
||||||
BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
ttmp->type = V_ASN1_INTEGER;
|
|
||||||
if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(ttmp = ASN1_TYPE_new())) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
ttmp->value.integer = prkey;
|
|
||||||
prkey = NULL;
|
|
||||||
ttmp->type = V_ASN1_INTEGER;
|
|
||||||
if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
ttmp = NULL;
|
|
||||||
|
|
||||||
if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
|
|
||||||
&p8->pkey->value.octet_string->data,
|
|
||||||
&p8->pkey->value.octet_string->length)) {
|
|
||||||
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PKCS8_EMBEDDED_PARAM:
|
|
||||||
|
|
||||||
p8->pkeyalg->parameter->type = V_ASN1_NULL;
|
|
||||||
if (!(ndsa = sk_ASN1_TYPE_new_null())) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (!(ttmp = ASN1_TYPE_new())) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
ttmp->value.sequence = params;
|
|
||||||
params = NULL;
|
|
||||||
ttmp->type = V_ASN1_SEQUENCE;
|
|
||||||
if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(ttmp = ASN1_TYPE_new())) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
ttmp->value.integer = prkey;
|
|
||||||
prkey = NULL;
|
|
||||||
ttmp->type = V_ASN1_INTEGER;
|
|
||||||
if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
ttmp = NULL;
|
|
||||||
|
|
||||||
if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
|
|
||||||
&p8->pkey->value.octet_string->data,
|
|
||||||
&p8->pkey->value.octet_string->length)) {
|
|
||||||
|
|
||||||
EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
err:
|
|
||||||
if (p != NULL) OPENSSL_free(p);
|
|
||||||
if (params != NULL) ASN1_STRING_free(params);
|
|
||||||
if (prkey != NULL) M_ASN1_INTEGER_free(prkey);
|
|
||||||
if (ttmp != NULL) ASN1_TYPE_free(ttmp);
|
|
||||||
if (ndsa != NULL) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_EC
|
|
||||||
static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
|
|
||||||
{
|
|
||||||
EC_KEY *ec_key;
|
|
||||||
const EC_GROUP *group;
|
|
||||||
unsigned char *p, *pp;
|
|
||||||
int nid, i, ret = 0;
|
|
||||||
unsigned int tmp_flags, old_flags;
|
|
||||||
|
|
||||||
ec_key = pkey->pkey.ec;
|
|
||||||
if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL)
|
|
||||||
{
|
|
||||||
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set the ec parameters OID */
|
|
||||||
if (p8->pkeyalg->algorithm)
|
|
||||||
ASN1_OBJECT_free(p8->pkeyalg->algorithm);
|
|
||||||
|
|
||||||
p8->pkeyalg->algorithm = OBJ_nid2obj(NID_X9_62_id_ecPublicKey);
|
|
||||||
|
|
||||||
/* set the ec parameters */
|
|
||||||
|
|
||||||
if (p8->pkeyalg->parameter)
|
|
||||||
{
|
|
||||||
ASN1_TYPE_free(p8->pkeyalg->parameter);
|
|
||||||
p8->pkeyalg->parameter = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((p8->pkeyalg->parameter = ASN1_TYPE_new()) == NULL)
|
|
||||||
{
|
|
||||||
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
|
|
||||||
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 */
|
|
||||||
p8->pkeyalg->parameter->type = V_ASN1_OBJECT;
|
|
||||||
p8->pkeyalg->parameter->value.object = OBJ_nid2obj(nid);
|
|
||||||
}
|
|
||||||
else /* explicit parameters */
|
|
||||||
{
|
|
||||||
if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
|
|
||||||
{
|
|
||||||
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
|
|
||||||
{
|
|
||||||
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pp = p;
|
|
||||||
if (!i2d_ECParameters(ec_key, &pp))
|
|
||||||
{
|
|
||||||
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
|
|
||||||
OPENSSL_free(p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
|
|
||||||
if ((p8->pkeyalg->parameter->value.sequence
|
|
||||||
= ASN1_STRING_new()) == NULL)
|
|
||||||
{
|
|
||||||
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_ASN1_LIB);
|
|
||||||
OPENSSL_free(p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, i);
|
|
||||||
OPENSSL_free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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(pkey->pkey.ec);
|
|
||||||
tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
|
|
||||||
EC_KEY_set_enc_flags(pkey->pkey.ec, tmp_flags);
|
|
||||||
i = i2d_ECPrivateKey(pkey->pkey.ec, NULL);
|
|
||||||
if (!i)
|
|
||||||
{
|
|
||||||
EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
|
|
||||||
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
p = (unsigned char *) OPENSSL_malloc(i);
|
|
||||||
if (!p)
|
|
||||||
{
|
|
||||||
EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
|
|
||||||
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pp = p;
|
|
||||||
if (!i2d_ECPrivateKey(pkey->pkey.ec, &pp))
|
|
||||||
{
|
|
||||||
EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
|
|
||||||
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
|
|
||||||
OPENSSL_free(p);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* restore old encoding flags */
|
|
||||||
EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
|
|
||||||
|
|
||||||
switch(p8->broken) {
|
|
||||||
|
|
||||||
case PKCS8_OK:
|
|
||||||
p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
|
|
||||||
if (!p8->pkey->value.octet_string ||
|
|
||||||
!M_ASN1_OCTET_STRING_set(p8->pkey->value.octet_string,
|
|
||||||
(const void *)p, i))
|
|
||||||
|
|
||||||
{
|
|
||||||
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ret = 1;
|
|
||||||
break;
|
|
||||||
case PKCS8_NO_OCTET: /* RSA specific */
|
|
||||||
case PKCS8_NS_DB: /* DSA specific */
|
|
||||||
case PKCS8_EMBEDDED_PARAM: /* DSA specific */
|
|
||||||
default:
|
|
||||||
EVPerr(EVP_F_ECKEY_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
|
|
||||||
}
|
|
||||||
OPENSSL_cleanse(p, (size_t)i);
|
|
||||||
OPENSSL_free(p);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EVP_PKEY attribute functions */
|
/* EVP_PKEY attribute functions */
|
||||||
|
|
||||||
int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
|
int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
|
||||||
|
@ -121,6 +121,8 @@ typedef struct env_md_st EVP_MD;
|
|||||||
typedef struct env_md_ctx_st EVP_MD_CTX;
|
typedef struct env_md_ctx_st EVP_MD_CTX;
|
||||||
typedef struct evp_pkey_st EVP_PKEY;
|
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_st DH;
|
||||||
typedef struct dh_method DH_METHOD;
|
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_algor_st X509_ALGOR;
|
||||||
typedef struct X509_crl_st X509_CRL;
|
typedef struct X509_crl_st X509_CRL;
|
||||||
typedef struct X509_name_st X509_NAME;
|
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_st X509_STORE;
|
||||||
typedef struct x509_store_ctx_st X509_STORE_CTX;
|
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 v3_ext_ctx X509V3_CTX;
|
||||||
typedef struct conf_st CONF;
|
typedef struct conf_st CONF;
|
||||||
|
|
||||||
|
@ -19,10 +19,10 @@ APPS=
|
|||||||
LIB=$(TOP)/libcrypto.a
|
LIB=$(TOP)/libcrypto.a
|
||||||
LIBSRC= rsa_eay.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_saos.c rsa_err.c \
|
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_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 \
|
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_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)
|
SRC= $(LIBSRC)
|
||||||
|
|
||||||
|
@ -374,6 +374,9 @@ void ERR_load_RSA_strings(void);
|
|||||||
#define RSA_F_RSA_PADDING_CHECK_X931 128
|
#define RSA_F_RSA_PADDING_CHECK_X931 128
|
||||||
#define RSA_F_RSA_PRINT 115
|
#define RSA_F_RSA_PRINT 115
|
||||||
#define RSA_F_RSA_PRINT_FP 116
|
#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_SETUP_BLINDING 136
|
||||||
#define RSA_F_RSA_SIGN 117
|
#define RSA_F_RSA_SIGN 117
|
||||||
#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118
|
#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118
|
||||||
|
154
crypto/rsa/rsa_ameth.c
Normal file
154
crypto/rsa/rsa_ameth.c
Normal file
@ -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_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_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_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_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_PKCS1_TYPE_2), "RSA_padding_add_PKCS1_type_2"},
|
||||||
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23), "RSA_padding_add_SSLv23"},
|
{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_PADDING_CHECK_X931), "RSA_padding_check_X931"},
|
||||||
{ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"},
|
{ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"},
|
||||||
{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
|
{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_SETUP_BLINDING), "RSA_setup_blinding"},
|
||||||
{ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"},
|
{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_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"},
|
||||||
{ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"},
|
{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_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}
|
{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_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_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_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_PADDING_CHECK_FAILED) ,"padding check failed"},
|
||||||
{ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"},
|
{ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"},
|
||||||
{ERR_REASON(RSA_R_Q_NOT_PRIME) ,"q 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_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_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_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_ALGORITHM_TYPE),"unknown algorithm type"},
|
||||||
{ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE) ,"unknown padding 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_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
|
||||||
{ERR_REASON(RSA_R_SLEN_CHECK_FAILED) ,"salt length check failed"},
|
|
||||||
{0,NULL}
|
{0,NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -155,12 +155,12 @@ typedef struct X509_val_st
|
|||||||
ASN1_TIME *notAfter;
|
ASN1_TIME *notAfter;
|
||||||
} X509_VAL;
|
} X509_VAL;
|
||||||
|
|
||||||
typedef struct X509_pubkey_st
|
struct X509_pubkey_st
|
||||||
{
|
{
|
||||||
X509_ALGOR *algor;
|
X509_ALGOR *algor;
|
||||||
ASN1_BIT_STRING *public_key;
|
ASN1_BIT_STRING *public_key;
|
||||||
EVP_PKEY *pkey;
|
EVP_PKEY *pkey;
|
||||||
} X509_PUBKEY;
|
};
|
||||||
|
|
||||||
typedef struct X509_sig_st
|
typedef struct X509_sig_st
|
||||||
{
|
{
|
||||||
@ -545,7 +545,7 @@ X509_ALGOR *prf;
|
|||||||
|
|
||||||
/* PKCS#8 private key info structure */
|
/* 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 */
|
int broken; /* Flag for various broken formats */
|
||||||
#define PKCS8_OK 0
|
#define PKCS8_OK 0
|
||||||
@ -556,7 +556,7 @@ typedef struct pkcs8_priv_key_info_st
|
|||||||
X509_ALGOR *pkeyalg;
|
X509_ALGOR *pkeyalg;
|
||||||
ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
|
ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
|
||||||
STACK_OF(X509_ATTRIBUTE) *attributes;
|
STACK_OF(X509_ATTRIBUTE) *attributes;
|
||||||
} PKCS8_PRIV_KEY_INFO;
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
@ -859,6 +859,10 @@ X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
|
|||||||
X509_CRL *X509_CRL_dup(X509_CRL *crl);
|
X509_CRL *X509_CRL_dup(X509_CRL *crl);
|
||||||
X509_REQ *X509_REQ_dup(X509_REQ *req);
|
X509_REQ *X509_REQ_dup(X509_REQ *req);
|
||||||
X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
|
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 *X509_NAME_dup(X509_NAME *xn);
|
||||||
X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
|
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 *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
|
||||||
PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, 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_check_trust(X509 *x, int id, int flags);
|
||||||
int X509_TRUST_get_count(void);
|
int X509_TRUST_get_count(void);
|
||||||
X509_TRUST * X509_TRUST_get0(int idx);
|
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_KEY_VALUES_MISMATCH 116
|
||||||
#define X509_R_LOADING_CERT_DIR 103
|
#define X509_R_LOADING_CERT_DIR 103
|
||||||
#define X509_R_LOADING_DEFAULTS 104
|
#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_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_SHOULD_RETRY 106
|
||||||
#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107
|
#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107
|
||||||
#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108
|
#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_KEY_VALUES_MISMATCH) ,"key values mismatch"},
|
||||||
{ERR_REASON(X509_R_LOADING_CERT_DIR) ,"loading cert dir"},
|
{ERR_REASON(X509_R_LOADING_CERT_DIR) ,"loading cert dir"},
|
||||||
{ERR_REASON(X509_R_LOADING_DEFAULTS) ,"loading defaults"},
|
{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_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_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_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"},
|
{ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),"unable to get certs public key"},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user