Use default point formats extension for server side as well as client
authorDr. Stephen Henson <steve@openssl.org>
Wed, 26 Dec 2012 17:09:14 +0000 (17:09 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 26 Dec 2012 17:09:14 +0000 (17:09 +0000)
side, if possible.

Don't advertise compressed char2 for SuiteB as it is not supported.
(backport from HEAD)

ssl/t1_lib.c

index 8f6ced26184bde4f12a18a3c92cbefdc170421e3..31cce72e0e71cc9bf360311e395a5929de3b9cc6 100644 (file)
@@ -622,6 +622,27 @@ static int tls1_check_ec_key(SSL *s,
        return 1;
        }
 
+static void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
+                                       size_t *pformatslen)
+       {
+       /* If we have a custom point format list use it otherwise
+        * use default */
+       if (s->tlsext_ecpointformatlist)
+               {
+               *pformats = s->tlsext_ecpointformatlist;
+               *pformatslen = s->tlsext_ecpointformatlist_length;
+               }
+       else
+               {
+               *pformats = ecformats_default;
+               /* For Suite B we don't support char2 fields */
+               if (tls1_suiteb(s))
+                       *pformatslen = sizeof(ecformats_default) - 1;
+               else
+                       *pformatslen = sizeof(ecformats_default);
+               }
+       }
+
 /* Check cert parameters compatible with extensions: currently just checks
  * EC certificates have compatible curves and compression.
  */
@@ -1145,16 +1166,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                long lenmax; 
                const unsigned char *plist;
                size_t plistlen;
-               /* If we have a custom point format list use it otherwise
-                * use default */
-               plist = s->tlsext_ecpointformatlist;
-               if (plist)
-                       plistlen = s->tlsext_ecpointformatlist_length;
-               else
-                       {
-                       plist = ecformats_default;
-                       plistlen = sizeof(ecformats_default);
-                       }
+
+               tls1_get_formatlist(s, &plist, &plistlen);
 
                if ((lenmax = limit - ret - 5) < 0) return NULL; 
                if (plistlen > (size_t)lenmax) return NULL;
@@ -1393,6 +1406,10 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
 #ifndef OPENSSL_NO_NEXTPROTONEG
        int next_proto_neg_seen;
 #endif
+       unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+       unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+       int using_ecc = (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA);
+       using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
 
        /* don't add extensions for SSLv3, unless doing secure renegotiation */
        if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
@@ -1434,25 +1451,28 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
         }
 
 #ifndef OPENSSL_NO_EC
-       if (s->tlsext_ecpointformatlist != NULL &&
-           s->version != DTLS1_VERSION)
+       if (using_ecc && s->version != DTLS1_VERSION)
                {
+               const unsigned char *plist;
+               size_t plistlen;
                /* Add TLS extension ECPointFormats to the ServerHello message */
                long lenmax; 
 
+               tls1_get_formatlist(s, &plist, &plistlen);
+
                if ((lenmax = limit - ret - 5) < 0) return NULL; 
-               if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
-               if (s->tlsext_ecpointformatlist_length > 255)
+               if (plistlen > (size_t)lenmax) return NULL;
+               if (plistlen > 255)
                        {
                        SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
                        return NULL;
                        }
                
                s2n(TLSEXT_TYPE_ec_point_formats,ret);
-               s2n(s->tlsext_ecpointformatlist_length + 1,ret);
-               *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
-               memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
-               ret+=s->tlsext_ecpointformatlist_length;
+               s2n(plistlen + 1,ret);
+               *(ret++) = (unsigned char) plistlen;
+               memcpy(ret, plist, plistlen);
+               ret+=plistlen;
 
                }
        /* Currently the server should not respond with a SupportedCurves extension */
@@ -2612,32 +2632,6 @@ int ssl_prepare_clienthello_tlsext(SSL *s)
 
 int ssl_prepare_serverhello_tlsext(SSL *s)
        {
-#ifndef OPENSSL_NO_EC
-       /* If we are server and using an ECC cipher suite, send the point formats we support 
-        * if the client sent us an ECPointsFormat extension.  Note that the server is not
-        * supposed to send an EllipticCurves extension.
-        */
-
-       unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
-       unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
-       int using_ecc = (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) || (alg_a & SSL_aECDSA);
-       using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
-       
-       if (using_ecc)
-               {
-               if (s->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->tlsext_ecpointformatlist);
-               if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL)
-                       {
-                       SSLerr(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT,ERR_R_MALLOC_FAILURE);
-                       return -1;
-                       }
-               s->tlsext_ecpointformatlist_length = 3;
-               s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed;
-               s->tlsext_ecpointformatlist[1] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
-               s->tlsext_ecpointformatlist[2] = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
-               }
-#endif /* OPENSSL_NO_EC */
-
        return 1;
        }