summaryrefslogtreecommitdiffstats
path: root/ssl/s3_lib.c
diff options
context:
space:
mode:
authorBodo Möller <bodo@openssl.org>2006-03-30 02:44:56 +0000
committerBodo Möller <bodo@openssl.org>2006-03-30 02:44:56 +0000
commit332737217a9b8eb07d53634ae72b0e2e9ec9b8c6 (patch)
tree2715bf871acf3b2947c4c71d5f8c337b82b1ec68 /ssl/s3_lib.c
parentbcbe37b716780763ee66c839618bd76eda2b507c (diff)
Implement Supported Elliptic Curves Extension.
Submitted by: Douglas Stebila
Diffstat (limited to 'ssl/s3_lib.c')
-rw-r--r--ssl/s3_lib.c101
1 files changed, 100 insertions, 1 deletions
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index a488692579..8e59a92905 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -2046,7 +2046,9 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
int i,j,ok;
#ifndef OPENSSL_NO_TLSEXT
#ifndef OPENSSL_NO_EC
- int ec_ok;
+ int ec_ok, ec_nid;
+ unsigned char ec_search1, ec_search2;
+ unsigned char *ec_ptr;
#endif /* OPENSSL_NO_EC */
#endif /* OPENSSL_NO_TLSEXT */
CERT *cert;
@@ -2188,6 +2190,103 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
}
ok = ok && ec_ok;
}
+ if (
+ /* if we are considering an ECC cipher suite that uses our certificate */
+ (alg & SSL_aECDSA)
+ /* and we have an ECC certificate */
+ && (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL)
+ /* and the client specified an EllipticCurves extension */
+ && ((s->session->tlsext_ellipticcurvelist_length > 0) && (s->session->tlsext_ellipticcurvelist != NULL))
+ )
+ {
+ ec_ok = 0;
+ if (
+ (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL)
+ && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL)
+ )
+ {
+ ec_nid = EC_GROUP_get_curve_name(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group);
+ if ((ec_nid == 0)
+ && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL)
+ )
+ {
+ if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field)
+ {
+ ec_search1 = 0xFF;
+ ec_search2 = 0x01;
+ }
+ else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field)
+ {
+ ec_search1 = 0xFF;
+ ec_search2 = 0x02;
+ }
+ }
+ else
+ {
+ ec_search1 = 0x00;
+ ec_search2 = tls1_ec_nid2curve_id(ec_nid);
+ }
+ if ((ec_search1 != 0) || (ec_search2 != 0))
+ {
+ for (j = 0; j < s->session->tlsext_ellipticcurvelist_length / 2; j++)
+ {
+ if ((s->session->tlsext_ellipticcurvelist[2*j] == ec_search1) && (s->session->tlsext_ellipticcurvelist[2*j+1] == ec_search2))
+ {
+ ec_ok = 1;
+ break;
+ }
+ }
+ }
+ }
+ ok = ok && ec_ok;
+ }
+ if (
+ /* if we are considering an ECC cipher suite that uses an ephemeral EC key */
+ ((alg & SSL_kECDH) || (alg & SSL_kECDHE))
+ /* and we have an ephemeral EC key */
+ && (s->cert->ecdh_tmp != NULL)
+ /* and the client specified an EllipticCurves extension */
+ && ((s->session->tlsext_ellipticcurvelist_length > 0) && (s->session->tlsext_ellipticcurvelist != NULL))
+ )
+ {
+ ec_ok = 0;
+ if (s->cert->ecdh_tmp->group != NULL)
+ {
+ ec_nid = EC_GROUP_get_curve_name(s->cert->ecdh_tmp->group);
+ if ((ec_nid == 0)
+ && (s->cert->ecdh_tmp->group->meth != NULL)
+ )
+ {
+ if (EC_METHOD_get_field_type(s->cert->ecdh_tmp->group->meth) == NID_X9_62_prime_field)
+ {
+ ec_search1 = 0xFF;
+ ec_search2 = 0x01;
+ }
+ else if (EC_METHOD_get_field_type(s->cert->ecdh_tmp->group->meth) == NID_X9_62_characteristic_two_field)
+ {
+ ec_search1 = 0xFF;
+ ec_search2 = 0x02;
+ }
+ }
+ else
+ {
+ ec_search1 = 0x00;
+ ec_search2 = tls1_ec_nid2curve_id(ec_nid);
+ }
+ if ((ec_search1 != 0) || (ec_search2 != 0))
+ {
+ for (j = 0; j < s->session->tlsext_ellipticcurvelist_length / 2; j++)
+ {
+ if ((s->session->tlsext_ellipticcurvelist[2*j] == ec_search1) && (s->session->tlsext_ellipticcurvelist[2*j+1] == ec_search2))
+ {
+ ec_ok = 1;
+ break;
+ }
+ }
+ }
+ }
+ ok = ok && ec_ok;
+ }
#endif /* OPENSSL_NO_EC */
#endif /* OPENSSL_NO_TLSEXT */