Adding SSL_set_cipher_lists and turning on elliptic curve
Summary:
- adding SSL_set_cipher_lists for JSSE support
- enabling elliptic curve for new JSSE cipher suites
Details:
Adding SSL_set_cipher_lists that allows setting of SSL ciphers (and
indirectly ciphers_by_id). This allows us to explicitly set a desired
cipher suite lists with our own ordering for JSSE support.
patches/jsse.patch
Enabling EC, ECDH, and ECDSA which are needed for RI 6 elliptic curve cipher suites.
- EC = Elliptic Curve
- ECDH = Elliptic Curve Diffie-Hellman
- ECDSA = Elliptic Curve Digital Signature Algorithm
android-config.mk
patches/apps_Android.mk
patches/crypto_Android.mk
openssl.config
Remove warning from openssl output to remove testssl warnings
patches/progs.patch
openssl.config
Misc
Update clean, build, and test instructions
README.android
Fixing whitespace inconsistency noted when updating clean target
patches/ssl_Android.mk
Generated files
Copied from patches:
apps/Android.mk
crypto/Android.mk
ssl/Android.mk
Newly imported EC files from openssl-1.0.0.tar.gz
Interestingly most of the needed files were already present, if not compiled.
crypto/ec/ec_ameth.c
crypto/ec/ec_pmeth.c
crypto/ec/eck_prn.c
SSL_set_cipher_lists
include/openssl/ssl.h
ssl/ssl.h
ssl/ssl_lib.c
Disabled warning
apps/openssl.c
Change-Id: I1d75f64b64e03f7bfb45456876b60ebbf3a09de5
diff --git a/README.android b/README.android
index f6b92c3..6232aa1 100644
--- a/README.android
+++ b/README.android
@@ -38,11 +38,11 @@
5) Cleanup before building with:
- m -j16 clean-openssl clean-libcrypto clean-libssl
+ m -j16 clean-libcrypto clean-libssl clean-openssl clean-ssltest
6) Build openssl from the external/openssl directory with:
- mm -j16
+ mm -j16 snod && adb sync system
If there are build errors, then patches/*.mk, openssl.config, or
android-config.mk may need updating.
diff --git a/android-config.mk b/android-config.mk
index a28e35d..0597a42 100644
--- a/android-config.mk
+++ b/android-config.mk
@@ -11,4 +11,4 @@
LOCAL_CFLAGS += -DOPENSSL_NO_BF -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_CAST -DOPENSSL_NO_CMS -DOPENSSL_NO_GMP -DOPENSSL_NO_IDEA -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SEED -DOPENSSL_NO_STORE -DOPENSSL_NO_WHIRLPOOL
# Extra
-LOCAL_CFLAGS += -DOPENSSL_NO_HW -DOPENSSL_NO_ENGINE -DOPENSSL_NO_EC -DOPENSSL_NO_ECDH -DOPENSSL_NO_ECDSA -DZLIB
+LOCAL_CFLAGS += -DOPENSSL_NO_HW -DOPENSSL_NO_ENGINE -DZLIB
diff --git a/apps/Android.mk b/apps/Android.mk
index a908806..e9f215c 100644
--- a/apps/Android.mk
+++ b/apps/Android.mk
@@ -17,6 +17,7 @@
dsa.c \
dsaparam.c \
ecparam.c \
+ ec.c \
enc.c \
engine.c \
errstr.c \
@@ -64,7 +65,7 @@
# These flags omit whole features from the commandline "openssl".
# However, portions of these features are actually turned on.
-LOCAL_CFLAGS += -DOPENSSL_NO_EC -DOPENSSL_NO_ECDSA -DOPENSSL_NO_DTLS1
+LOCAL_CFLAGS += -DOPENSSL_NO_DTLS1
LOCAL_MODULE:= openssl
diff --git a/apps/openssl.c b/apps/openssl.c
index 851e639..be37ee6 100644
--- a/apps/openssl.c
+++ b/apps/openssl.c
@@ -275,8 +275,10 @@
if (ERR_GET_REASON(ERR_peek_last_error())
== CONF_R_NO_SUCH_FILE)
{
+#if 0 /* ANDROID */
BIO_printf(bio_err,
"WARNING: can't open config file: %s\n",p);
+#endif
ERR_clear_error();
NCONF_free(config);
config = NULL;
diff --git a/crypto/Android.mk b/crypto/Android.mk
index 14bac8e..cb2dfd4 100644
--- a/crypto/Android.mk
+++ b/crypto/Android.mk
@@ -226,6 +226,33 @@
dso/dso_openssl.c \
dso/dso_vms.c \
dso/dso_win32.c \
+ ec/ec2_mult.c \
+ ec/ec2_smpl.c \
+ ec/ec_ameth.c \
+ ec/ec_asn1.c \
+ ec/ec_check.c \
+ ec/ec_curve.c \
+ ec/ec_cvt.c \
+ ec/ec_err.c \
+ ec/ec_key.c \
+ ec/ec_lib.c \
+ ec/ec_mult.c \
+ ec/ec_pmeth.c \
+ ec/ec_print.c \
+ ec/eck_prn.c \
+ ec/ecp_mont.c \
+ ec/ecp_nist.c \
+ ec/ecp_smpl.c \
+ ecdh/ech_err.c \
+ ecdh/ech_key.c \
+ ecdh/ech_lib.c \
+ ecdh/ech_ossl.c \
+ ecdsa/ecs_asn1.c \
+ ecdsa/ecs_err.c \
+ ecdsa/ecs_lib.c \
+ ecdsa/ecs_ossl.c \
+ ecdsa/ecs_sign.c \
+ ecdsa/ecs_vrf.c \
err/err.c \
err/err_all.c \
err/err_prn.c \
@@ -256,6 +283,7 @@
evp/evp_pkey.c \
evp/m_dss.c \
evp/m_dss1.c \
+ evp/m_ecdsa.c \
evp/m_md2.c \
evp/m_md4.c \
evp/m_md5.c \
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
new file mode 100644
index 0000000..c00f7d7
--- /dev/null
+++ b/crypto/ec/ec_ameth.c
@@ -0,0 +1,659 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) 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/ec.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_CMS
+#include <openssl/cms.h>
+#endif
+#include "asn1_locl.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, const 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_EC),
+ 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_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+ {
+ int r;
+ const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
+ const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
+ *pb = EC_KEY_get0_public_key(b->pkey.ec);
+ r = EC_POINT_cmp(group, pa, pb, NULL);
+ if (r == 0)
+ return 1;
+ if (r == 1)
+ return 0;
+ return -2;
+ }
+
+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, const 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;
+}
+
+static int int_ec_size(const EVP_PKEY *pkey)
+ {
+ return ECDSA_size(pkey->pkey.ec);
+ }
+
+static int ec_bits(const EVP_PKEY *pkey)
+ {
+ BIGNUM *order = BN_new();
+ const EC_GROUP *group;
+ int ret;
+
+ if (!order)
+ {
+ ERR_clear_error();
+ return 0;
+ }
+ group = EC_KEY_get0_group(pkey->pkey.ec);
+ if (!EC_GROUP_get_order(group, order, NULL))
+ {
+ ERR_clear_error();
+ return 0;
+ }
+
+ ret = BN_num_bits(order);
+ BN_free(order);
+ return ret;
+ }
+
+static int ec_missing_parameters(const EVP_PKEY *pkey)
+ {
+ if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
+ return 1;
+ return 0;
+ }
+
+static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+ {
+ EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
+ if (group == NULL)
+ return 0;
+ if (EC_KEY_set_group(to->pkey.ec, group) == 0)
+ return 0;
+ EC_GROUP_free(group);
+ return 1;
+ }
+
+static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+ {
+ const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
+ *group_b = EC_KEY_get0_group(b->pkey.ec);
+ if (EC_GROUP_cmp(group_a, group_b, NULL))
+ return 0;
+ else
+ return 1;
+ }
+
+static void int_ec_free(EVP_PKEY *pkey)
+ {
+ EC_KEY_free(pkey->pkey.ec);
+ }
+
+static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
+ {
+ unsigned char *buffer=NULL;
+ const char *ecstr;
+ size_t buf_len=0, i;
+ int ret=0, reason=ERR_R_BIO_LIB;
+ BIGNUM *pub_key=NULL, *order=NULL;
+ BN_CTX *ctx=NULL;
+ const EC_GROUP *group;
+ const EC_POINT *public_key;
+ const BIGNUM *priv_key;
+
+ if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
+ {
+ reason = ERR_R_PASSED_NULL_PARAMETER;
+ goto err;
+ }
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+
+ if (ktype > 0)
+ {
+ public_key = EC_KEY_get0_public_key(x);
+ if ((pub_key = EC_POINT_point2bn(group, public_key,
+ EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
+ {
+ reason = ERR_R_EC_LIB;
+ goto err;
+ }
+ if (pub_key)
+ buf_len = (size_t)BN_num_bytes(pub_key);
+ }
+
+ if (ktype == 2)
+ {
+ priv_key = EC_KEY_get0_private_key(x);
+ if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
+ buf_len = i;
+ }
+ else
+ priv_key = NULL;
+
+ if (ktype > 0)
+ {
+ buf_len += 10;
+ if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
+ {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ }
+ if (ktype == 2)
+ ecstr = "Private-Key";
+ else if (ktype == 1)
+ ecstr = "Public-Key";
+ else
+ ecstr = "ECDSA-Parameters";
+
+ if (!BIO_indent(bp, off, 128))
+ goto err;
+ if ((order = BN_new()) == NULL)
+ goto err;
+ if (!EC_GROUP_get_order(group, order, NULL))
+ goto err;
+ if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
+ BN_num_bits(order)) <= 0) goto err;
+
+ if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
+ buffer, off))
+ goto err;
+ if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
+ buffer, off))
+ goto err;
+ if (!ECPKParameters_print(bp, group, off))
+ goto err;
+ ret=1;
+err:
+ if (!ret)
+ ECerr(EC_F_DO_EC_KEY_PRINT, reason);
+ if (pub_key)
+ BN_free(pub_key);
+ if (order)
+ BN_free(order);
+ if (ctx)
+ BN_CTX_free(ctx);
+ if (buffer != NULL)
+ OPENSSL_free(buffer);
+ return(ret);
+ }
+
+static int eckey_param_decode(EVP_PKEY *pkey,
+ const unsigned char **pder, int derlen)
+ {
+ EC_KEY *eckey;
+ if (!(eckey = d2i_ECParameters(NULL, pder, derlen)))
+ {
+ ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
+ return 0;
+ }
+ EVP_PKEY_assign_EC_KEY(pkey, eckey);
+ return 1;
+ }
+
+static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+ {
+ return i2d_ECParameters(pkey->pkey.ec, pder);
+ }
+
+static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx)
+ {
+ return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
+ }
+
+static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx)
+ {
+ return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
+ }
+
+
+static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx)
+ {
+ return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
+ }
+
+static int old_ec_priv_decode(EVP_PKEY *pkey,
+ const unsigned char **pder, int derlen)
+ {
+ EC_KEY *ec;
+ if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen)))
+ {
+ ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
+ return 0;
+ }
+ EVP_PKEY_assign_EC_KEY(pkey, ec);
+ return 1;
+ }
+
+static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+ {
+ return i2d_ECPrivateKey(pkey->pkey.ec, pder);
+ }
+
+static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+ {
+ switch (op)
+ {
+ case ASN1_PKEY_CTRL_PKCS7_SIGN:
+ if (arg1 == 0)
+ {
+ int snid, hnid;
+ X509_ALGOR *alg1, *alg2;
+ PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
+ if (alg1 == NULL || alg1->algorithm == NULL)
+ return -1;
+ hnid = OBJ_obj2nid(alg1->algorithm);
+ if (hnid == NID_undef)
+ return -1;
+ if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+ return -1;
+ X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+ }
+ return 1;
+#ifndef OPENSSL_NO_CMS
+ case ASN1_PKEY_CTRL_CMS_SIGN:
+ if (arg1 == 0)
+ {
+ int snid, hnid;
+ X509_ALGOR *alg1, *alg2;
+ CMS_SignerInfo_get0_algs(arg2, NULL, NULL,
+ &alg1, &alg2);
+ if (alg1 == NULL || alg1->algorithm == NULL)
+ return -1;
+ hnid = OBJ_obj2nid(alg1->algorithm);
+ if (hnid == NID_undef)
+ return -1;
+ if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+ return -1;
+ X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+ }
+ return 1;
+#endif
+
+ case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+ *(int *)arg2 = NID_sha1;
+ return 2;
+
+ default:
+ return -2;
+
+ }
+
+ }
+
+const EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
+ {
+ EVP_PKEY_EC,
+ EVP_PKEY_EC,
+ 0,
+ "EC",
+ "OpenSSL EC algorithm",
+
+ eckey_pub_decode,
+ eckey_pub_encode,
+ eckey_pub_cmp,
+ eckey_pub_print,
+
+ eckey_priv_decode,
+ eckey_priv_encode,
+ eckey_priv_print,
+
+ int_ec_size,
+ ec_bits,
+
+ eckey_param_decode,
+ eckey_param_encode,
+ ec_missing_parameters,
+ ec_copy_parameters,
+ ec_cmp_parameters,
+ eckey_param_print,
+
+ int_ec_free,
+ ec_pkey_ctrl,
+ old_ec_priv_decode,
+ old_ec_priv_encode
+ };
diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c
new file mode 100644
index 0000000..f433076
--- /dev/null
+++ b/crypto/ec/ec_pmeth.c
@@ -0,0 +1,340 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) 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 <openssl/ecdsa.h>
+#include <openssl/evp.h>
+#include "evp_locl.h"
+
+/* EC pkey context structure */
+
+typedef struct
+ {
+ /* Key and paramgen group */
+ EC_GROUP *gen_group;
+ /* message digest */
+ const EVP_MD *md;
+ } EC_PKEY_CTX;
+
+static int pkey_ec_init(EVP_PKEY_CTX *ctx)
+ {
+ EC_PKEY_CTX *dctx;
+ dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
+ if (!dctx)
+ return 0;
+ dctx->gen_group = NULL;
+ dctx->md = NULL;
+
+ ctx->data = dctx;
+
+ return 1;
+ }
+
+static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+ {
+ EC_PKEY_CTX *dctx, *sctx;
+ if (!pkey_ec_init(dst))
+ return 0;
+ sctx = src->data;
+ dctx = dst->data;
+ if (sctx->gen_group)
+ {
+ dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
+ if (!dctx->gen_group)
+ return 0;
+ }
+ dctx->md = sctx->md;
+ return 1;
+ }
+
+static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
+ {
+ EC_PKEY_CTX *dctx = ctx->data;
+ if (dctx)
+ {
+ if (dctx->gen_group)
+ EC_GROUP_free(dctx->gen_group);
+ OPENSSL_free(dctx);
+ }
+ }
+
+static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen)
+ {
+ int ret, type;
+ unsigned int sltmp;
+ EC_PKEY_CTX *dctx = ctx->data;
+ EC_KEY *ec = ctx->pkey->pkey.ec;
+
+ if (!sig)
+ {
+ *siglen = ECDSA_size(ec);
+ return 1;
+ }
+ else if(*siglen < (size_t)ECDSA_size(ec))
+ {
+ ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ if (dctx->md)
+ type = EVP_MD_type(dctx->md);
+ else
+ type = NID_sha1;
+
+
+ ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
+
+ if (ret <= 0)
+ return ret;
+ *siglen = (size_t)sltmp;
+ return 1;
+ }
+
+static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
+ const unsigned char *sig, size_t siglen,
+ const unsigned char *tbs, size_t tbslen)
+ {
+ int ret, type;
+ EC_PKEY_CTX *dctx = ctx->data;
+ EC_KEY *ec = ctx->pkey->pkey.ec;
+
+ if (dctx->md)
+ type = EVP_MD_type(dctx->md);
+ else
+ type = NID_sha1;
+
+ ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
+
+ return ret;
+ }
+
+static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
+ {
+ int ret;
+ size_t outlen;
+ const EC_POINT *pubkey = NULL;
+ if (!ctx->pkey || !ctx->peerkey)
+ {
+ ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
+ return 0;
+ }
+
+ if (!key)
+ {
+ const EC_GROUP *group;
+ group = EC_KEY_get0_group(ctx->pkey->pkey.ec);
+ *keylen = (EC_GROUP_get_degree(group) + 7)/8;
+ return 1;
+ }
+
+ pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
+
+ /* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is
+ * not an error, the result is truncated.
+ */
+
+ outlen = *keylen;
+
+ ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0);
+ if (ret < 0)
+ return ret;
+ *keylen = ret;
+ return 1;
+ }
+
+static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+ {
+ EC_PKEY_CTX *dctx = ctx->data;
+ EC_GROUP *group;
+ switch (type)
+ {
+ case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
+ group = EC_GROUP_new_by_curve_name(p1);
+ if (group == NULL)
+ {
+ ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
+ return 0;
+ }
+ if (dctx->gen_group)
+ EC_GROUP_free(dctx->gen_group);
+ dctx->gen_group = group;
+ return 1;
+
+ case EVP_PKEY_CTRL_MD:
+ if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha512)
+ {
+ ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
+ return 0;
+ }
+ dctx->md = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_PEER_KEY:
+ /* Default behaviour is OK */
+ case EVP_PKEY_CTRL_DIGESTINIT:
+ case EVP_PKEY_CTRL_PKCS7_SIGN:
+ case EVP_PKEY_CTRL_CMS_SIGN:
+ return 1;
+
+ default:
+ return -2;
+
+ }
+ }
+
+static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
+ const char *type, const char *value)
+ {
+ if (!strcmp(type, "ec_paramgen_curve"))
+ {
+ int nid;
+ nid = OBJ_sn2nid(value);
+ if (nid == NID_undef)
+ nid = OBJ_ln2nid(value);
+ if (nid == NID_undef)
+ {
+ ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
+ return 0;
+ }
+ return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
+ }
+ return -2;
+ }
+
+static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+ {
+ EC_KEY *ec = NULL;
+ EC_PKEY_CTX *dctx = ctx->data;
+ int ret = 0;
+ if (dctx->gen_group == NULL)
+ {
+ ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
+ return 0;
+ }
+ ec = EC_KEY_new();
+ if (!ec)
+ return 0;
+ ret = EC_KEY_set_group(ec, dctx->gen_group);
+ if (ret)
+ EVP_PKEY_assign_EC_KEY(pkey, ec);
+ else
+ EC_KEY_free(ec);
+ return ret;
+ }
+
+static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+ {
+ EC_KEY *ec = NULL;
+ if (ctx->pkey == NULL)
+ {
+ ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
+ return 0;
+ }
+ ec = EC_KEY_new();
+ if (!ec)
+ return 0;
+ EVP_PKEY_assign_EC_KEY(pkey, ec);
+ /* Note: if error return, pkey is freed by parent routine */
+ if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+ return 0;
+ return EC_KEY_generate_key(pkey->pkey.ec);
+ }
+
+const EVP_PKEY_METHOD ec_pkey_meth =
+ {
+ EVP_PKEY_EC,
+ 0,
+ pkey_ec_init,
+ pkey_ec_copy,
+ pkey_ec_cleanup,
+
+ 0,
+ pkey_ec_paramgen,
+
+ 0,
+ pkey_ec_keygen,
+
+ 0,
+ pkey_ec_sign,
+
+ 0,
+ pkey_ec_verify,
+
+ 0,0,
+
+ 0,0,0,0,
+
+ 0,0,
+
+ 0,0,
+
+ 0,
+ pkey_ec_derive,
+
+ pkey_ec_ctrl,
+ pkey_ec_ctrl_str
+
+ };
diff --git a/crypto/ec/eck_prn.c b/crypto/ec/eck_prn.c
new file mode 100644
index 0000000..7d3e175
--- /dev/null
+++ b/crypto/ec/eck_prn.c
@@ -0,0 +1,391 @@
+/* crypto/ec/eck_prn.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-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
+ * openssl-core@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).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions originally developed by SUN MICROSYSTEMS, INC., and
+ * contributed to the OpenSSL project.
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/ec.h>
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_FP_API
+int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
+ {
+ BIO *b;
+ int ret;
+
+ if ((b=BIO_new(BIO_s_file())) == NULL)
+ {
+ ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB);
+ return(0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = ECPKParameters_print(b, x, off);
+ BIO_free(b);
+ return(ret);
+ }
+
+int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
+ {
+ BIO *b;
+ int ret;
+
+ if ((b=BIO_new(BIO_s_file())) == NULL)
+ {
+ ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
+ return(0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = EC_KEY_print(b, x, off);
+ BIO_free(b);
+ return(ret);
+ }
+
+int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
+ {
+ BIO *b;
+ int ret;
+
+ if ((b=BIO_new(BIO_s_file())) == NULL)
+ {
+ ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
+ return(0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = ECParameters_print(b, x);
+ BIO_free(b);
+ return(ret);
+ }
+#endif
+
+int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
+ {
+ EVP_PKEY *pk;
+ int ret;
+ pk = EVP_PKEY_new();
+ if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
+ return 0;
+ ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+ EVP_PKEY_free(pk);
+ return ret;
+ }
+
+int ECParameters_print(BIO *bp, const EC_KEY *x)
+ {
+ EVP_PKEY *pk;
+ int ret;
+ pk = EVP_PKEY_new();
+ if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
+ return 0;
+ ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
+ EVP_PKEY_free(pk);
+ return ret;
+ }
+
+static int print_bin(BIO *fp, const char *str, const unsigned char *num,
+ size_t len, int off);
+
+int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
+ {
+ unsigned char *buffer=NULL;
+ size_t buf_len=0, i;
+ int ret=0, reason=ERR_R_BIO_LIB;
+ BN_CTX *ctx=NULL;
+ const EC_POINT *point=NULL;
+ BIGNUM *p=NULL, *a=NULL, *b=NULL, *gen=NULL,
+ *order=NULL, *cofactor=NULL;
+ const unsigned char *seed;
+ size_t seed_len=0;
+
+ static const char *gen_compressed = "Generator (compressed):";
+ static const char *gen_uncompressed = "Generator (uncompressed):";
+ static const char *gen_hybrid = "Generator (hybrid):";
+
+ if (!x)
+ {
+ reason = ERR_R_PASSED_NULL_PARAMETER;
+ goto err;
+ }
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+
+ if (EC_GROUP_get_asn1_flag(x))
+ {
+ /* the curve parameter are given by an asn1 OID */
+ int nid;
+
+ if (!BIO_indent(bp, off, 128))
+ goto err;
+
+ nid = EC_GROUP_get_curve_name(x);
+ if (nid == 0)
+ goto err;
+
+ if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
+ goto err;
+ if (BIO_printf(bp, "\n") <= 0)
+ goto err;
+ }
+ else
+ {
+ /* explicit parameters */
+ int is_char_two = 0;
+ point_conversion_form_t form;
+ int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
+
+ if (tmp_nid == NID_X9_62_characteristic_two_field)
+ is_char_two = 1;
+
+ if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
+ (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
+ (cofactor = BN_new()) == NULL)
+ {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+
+ if (is_char_two)
+ {
+ if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx))
+ {
+ reason = ERR_R_EC_LIB;
+ goto err;
+ }
+ }
+ else /* prime field */
+ {
+ if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
+ {
+ reason = ERR_R_EC_LIB;
+ goto err;
+ }
+ }
+
+ if ((point = EC_GROUP_get0_generator(x)) == NULL)
+ {
+ reason = ERR_R_EC_LIB;
+ goto err;
+ }
+ if (!EC_GROUP_get_order(x, order, NULL) ||
+ !EC_GROUP_get_cofactor(x, cofactor, NULL))
+ {
+ reason = ERR_R_EC_LIB;
+ goto err;
+ }
+
+ form = EC_GROUP_get_point_conversion_form(x);
+
+ if ((gen = EC_POINT_point2bn(x, point,
+ form, NULL, ctx)) == NULL)
+ {
+ reason = ERR_R_EC_LIB;
+ goto err;
+ }
+
+ buf_len = (size_t)BN_num_bytes(p);
+ if (buf_len < (i = (size_t)BN_num_bytes(a)))
+ buf_len = i;
+ if (buf_len < (i = (size_t)BN_num_bytes(b)))
+ buf_len = i;
+ if (buf_len < (i = (size_t)BN_num_bytes(gen)))
+ buf_len = i;
+ if (buf_len < (i = (size_t)BN_num_bytes(order)))
+ buf_len = i;
+ if (buf_len < (i = (size_t)BN_num_bytes(cofactor)))
+ buf_len = i;
+
+ if ((seed = EC_GROUP_get0_seed(x)) != NULL)
+ seed_len = EC_GROUP_get_seed_len(x);
+
+ buf_len += 10;
+ if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
+ {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+
+ if (!BIO_indent(bp, off, 128))
+ goto err;
+
+ /* print the 'short name' of the field type */
+ if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
+ <= 0)
+ goto err;
+
+ if (is_char_two)
+ {
+ /* print the 'short name' of the base type OID */
+ int basis_type = EC_GROUP_get_basis_type(x);
+ if (basis_type == 0)
+ goto err;
+
+ if (!BIO_indent(bp, off, 128))
+ goto err;
+
+ if (BIO_printf(bp, "Basis Type: %s\n",
+ OBJ_nid2sn(basis_type)) <= 0)
+ goto err;
+
+ /* print the polynomial */
+ if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
+ off))
+ goto err;
+ }
+ else
+ {
+ if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer,off))
+ goto err;
+ }
+ if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off))
+ goto err;
+ if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off))
+ goto err;
+ if (form == POINT_CONVERSION_COMPRESSED)
+ {
+ if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
+ buffer, off))
+ goto err;
+ }
+ else if (form == POINT_CONVERSION_UNCOMPRESSED)
+ {
+ if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
+ buffer, off))
+ goto err;
+ }
+ else /* form == POINT_CONVERSION_HYBRID */
+ {
+ if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
+ buffer, off))
+ goto err;
+ }
+ if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
+ buffer, off)) goto err;
+ if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
+ buffer, off)) goto err;
+ if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
+ goto err;
+ }
+ ret=1;
+err:
+ if (!ret)
+ ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
+ if (p)
+ BN_free(p);
+ if (a)
+ BN_free(a);
+ if (b)
+ BN_free(b);
+ if (gen)
+ BN_free(gen);
+ if (order)
+ BN_free(order);
+ if (cofactor)
+ BN_free(cofactor);
+ if (ctx)
+ BN_CTX_free(ctx);
+ if (buffer != NULL)
+ OPENSSL_free(buffer);
+ return(ret);
+ }
+
+static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
+ size_t len, int off)
+ {
+ size_t i;
+ char str[128];
+
+ if (buf == NULL)
+ return 1;
+ if (off)
+ {
+ if (off > 128)
+ off=128;
+ memset(str,' ',off);
+ if (BIO_write(fp, str, off) <= 0)
+ return 0;
+ }
+
+ if (BIO_printf(fp,"%s", name) <= 0)
+ return 0;
+
+ for (i=0; i<len; i++)
+ {
+ if ((i%15) == 0)
+ {
+ str[0]='\n';
+ memset(&(str[1]),' ',off+4);
+ if (BIO_write(fp, str, off+1+4) <= 0)
+ return 0;
+ }
+ if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0)
+ return 0;
+ }
+ if (BIO_write(fp,"\n",1) <= 0)
+ return 0;
+
+ return 1;
+ }
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index e48f42e..f9e34ec 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1512,6 +1512,7 @@
BIO * SSL_get_wbio(const SSL *s);
#endif
int SSL_set_cipher_list(SSL *s, const char *str);
+int SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk);
void SSL_set_read_ahead(SSL *s, int yes);
int SSL_get_verify_mode(const SSL *s);
int SSL_get_verify_depth(const SSL *s);
diff --git a/openssl.config b/openssl.config
index 4328101..3b109b6 100644
--- a/openssl.config
+++ b/openssl.config
@@ -84,9 +84,6 @@
crypto/dso/Makefile \
crypto/dso/dso_beos.c \
crypto/ec/Makefile \
- crypto/ec/ec_ameth.c \
- crypto/ec/ec_pmeth.c \
- crypto/ec/eck_prn.c \
crypto/ecdh/Makefile \
crypto/ecdsa/Makefile \
crypto/engine/Makefile \
@@ -167,6 +164,7 @@
"
OPENSSL_PATCHES_progs_SOURCES="\
+ apps/openssl.c \
apps/progs.h \
apps/speed.c"
diff --git a/patches/apps_Android.mk b/patches/apps_Android.mk
index a908806..e9f215c 100644
--- a/patches/apps_Android.mk
+++ b/patches/apps_Android.mk
@@ -17,6 +17,7 @@
dsa.c \
dsaparam.c \
ecparam.c \
+ ec.c \
enc.c \
engine.c \
errstr.c \
@@ -64,7 +65,7 @@
# These flags omit whole features from the commandline "openssl".
# However, portions of these features are actually turned on.
-LOCAL_CFLAGS += -DOPENSSL_NO_EC -DOPENSSL_NO_ECDSA -DOPENSSL_NO_DTLS1
+LOCAL_CFLAGS += -DOPENSSL_NO_DTLS1
LOCAL_MODULE:= openssl
diff --git a/patches/crypto_Android.mk b/patches/crypto_Android.mk
index 14bac8e..cb2dfd4 100644
--- a/patches/crypto_Android.mk
+++ b/patches/crypto_Android.mk
@@ -226,6 +226,33 @@
dso/dso_openssl.c \
dso/dso_vms.c \
dso/dso_win32.c \
+ ec/ec2_mult.c \
+ ec/ec2_smpl.c \
+ ec/ec_ameth.c \
+ ec/ec_asn1.c \
+ ec/ec_check.c \
+ ec/ec_curve.c \
+ ec/ec_cvt.c \
+ ec/ec_err.c \
+ ec/ec_key.c \
+ ec/ec_lib.c \
+ ec/ec_mult.c \
+ ec/ec_pmeth.c \
+ ec/ec_print.c \
+ ec/eck_prn.c \
+ ec/ecp_mont.c \
+ ec/ecp_nist.c \
+ ec/ecp_smpl.c \
+ ecdh/ech_err.c \
+ ecdh/ech_key.c \
+ ecdh/ech_lib.c \
+ ecdh/ech_ossl.c \
+ ecdsa/ecs_asn1.c \
+ ecdsa/ecs_err.c \
+ ecdsa/ecs_lib.c \
+ ecdsa/ecs_ossl.c \
+ ecdsa/ecs_sign.c \
+ ecdsa/ecs_vrf.c \
err/err.c \
err/err_all.c \
err/err_prn.c \
@@ -256,6 +283,7 @@
evp/evp_pkey.c \
evp/m_dss.c \
evp/m_dss1.c \
+ evp/m_ecdsa.c \
evp/m_md2.c \
evp/m_md4.c \
evp/m_md5.c \
diff --git a/patches/jsse.patch b/patches/jsse.patch
index f1c14a8..b0ae319 100644
--- a/patches/jsse.patch
+++ b/patches/jsse.patch
@@ -10,7 +10,15 @@
/* Default generate session ID callback. */
GEN_SESSION_CB generate_session_id;
-@@ -1559,6 +1571,7 @@ int SSL_SESSION_print(BIO *fp,const SSL_
+@@ -1500,6 +1512,7 @@ BIO * SSL_get_rbio(const SSL *s);
+ BIO * SSL_get_wbio(const SSL *s);
+ #endif
+ int SSL_set_cipher_list(SSL *s, const char *str);
++int SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk);
+ void SSL_set_read_ahead(SSL *s, int yes);
+ int SSL_get_verify_mode(const SSL *s);
+ int SSL_get_verify_depth(const SSL *s);
+@@ -1559,6 +1572,7 @@ int SSL_SESSION_print(BIO *fp,const SSL_
void SSL_SESSION_free(SSL_SESSION *ses);
int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
int SSL_set_session(SSL *to, SSL_SESSION *session);
@@ -18,7 +26,7 @@
int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
int SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
-@@ -2204,6 +2217,7 @@ void ERR_load_SSL_strings(void);
+@@ -2204,6 +2218,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345
#define SSL_R_SERVERHELLO_TLSEXT 275
#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
@@ -27,7 +35,7 @@
#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220
#define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221
--- openssl-1.0.0.orig/ssl/d1_clnt.c 2010-01-26 11:46:29.000000000 -0800
-+++ openssl-1.0.0/ssl/d1_clnt.c 2010-05-03 01:44:52.000000000 -0700
++++ openssl-1.0.0/ssl/d1_clnt.c 2010-05-12 22:07:36.000000000 -0700
@@ -613,6 +613,12 @@ int dtls1_client_hello(SSL *s)
#endif
(s->session->not_resumable))
@@ -42,7 +50,7 @@
goto err;
}
--- openssl-1.0.0.orig/ssl/s23_clnt.c 2010-02-16 06:20:40.000000000 -0800
-+++ openssl-1.0.0/ssl/s23_clnt.c 2010-05-03 01:44:52.000000000 -0700
++++ openssl-1.0.0/ssl/s23_clnt.c 2010-05-12 22:07:36.000000000 -0700
@@ -687,6 +687,13 @@ static int ssl23_get_server_hello(SSL *s
/* Since, if we are sending a ssl23 client hello, we are not
@@ -58,7 +66,7 @@
goto err;
--- openssl-1.0.0.orig/ssl/s3_clnt.c 2010-02-27 16:24:24.000000000 -0800
-+++ openssl-1.0.0/ssl/s3_clnt.c 2010-05-03 01:44:52.000000000 -0700
++++ openssl-1.0.0/ssl/s3_clnt.c 2010-05-12 22:07:36.000000000 -0700
@@ -621,6 +668,12 @@ int ssl3_client_hello(SSL *s)
#endif
(sess->not_resumable))
@@ -86,7 +94,7 @@
{
al=SSL_AD_INTERNAL_ERROR;
--- openssl-1.0.0.orig/ssl/s3_srvr.c 2010-02-27 15:04:10.000000000 -0800
-+++ openssl-1.0.0/ssl/s3_srvr.c 2010-05-03 01:44:52.000000000 -0700
++++ openssl-1.0.0/ssl/s3_srvr.c 2010-05-12 22:07:36.000000000 -0700
@@ -869,6 +869,12 @@ int ssl3_get_client_hello(SSL *s)
*/
if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))
@@ -114,7 +122,7 @@
goto err;
}
--- openssl-1.0.0.orig/ssl/ssl_err.c 2010-01-06 09:37:38.000000000 -0800
-+++ openssl-1.0.0/ssl/ssl_err.c 2010-05-03 01:44:52.000000000 -0700
++++ openssl-1.0.0/ssl/ssl_err.c 2010-05-12 22:07:36.000000000 -0700
@@ -462,6 +462,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
{ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"},
{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"},
@@ -124,7 +132,7 @@
{ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
{ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},
--- openssl-1.0.0.orig/ssl/ssl_lib.c 2010-02-17 11:43:46.000000000 -0800
-+++ openssl-1.0.0/ssl/ssl_lib.c 2010-05-03 01:44:52.000000000 -0700
++++ openssl-1.0.0/ssl/ssl_lib.c 2010-05-12 22:07:36.000000000 -0700
@@ -326,6 +326,7 @@ SSL *SSL_new(SSL_CTX *ctx)
OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx));
@@ -133,8 +141,41 @@
s->generate_session_id=ctx->generate_session_id;
s->param = X509_VERIFY_PARAM_new();
+@@ -1303,6 +1304,32 @@ int SSL_set_cipher_list(SSL *s,const cha
+ return 1;
+ }
+
++/** specify the ciphers to be used by the SSL */
++int SSL_set_cipher_lists(SSL *s,STACK_OF(SSL_CIPHER) *sk)
++ {
++ STACK_OF(SSL_CIPHER) *tmp_cipher_list;
++
++ if (sk == NULL)
++ return 0;
++
++ /* Based on end of ssl_create_cipher_list */
++ tmp_cipher_list = sk_SSL_CIPHER_dup(sk);
++ if (tmp_cipher_list == NULL)
++ {
++ return 0;
++ }
++ if (s->cipher_list != NULL)
++ sk_SSL_CIPHER_free(s->cipher_list);
++ s->cipher_list = sk;
++ if (s->cipher_list_by_id != NULL)
++ sk_SSL_CIPHER_free(s->cipher_list_by_id);
++ s->cipher_list_by_id = tmp_cipher_list;
++ (void)sk_SSL_CIPHER_set_cmp_func(s->cipher_list_by_id,ssl_cipher_ptr_id_cmp);
++
++ sk_SSL_CIPHER_sort(s->cipher_list_by_id);
++ return 1;
++ }
++
+ /* works well for SSLv2, not so good for SSLv3 */
+ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
+ {
--- openssl-1.0.0.orig/ssl/ssl_sess.c 2010-02-01 08:49:42.000000000 -0800
-+++ openssl-1.0.0/ssl/ssl_sess.c 2010-05-03 01:44:52.000000000 -0700
++++ openssl-1.0.0/ssl/ssl_sess.c 2010-05-12 22:07:36.000000000 -0700
@@ -261,6 +261,11 @@ static int def_generate_session_id(const
return 0;
}
diff --git a/patches/progs.patch b/patches/progs.patch
index d7b794c..f82ea66 100644
--- a/patches/progs.patch
+++ b/patches/progs.patch
@@ -1,5 +1,18 @@
+--- openssl-1.0.0.orig/apps/openssl.c 2009-10-04 09:43:21.000000000 -0700
++++ openssl-1.0.0/apps/openssl.c 2010-05-14 11:50:23.000000000 -0700
+@@ -275,8 +275,10 @@ int main(int Argc, char *Argv[])
+ if (ERR_GET_REASON(ERR_peek_last_error())
+ == CONF_R_NO_SUCH_FILE)
+ {
++#if 0 /* ANDROID */
+ BIO_printf(bio_err,
+ "WARNING: can't open config file: %s\n",p);
++#endif
+ ERR_clear_error();
+ NCONF_free(config);
+ config = NULL;
--- openssl-1.0.0.orig/apps/progs.h 2009-06-30 08:08:38.000000000 -0700
-+++ openssl-1.0.0/apps/progs.h 2010-04-14 14:19:31.000000000 -0700
++++ openssl-1.0.0/apps/progs.h 2010-05-14 11:50:23.000000000 -0700
@@ -43,7 +43,9 @@ extern int spkac_main(int argc,char *arg
extern int smime_main(int argc,char *argv[]);
extern int rand_main(int argc,char *argv[]);
@@ -44,7 +57,7 @@
{FUNC_TYPE_MD,"md2",dgst_main},
#endif
--- openssl-1.0.0.orig/apps/speed.c 2010-03-03 11:56:17.000000000 -0800
-+++ openssl-1.0.0/apps/speed.c 2010-04-13 16:53:43.000000000 -0700
++++ openssl-1.0.0/apps/speed.c 2010-05-14 11:50:23.000000000 -0700
@@ -1718,6 +1718,7 @@ int MAIN(int argc, char **argv)
}
}
diff --git a/patches/ssl_Android.mk b/patches/ssl_Android.mk
index 0ea0b45..201a740 100644
--- a/patches/ssl_Android.mk
+++ b/patches/ssl_Android.mk
@@ -60,7 +60,7 @@
# ssltest
-LOCAL_SRC_FILES:=ssltest.c
+LOCAL_SRC_FILES:= ssltest.c
LOCAL_C_INCLUDES += $(local_c_includes)
@@ -68,7 +68,7 @@
include $(LOCAL_PATH)/../android-config.mk
-LOCAL_MODULE:=ssltest
+LOCAL_MODULE:= ssltest
LOCAL_MODULE_TAGS := optional
diff --git a/ssl/Android.mk b/ssl/Android.mk
index 0ea0b45..201a740 100644
--- a/ssl/Android.mk
+++ b/ssl/Android.mk
@@ -60,7 +60,7 @@
# ssltest
-LOCAL_SRC_FILES:=ssltest.c
+LOCAL_SRC_FILES:= ssltest.c
LOCAL_C_INCLUDES += $(local_c_includes)
@@ -68,7 +68,7 @@
include $(LOCAL_PATH)/../android-config.mk
-LOCAL_MODULE:=ssltest
+LOCAL_MODULE:= ssltest
LOCAL_MODULE_TAGS := optional
diff --git a/ssl/ssl.h b/ssl/ssl.h
index e48f42e..f9e34ec 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -1512,6 +1512,7 @@
BIO * SSL_get_wbio(const SSL *s);
#endif
int SSL_set_cipher_list(SSL *s, const char *str);
+int SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk);
void SSL_set_read_ahead(SSL *s, int yes);
int SSL_get_verify_mode(const SSL *s);
int SSL_get_verify_depth(const SSL *s);
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index a594b79..e3437a0 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1304,6 +1304,32 @@
return 1;
}
+/** specify the ciphers to be used by the SSL */
+int SSL_set_cipher_lists(SSL *s,STACK_OF(SSL_CIPHER) *sk)
+ {
+ STACK_OF(SSL_CIPHER) *tmp_cipher_list;
+
+ if (sk == NULL)
+ return 0;
+
+ /* Based on end of ssl_create_cipher_list */
+ tmp_cipher_list = sk_SSL_CIPHER_dup(sk);
+ if (tmp_cipher_list == NULL)
+ {
+ return 0;
+ }
+ if (s->cipher_list != NULL)
+ sk_SSL_CIPHER_free(s->cipher_list);
+ s->cipher_list = sk;
+ if (s->cipher_list_by_id != NULL)
+ sk_SSL_CIPHER_free(s->cipher_list_by_id);
+ s->cipher_list_by_id = tmp_cipher_list;
+ (void)sk_SSL_CIPHER_set_cmp_func(s->cipher_list_by_id,ssl_cipher_ptr_id_cmp);
+
+ sk_SSL_CIPHER_sort(s->cipher_list_by_id);
+ return 1;
+ }
+
/* works well for SSLv2, not so good for SSLv3 */
char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
{