Loading ssl/s3_lib.c +8 −159 Original line number Diff line number Diff line Loading @@ -152,11 +152,6 @@ #include <openssl/objects.h> #include "ssl_locl.h" #include "kssl_lcl.h" #ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_EC #include "../crypto/ec/ec_lcl.h" #endif /* OPENSSL_NO_EC */ #endif /* OPENSSL_NO_TLSEXT */ #include <openssl/md5.h> #ifndef OPENSSL_NO_DH #include <openssl/dh.h> Loading Loading @@ -3844,11 +3839,6 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, SSL_CIPHER *c,*ret=NULL; STACK_OF(SSL_CIPHER) *prio, *allow; int i,ii,ok; #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_EC) unsigned int j; int ec_ok, ec_nid; unsigned char ec_search1 = 0, ec_search2 = 0; #endif CERT *cert; unsigned long alg_k,alg_a,mask_k,mask_a,emask_k,emask_a; Loading Loading @@ -3949,155 +3939,14 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, #ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_EC if ( /* if we are considering an ECC cipher suite that uses our certificate */ (alg_a & SSL_aECDSA || alg_a & SSL_aECDH) /* and we have an ECC certificate */ && (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL) /* and the client specified a Supported Point Formats extension */ && ((s->session->tlsext_ecpointformatlist_length > 0) && (s->session->tlsext_ecpointformatlist != NULL)) /* and our certificate's point is compressed */ && ( (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info != NULL) && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key != NULL) && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key != NULL) && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data != NULL) && ( (*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED) || (*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED + 1) ) ) ) { ec_ok = 0; /* if our certificate's curve is over a field type that the client does not support * then do not allow this cipher suite to be negotiated */ if ( (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL) && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL) && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL) && (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field) ) { for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++) { if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime) { ec_ok = 1; break; } } } else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field) { for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++) { if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2) { ec_ok = 1; break; } } } ok = ok && ec_ok; } if ( /* if we are considering an ECC cipher suite that uses our certificate */ (alg_a & SSL_aECDSA || alg_a & SSL_aECDH) /* 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_k & SSL_kEECDH) /* 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; } /* if we are considering an ECC cipher suite that uses our * certificate check it */ if (alg_a & (SSL_aECDSA|SSL_aECDH)) ok = ok && tls1_check_ec_server_key(s); /* if we are considering an ECC cipher suite that uses * an ephemeral EC key check it */ if (alg_k & SSL_kEECDH) ok = ok && tls1_check_ec_tmp_key(s); #endif /* OPENSSL_NO_EC */ #endif /* OPENSSL_NO_TLSEXT */ Loading ssl/ssl_locl.h +2 −0 Original line number Diff line number Diff line Loading @@ -1107,6 +1107,8 @@ int tls1_set_curves(unsigned char **pext, size_t *pextlen, int *curves, size_t ncurves); int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, const char *str); int tls1_check_ec_server_key(SSL *s); int tls1_check_ec_tmp_key(SSL *s); #endif /* OPENSSL_NO_EC */ #ifndef OPENSSL_NO_TLSEXT Loading ssl/t1_lib.c +153 −31 Original line number Diff line number Diff line Loading @@ -307,6 +307,30 @@ int tls1_ec_nid2curve_id(int nid) return 0; } } /* Get curves list, if "sess" is set return client curves otherwise * preferred list */ static void tls1_get_curvelist(SSL *s, int sess, const unsigned char **pcurves, size_t *pcurveslen) { if (sess) { *pcurves = s->session->tlsext_ellipticcurvelist; *pcurveslen = s->session->tlsext_ellipticcurvelist_length; } else { *pcurves = s->tlsext_ellipticcurvelist; *pcurveslen = s->tlsext_ellipticcurvelist_length; } /* If not set use default: for now static structure */ if (!*pcurves) { *pcurves = eccurves_default; *pcurveslen = sizeof(eccurves_default); } } /* Return any common values from two lists. One list is used as a * preference list where we return the most preferred match. Loading Loading @@ -362,28 +386,10 @@ int tls1_shared_curve(SSL *s, int nmatch) /* Can't do anything on client side */ if (s->server == 0) return -1; /* Use our preferred curve list, if not set use default */ if (s->tlsext_ellipticcurvelist) { l1 = s->tlsext_ellipticcurvelist; l1len = s->tlsext_ellipticcurvelist_length; } else { l1 = eccurves_default; l1len = sizeof(eccurves_default); } /* Use peer preferred curve list, if not set use default */ if(s->session->tlsext_ellipticcurvelist) { l2 = s->session->tlsext_ellipticcurvelist; l2len =s->session->tlsext_ellipticcurvelist_length; } else { l2 = eccurves_default; l2len = sizeof(eccurves_default); } /* Get supported curves */ tls1_get_curvelist(s, 0, &l1, &l1len); tls1_get_curvelist(s, 1, &l2, &l2len); id = tls1_shared_list(s, l1, l1len, l2, l2len, nmatch); if (nmatch == -1) return id; Loading Loading @@ -466,6 +472,130 @@ int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, return 0; return tls1_set_curves(pext, pextlen, ncb.nid_arr, ncb.nidcnt); } /* For an EC key set TLS id and required compression based on parameters */ static int tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, EC_KEY *ec) { int is_prime, id; const EC_GROUP *grp; const EC_POINT *pt; const EC_METHOD *meth; if (!ec) return 0; /* Determine if it is a prime field */ grp = EC_KEY_get0_group(ec); pt = EC_KEY_get0_public_key(ec); if (!grp || !pt) return 0; meth = EC_GROUP_method_of(grp); if (!meth) return 0; if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field) is_prime = 1; else is_prime = 0; /* Determine curve ID */ id = EC_GROUP_get_curve_name(grp); id = tls1_ec_nid2curve_id(id); /* If we have an ID set it, otherwise set arbitrary explicit curve */ if (id) { curve_id[0] = 0; curve_id[1] = (unsigned char)id; } else { curve_id[0] = 0xff; if (is_prime) curve_id[1] = 0x01; else curve_id[1] = 0x02; } if (comp_id) { if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) { if (is_prime) *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; else *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; } else *comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; } return 1; } /* Check an EC key is compatible with extensions */ static int tls1_check_ec_key(SSL *s, unsigned char *curve_id, unsigned char *comp_id) { const unsigned char *p; size_t plen, i; /* If point formats extension present check it, otherwise everything * is supported (see RFC4492). */ if (comp_id && s->session->tlsext_ecpointformatlist) { p = s->session->tlsext_ecpointformatlist; plen = s->session->tlsext_ecpointformatlist_length; for (i = 0; i < plen; i++, p++) { if (*comp_id == *p) break; } if (i == plen) return 0; } /* If curve list present check it, otherwise everything is * supported. */ if (s->session->tlsext_ellipticcurvelist) { p = s->session->tlsext_ellipticcurvelist; plen = s->session->tlsext_ellipticcurvelist_length; for (i = 0; i < plen; i+=2, p+=2) { if (p[0] == curve_id[0] && p[1] == curve_id[1]) return 1; } return 0; } return 1; } /* Check EC server key is compatible with client extensions */ int tls1_check_ec_server_key(SSL *s) { int rv; CERT_PKEY *cpk = s->cert->pkeys + SSL_PKEY_ECC; EVP_PKEY *pkey; unsigned char comp_id, curve_id[2]; if (!cpk->x509 || !cpk->privatekey) return 0; pkey = X509_get_pubkey(cpk->x509); if (!pkey) return 0; rv = tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec); EVP_PKEY_free(pkey); if (!rv) return 0; return tls1_check_ec_key(s, curve_id, &comp_id); } /* Check EC temporary key is compatible with client extensions */ int tls1_check_ec_tmp_key(SSL *s) { unsigned char curve_id[2]; EC_KEY *ec = s->cert->ecdh_tmp; if (!ec) { if (s->cert->ecdh_tmp_cb) return 1; else return 0; } if (!tls1_set_ec_id(curve_id, NULL, ec)) return 1; return tls1_check_ec_key(s, curve_id, NULL); } #endif /* OPENSSL_NO_EC */ Loading Loading @@ -685,15 +815,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha /* Add TLS extension EllipticCurves to the ClientHello message */ plist = s->tlsext_ellipticcurvelist; /* If we have a custom curve list use it otherwise * use default */ if (plist) plistlen = s->tlsext_ellipticcurvelist_length; else { plist = eccurves_default; plistlen = sizeof(eccurves_default); } tls1_get_curvelist(s, 0, &plist, &plistlen); if ((lenmax = limit - ret - 6) < 0) return NULL; if (plistlen > (size_t)lenmax) return NULL; Loading Loading
ssl/s3_lib.c +8 −159 Original line number Diff line number Diff line Loading @@ -152,11 +152,6 @@ #include <openssl/objects.h> #include "ssl_locl.h" #include "kssl_lcl.h" #ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_EC #include "../crypto/ec/ec_lcl.h" #endif /* OPENSSL_NO_EC */ #endif /* OPENSSL_NO_TLSEXT */ #include <openssl/md5.h> #ifndef OPENSSL_NO_DH #include <openssl/dh.h> Loading Loading @@ -3844,11 +3839,6 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, SSL_CIPHER *c,*ret=NULL; STACK_OF(SSL_CIPHER) *prio, *allow; int i,ii,ok; #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_EC) unsigned int j; int ec_ok, ec_nid; unsigned char ec_search1 = 0, ec_search2 = 0; #endif CERT *cert; unsigned long alg_k,alg_a,mask_k,mask_a,emask_k,emask_a; Loading Loading @@ -3949,155 +3939,14 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, #ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_EC if ( /* if we are considering an ECC cipher suite that uses our certificate */ (alg_a & SSL_aECDSA || alg_a & SSL_aECDH) /* and we have an ECC certificate */ && (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL) /* and the client specified a Supported Point Formats extension */ && ((s->session->tlsext_ecpointformatlist_length > 0) && (s->session->tlsext_ecpointformatlist != NULL)) /* and our certificate's point is compressed */ && ( (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info != NULL) && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key != NULL) && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key != NULL) && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data != NULL) && ( (*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED) || (*(s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key->public_key->data) == POINT_CONVERSION_COMPRESSED + 1) ) ) ) { ec_ok = 0; /* if our certificate's curve is over a field type that the client does not support * then do not allow this cipher suite to be negotiated */ if ( (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL) && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != NULL) && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth != NULL) && (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_prime_field) ) { for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++) { if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime) { ec_ok = 1; break; } } } else if (EC_METHOD_get_field_type(s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group->meth) == NID_X9_62_characteristic_two_field) { for (j = 0; j < s->session->tlsext_ecpointformatlist_length; j++) { if (s->session->tlsext_ecpointformatlist[j] == TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2) { ec_ok = 1; break; } } } ok = ok && ec_ok; } if ( /* if we are considering an ECC cipher suite that uses our certificate */ (alg_a & SSL_aECDSA || alg_a & SSL_aECDH) /* 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_k & SSL_kEECDH) /* 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; } /* if we are considering an ECC cipher suite that uses our * certificate check it */ if (alg_a & (SSL_aECDSA|SSL_aECDH)) ok = ok && tls1_check_ec_server_key(s); /* if we are considering an ECC cipher suite that uses * an ephemeral EC key check it */ if (alg_k & SSL_kEECDH) ok = ok && tls1_check_ec_tmp_key(s); #endif /* OPENSSL_NO_EC */ #endif /* OPENSSL_NO_TLSEXT */ Loading
ssl/ssl_locl.h +2 −0 Original line number Diff line number Diff line Loading @@ -1107,6 +1107,8 @@ int tls1_set_curves(unsigned char **pext, size_t *pextlen, int *curves, size_t ncurves); int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, const char *str); int tls1_check_ec_server_key(SSL *s); int tls1_check_ec_tmp_key(SSL *s); #endif /* OPENSSL_NO_EC */ #ifndef OPENSSL_NO_TLSEXT Loading
ssl/t1_lib.c +153 −31 Original line number Diff line number Diff line Loading @@ -307,6 +307,30 @@ int tls1_ec_nid2curve_id(int nid) return 0; } } /* Get curves list, if "sess" is set return client curves otherwise * preferred list */ static void tls1_get_curvelist(SSL *s, int sess, const unsigned char **pcurves, size_t *pcurveslen) { if (sess) { *pcurves = s->session->tlsext_ellipticcurvelist; *pcurveslen = s->session->tlsext_ellipticcurvelist_length; } else { *pcurves = s->tlsext_ellipticcurvelist; *pcurveslen = s->tlsext_ellipticcurvelist_length; } /* If not set use default: for now static structure */ if (!*pcurves) { *pcurves = eccurves_default; *pcurveslen = sizeof(eccurves_default); } } /* Return any common values from two lists. One list is used as a * preference list where we return the most preferred match. Loading Loading @@ -362,28 +386,10 @@ int tls1_shared_curve(SSL *s, int nmatch) /* Can't do anything on client side */ if (s->server == 0) return -1; /* Use our preferred curve list, if not set use default */ if (s->tlsext_ellipticcurvelist) { l1 = s->tlsext_ellipticcurvelist; l1len = s->tlsext_ellipticcurvelist_length; } else { l1 = eccurves_default; l1len = sizeof(eccurves_default); } /* Use peer preferred curve list, if not set use default */ if(s->session->tlsext_ellipticcurvelist) { l2 = s->session->tlsext_ellipticcurvelist; l2len =s->session->tlsext_ellipticcurvelist_length; } else { l2 = eccurves_default; l2len = sizeof(eccurves_default); } /* Get supported curves */ tls1_get_curvelist(s, 0, &l1, &l1len); tls1_get_curvelist(s, 1, &l2, &l2len); id = tls1_shared_list(s, l1, l1len, l2, l2len, nmatch); if (nmatch == -1) return id; Loading Loading @@ -466,6 +472,130 @@ int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, return 0; return tls1_set_curves(pext, pextlen, ncb.nid_arr, ncb.nidcnt); } /* For an EC key set TLS id and required compression based on parameters */ static int tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, EC_KEY *ec) { int is_prime, id; const EC_GROUP *grp; const EC_POINT *pt; const EC_METHOD *meth; if (!ec) return 0; /* Determine if it is a prime field */ grp = EC_KEY_get0_group(ec); pt = EC_KEY_get0_public_key(ec); if (!grp || !pt) return 0; meth = EC_GROUP_method_of(grp); if (!meth) return 0; if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field) is_prime = 1; else is_prime = 0; /* Determine curve ID */ id = EC_GROUP_get_curve_name(grp); id = tls1_ec_nid2curve_id(id); /* If we have an ID set it, otherwise set arbitrary explicit curve */ if (id) { curve_id[0] = 0; curve_id[1] = (unsigned char)id; } else { curve_id[0] = 0xff; if (is_prime) curve_id[1] = 0x01; else curve_id[1] = 0x02; } if (comp_id) { if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) { if (is_prime) *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; else *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; } else *comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; } return 1; } /* Check an EC key is compatible with extensions */ static int tls1_check_ec_key(SSL *s, unsigned char *curve_id, unsigned char *comp_id) { const unsigned char *p; size_t plen, i; /* If point formats extension present check it, otherwise everything * is supported (see RFC4492). */ if (comp_id && s->session->tlsext_ecpointformatlist) { p = s->session->tlsext_ecpointformatlist; plen = s->session->tlsext_ecpointformatlist_length; for (i = 0; i < plen; i++, p++) { if (*comp_id == *p) break; } if (i == plen) return 0; } /* If curve list present check it, otherwise everything is * supported. */ if (s->session->tlsext_ellipticcurvelist) { p = s->session->tlsext_ellipticcurvelist; plen = s->session->tlsext_ellipticcurvelist_length; for (i = 0; i < plen; i+=2, p+=2) { if (p[0] == curve_id[0] && p[1] == curve_id[1]) return 1; } return 0; } return 1; } /* Check EC server key is compatible with client extensions */ int tls1_check_ec_server_key(SSL *s) { int rv; CERT_PKEY *cpk = s->cert->pkeys + SSL_PKEY_ECC; EVP_PKEY *pkey; unsigned char comp_id, curve_id[2]; if (!cpk->x509 || !cpk->privatekey) return 0; pkey = X509_get_pubkey(cpk->x509); if (!pkey) return 0; rv = tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec); EVP_PKEY_free(pkey); if (!rv) return 0; return tls1_check_ec_key(s, curve_id, &comp_id); } /* Check EC temporary key is compatible with client extensions */ int tls1_check_ec_tmp_key(SSL *s) { unsigned char curve_id[2]; EC_KEY *ec = s->cert->ecdh_tmp; if (!ec) { if (s->cert->ecdh_tmp_cb) return 1; else return 0; } if (!tls1_set_ec_id(curve_id, NULL, ec)) return 1; return tls1_check_ec_key(s, curve_id, NULL); } #endif /* OPENSSL_NO_EC */ Loading Loading @@ -685,15 +815,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha /* Add TLS extension EllipticCurves to the ClientHello message */ plist = s->tlsext_ellipticcurvelist; /* If we have a custom curve list use it otherwise * use default */ if (plist) plistlen = s->tlsext_ellipticcurvelist_length; else { plist = eccurves_default; plistlen = sizeof(eccurves_default); } tls1_get_curvelist(s, 0, &plist, &plistlen); if ((lenmax = limit - ret - 6) < 0) return NULL; if (plistlen > (size_t)lenmax) return NULL; Loading