@@ -1,4 +1,4 @@
1-/* $OpenBSD: t1_lib.c,v 1.55 2014/09/21 17:11:04 jsing Exp $ */
1+/* $OpenBSD: t1_lib.c,v 1.56 2014/09/22 14:26:22 jsing Exp $ */
22/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
33 * All rights reserved.
44 *
@@ -349,6 +349,20 @@ tls1_ec_nid2curve_id(int nid)
349349 }
350350}
351351352+static void
353+tls1_get_formatlist(SSL *s, const unsigned char **pformats, size_t *pformatslen)
354+{
355+/*
356+ * If we have a custom point format list use it, otherwise use default.
357+ */
358+*pformats = s->tlsext_ecpointformatlist;
359+*pformatslen = s->tlsext_ecpointformatlist_length;
360+if (*pformats == NULL) {
361+*pformats = ecformats_default;
362+*pformatslen = sizeof(ecformats_default);
363+ }
364+}
365+352366/*
353367 * List of supported signature algorithms and hashes. Should make this
354368 * customisable at some point, for now include everything we support.
@@ -486,20 +500,11 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
486500/*
487501 * Add TLS extension ECPointFormats to the ClientHello message.
488502 */
489-size_t lenmax;
490503const unsigned char *plist;
491504size_t plistlen;
505+size_t lenmax;
492506493-/*
494- * If we have a custom point format list use it otherwise
495- * use default.
496- */
497-plist = s->tlsext_ecpointformatlist;
498-plistlen = s->tlsext_ecpointformatlist_length;
499-if (plist == NULL) {
500-plist = ecformats_default;
501-plistlen = sizeof(ecformats_default);
502- }
507+tls1_get_formatlist(s, &plist, &plistlen);
503508504509if ((size_t)(limit - ret) < 5)
505510return NULL;
@@ -723,12 +728,19 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
723728unsigned char *
724729ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
725730{
726-int extdatalen = 0;
731+int using_ecc, extdatalen = 0;
732+unsigned long alg_a, alg_k;
727733unsigned char *ret = p;
728734#ifndef OPENSSL_NO_NEXTPROTONEG
729735int next_proto_neg_seen;
730736#endif
731737738+alg_a = s->s3->tmp.new_cipher->algorithm_auth;
739+alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
740+using_ecc = (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe) ||
741+alg_a & SSL_aECDSA) &&
742+s->session->tlsext_ecpointformatlist != NULL;
743+732744/* don't add extensions for SSLv3, unless doing secure renegotiation */
733745if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
734746return p;
@@ -770,32 +782,39 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
770782ret += el;
771783 }
772784773-if (s->tlsext_ecpointformatlist != NULL &&
774-s->version != DTLS1_VERSION) {
775-/* Add TLS extension ECPointFormats to the ServerHello message */
785+if (using_ecc && s->version != DTLS1_VERSION) {
786+/*
787+ * Add TLS extension ECPointFormats to the ServerHello message.
788+ */
789+const unsigned char *plist;
790+size_t plistlen;
776791size_t lenmax;
777792793+tls1_get_formatlist(s, &plist, &plistlen);
794+778795if ((size_t)(limit - ret) < 5)
779796return NULL;
780797781798lenmax = limit - ret - 5;
782-if (s->tlsext_ecpointformatlist_length > lenmax)
799+if (plistlen > lenmax)
783800return NULL;
784-if (s->tlsext_ecpointformatlist_length > 255) {
801+if (plistlen > 255) {
785802SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT,
786803ERR_R_INTERNAL_ERROR);
787804return NULL;
788805 }
789806790807s2n(TLSEXT_TYPE_ec_point_formats, ret);
791-s2n(s->tlsext_ecpointformatlist_length + 1, ret);
792-*(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
793-memcpy(ret, s->tlsext_ecpointformatlist,
794-s->tlsext_ecpointformatlist_length);
795-ret += s->tlsext_ecpointformatlist_length;
796-808+s2n(plistlen + 1, ret);
809+*(ret++) = (unsigned char)plistlen;
810+memcpy(ret, plist, plistlen);
811+ret += plistlen;
797812 }
798-/* Currently the server should not respond with a SupportedCurves extension */
813+814+/*
815+ * Currently the server should not respond with a SupportedCurves
816+ * extension.
817+ */
799818800819if (s->tlsext_ticket_expected &&
801820 !(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
@@ -1526,28 +1545,6 @@ ssl_prepare_clienthello_tlsext(SSL *s)
15261545int
15271546ssl_prepare_serverhello_tlsext(SSL *s)
15281547{
1529-/* If we are server and using an ECC cipher suite, send the point formats we support
1530- * if the client sent us an ECPointsFormat extension. Note that the server is not
1531- * supposed to send an EllipticCurves extension.
1532- */
1533-1534-unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
1535-unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
1536-int using_ecc = (alg_k & (SSL_kECDHE|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA);
1537-using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
1538-1539-if (using_ecc) {
1540-free(s->tlsext_ecpointformatlist);
1541-if ((s->tlsext_ecpointformatlist = malloc(3)) == NULL) {
1542-SSLerr(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT, ERR_R_MALLOC_FAILURE);
1543-return -1;
1544- }
1545-s->tlsext_ecpointformatlist_length = 3;
1546-s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
1547-s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
1548-s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
1549- }
1550-15511548return 1;
15521549}
15531550