| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| } | ||
| }; | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| } | ||
| }; |