Fix compilation with no-nextprotoneg.
[openssl.git] / ssl / t1_lib.c
index 66119d43f8de446f6e508c8a51e8f240daa2f072..8b7cce65f308963191cb582294b3458e4093587c 100644 (file)
@@ -244,7 +244,10 @@ static int nid_list[] =
                NID_secp256k1, /* secp256k1 (22) */ 
                NID_X9_62_prime256v1, /* secp256r1 (23) */ 
                NID_secp384r1, /* secp384r1 (24) */
-               NID_secp521r1  /* secp521r1 (25) */     
+               NID_secp521r1,  /* secp521r1 (25) */    
+               NID_brainpoolP256r1,  /* brainpoolP256r1 (26) */        
+               NID_brainpoolP384r1,  /* brainpoolP384r1 (27) */        
+               NID_brainpoolP512r1  /* brainpool512r1 (28) */  
        };
 
 
@@ -260,11 +263,14 @@ static const unsigned char eccurves_default[] =
                0,14, /* sect571r1 (14) */ 
                0,13, /* sect571k1 (13) */ 
                0,25, /* secp521r1 (25) */      
+               0,28, /* brainpool512r1 (28) */ 
                0,11, /* sect409k1 (11) */ 
                0,12, /* sect409r1 (12) */
+               0,27, /* brainpoolP384r1 (27) */        
                0,24, /* secp384r1 (24) */
                0,9,  /* sect283k1 (9) */
                0,10, /* sect283r1 (10) */ 
+               0,26, /* brainpoolP256r1 (26) */        
                0,22, /* secp256k1 (22) */ 
                0,23, /* secp256r1 (23) */ 
                0,8,  /* sect239k1 (8) */ 
@@ -354,6 +360,12 @@ int tls1_ec_nid2curve_id(int nid)
                return 24;
        case NID_secp521r1:  /* secp521r1 (25) */       
                return 25;
+       case NID_brainpoolP256r1:  /* brainpoolP256r1 (26) */
+               return 26;
+       case NID_brainpoolP384r1:  /* brainpoolP384r1 (27) */
+               return 27;
+       case NID_brainpoolP512r1:  /* brainpool512r1 (28) */
+               return 28;
        default:
                return 0;
                }
@@ -578,14 +590,12 @@ static int tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id,
        {
        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)
+       if (!grp)
                return 0;
         meth = EC_GROUP_method_of(grp);
        if (!meth)
@@ -613,6 +623,8 @@ static int tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id,
                }
        if (comp_id)
                {
+               if (EC_KEY_get0_public_key(ec) == NULL)
+                       return 0;
                if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED)
                        {
                        if (is_prime)
@@ -864,9 +876,6 @@ static unsigned char tls12_sigalgs[] = {
 #ifndef OPENSSL_NO_SHA
        tlsext_sigalg(TLSEXT_hash_sha1)
 #endif
-#ifndef OPENSSL_NO_MD5
-       tlsext_sigalg_rsa(TLSEXT_hash_md5)
-#endif
 };
 #ifndef OPENSSL_NO_ECDSA
 static unsigned char suiteb_sigalgs[] = {
@@ -909,13 +918,7 @@ size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs)
        else
                {
                *psigs = tls12_sigalgs;
-#ifdef OPENSSL_FIPS
-               /* If FIPS mode don't include MD5 which is last */
-               if (FIPS_mode())
-                       return sizeof(tls12_sigalgs) - 2;
-               else
-#endif
-                       return sizeof(tls12_sigalgs);
+               return sizeof(tls12_sigalgs);
                }
        }
 /* Check signature algorithm is consistent with sent supported signature
@@ -1086,19 +1089,6 @@ void ssl_set_client_disabled(SSL *s)
        c->valid = 1;
        }
 
-/* byte_compare is a compare function for qsort(3) that compares bytes. */
-static int byte_compare(const void *in_a, const void *in_b)
-       {
-       unsigned char a = *((const unsigned char*) in_a);
-       unsigned char b = *((const unsigned char*) in_b);
-
-       if (a > b)
-               return 1;
-       else if (a < b)
-               return -1;
-       return 0;
-}
-
 unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
        {
        int extdatalen=0;
@@ -1445,26 +1435,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                 ret += el;
                 }
 
-       /* Add TLS extension Server_Authz_DataFormats to the ClientHello */
-       /* 2 bytes for extension type */
-       /* 2 bytes for extension length */
-       /* 1 byte for the list length */
-       /* 1 byte for the list (we only support audit proofs) */
-       if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL)
-               {
-                const unsigned short ext_len = 2;
-                const unsigned char list_len = 1;
-
-               if (limit < ret + 6)
-                       return NULL;
-
-               s2n(TLSEXT_TYPE_server_authz, ret);
-                /* Extension length: 2 bytes */
-               s2n(ext_len, ret);
-               *(ret++) = list_len;
-               *(ret++) = TLSEXT_AUTHZDATAFORMAT_audit_proof;
-               }
-
        /* Add custom TLS Extensions to ClientHello */
        if (s->ctx->custom_cli_ext_records_count)
                {
@@ -1498,6 +1468,26 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                        ret += outlen;
                        }
                }
+#ifdef TLSEXT_TYPE_encrypt_then_mac
+       s2n(TLSEXT_TYPE_encrypt_then_mac,ret);
+       s2n(0,ret);
+#endif
+#ifdef TLSEXT_TYPE_wtf
+       {
+       /* Work out length which would be used in the TLS record:
+        * NB this should ALWAYS appear after all other extensions.
+        */
+       int hlen = ret - (unsigned char *)s->init_buf->data - 3;
+       if (hlen > 0xff && hlen < 0x200)
+               {
+               hlen = 0x200 - hlen;
+               s2n(TLSEXT_TYPE_wtf,ret);
+               s2n(hlen,ret);
+               memset(ret, 0, hlen);
+               ret += hlen;
+               }
+       }
+#endif
 
        if ((extdatalen = ret-p-2) == 0)
                return p;
@@ -1693,79 +1683,6 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
                }
 #endif
 
-       /* If the client supports authz then see whether we have any to offer
-        * to it. */
-       if (s->s3->tlsext_authz_client_types_len)
-               {
-               size_t authz_length;
-               /* By now we already know the new cipher, so we can look ahead
-                * to see whether the cert we are going to send
-                * has any authz data attached to it. */
-               const unsigned char* authz = ssl_get_authz_data(s, &authz_length);
-               const unsigned char* const orig_authz = authz;
-               size_t i;
-               unsigned authz_count = 0;
-
-               /* The authz data contains a number of the following structures:
-                *      uint8_t authz_type
-                *      uint16_t length
-                *      uint8_t data[length]
-                *
-                * First we walk over it to find the number of authz elements. */
-               for (i = 0; i < authz_length; i++)
-                       {
-                       unsigned short length;
-                       unsigned char type;
-
-                       type = *(authz++);
-                       if (memchr(s->s3->tlsext_authz_client_types,
-                                  type,
-                                  s->s3->tlsext_authz_client_types_len) != NULL)
-                               authz_count++;
-
-                       n2s(authz, length);
-                       /* n2s increments authz by 2 */
-                       i += 2;
-                       authz += length;
-                       i += length;
-                       }
-
-               if (authz_count)
-                       {
-                       /* Add TLS extension server_authz to the ServerHello message
-                        * 2 bytes for extension type
-                        * 2 bytes for extension length
-                        * 1 byte for the list length
-                        * n bytes for the list */
-                       const unsigned short ext_len = 1 + authz_count;
-
-                       if ((long)(limit - ret - 4 - ext_len) < 0) return NULL;
-                       s2n(TLSEXT_TYPE_server_authz, ret);
-                       s2n(ext_len, ret);
-                       *(ret++) = authz_count;
-                       s->s3->tlsext_authz_promised_to_client = 1;
-                       }
-
-               authz = orig_authz;
-               for (i = 0; i < authz_length; i++)
-                       {
-                       unsigned short length;
-                       unsigned char type;
-
-                       authz_count++;
-                       type = *(authz++);
-                       if (memchr(s->s3->tlsext_authz_client_types,
-                                  type,
-                                  s->s3->tlsext_authz_client_types_len) != NULL)
-                               *(ret++) = type;
-                       n2s(authz, length);
-                       /* n2s increments authz by 2 */
-                       i += 2;
-                       authz += length;
-                       i += length;
-                       }
-               }
-
        /* If custom types were sent in ClientHello, add ServerHello responses */
        if (s->s3->tlsext_custom_types_count)
                {
@@ -1806,6 +1723,21 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
                                }
                        }
                }
+#ifdef TLSEXT_TYPE_encrypt_then_mac
+       if (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC)
+               {
+               /* Don't use encrypt_then_mac if AEAD: might want
+                * to disable for other ciphersuites too.
+                */
+               if (s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD)
+                       s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
+               else
+                       {
+                       s2n(TLSEXT_TYPE_encrypt_then_mac,ret);
+                       s2n(0,ret);
+                       }
+               }
+#endif
 
        if (s->s3->alpn_selected)
                {
@@ -1956,7 +1888,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, const unsign
                return;
        data += size;
 
-       if (TLS1_get_version(s) >= TLS1_2_VERSION)
+       if (TLS1_get_client_version(s) >= TLS1_2_VERSION)
                {
                const size_t len1 = sizeof(kSafariExtensionsBlock);
                const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
@@ -1980,7 +1912,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, const unsign
 
        s->s3->is_probably_safari = 1;
 }
-#endif /* OPENSSL_NO_EC */
+#endif /* !OPENSSL_NO_EC */
 
 static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) 
        {       
@@ -2019,7 +1951,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
 #ifndef OPENSSL_NO_EC
        if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
                ssl_check_for_safari(s, data, d, n);
-#endif /* OPENSSL_NO_EC */
+#endif /* !OPENSSL_NO_EC */
 
        /* Clear any signature algorithms extension received */
        if (s->cert->peer_sigalgs)
@@ -2040,6 +1972,10 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
                s->cert->pkeys[i].valid_flags = 0;
                }
 
+#ifdef TLSEXT_TYPE_encrypt_then_mac
+       s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
+#endif
+
        if (data >= (d+n-2))
                goto ri_check;
        n2s(data,len);
@@ -2500,8 +2436,10 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
                        {
                        if (tls1_alpn_handle_client_hello(s, data, size, al) != 0)
                                return 0;
+#ifndef OPENSSL_NO_NEXTPROTONEG
                        /* ALPN takes precedence over NPN. */
                        s->s3->next_proto_neg_seen = 0;
+#endif
                        }
 
                /* session ticket processed earlier */
@@ -2511,66 +2449,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
                                                              al))
                                return 0;
                         }
-
-               else if (type == TLSEXT_TYPE_server_authz)
-                       {
-                       unsigned char *sdata = data;
-                       unsigned char server_authz_dataformatlist_length;
-
-                       if (size == 0)
-                               {
-                               *al = TLS1_AD_DECODE_ERROR;
-                               return 0;
-                               }
-
-                       server_authz_dataformatlist_length = *(sdata++);
-
-                       if (server_authz_dataformatlist_length != size - 1)
-                               {
-                               *al = TLS1_AD_DECODE_ERROR;
-                               return 0;
-                               }
-
-                       /* Successful session resumption uses the same authz
-                        * information as the original session so we ignore this
-                        * in the case of a session resumption. */
-                       if (!s->hit)
-                               {
-                               if (s->s3->tlsext_authz_client_types != NULL)
-                                       OPENSSL_free(s->s3->tlsext_authz_client_types);
-                               s->s3->tlsext_authz_client_types =
-                                       OPENSSL_malloc(server_authz_dataformatlist_length);
-                               if (!s->s3->tlsext_authz_client_types)
-                                       {
-                                       *al = TLS1_AD_INTERNAL_ERROR;
-                                       return 0;
-                                       }
-
-                               s->s3->tlsext_authz_client_types_len =
-                                       server_authz_dataformatlist_length;
-                               memcpy(s->s3->tlsext_authz_client_types,
-                                      sdata,
-                                      server_authz_dataformatlist_length);
-
-                               /* Sort the types in order to check for duplicates. */
-                               qsort(s->s3->tlsext_authz_client_types,
-                                     server_authz_dataformatlist_length,
-                                     1 /* element size */,
-                                     byte_compare);
-
-                               for (i = 0; i < server_authz_dataformatlist_length; i++)
-                                       {
-                                       if (i > 0 &&
-                                           s->s3->tlsext_authz_client_types[i] ==
-                                             s->s3->tlsext_authz_client_types[i-1])
-                                               {
-                                               *al = TLS1_AD_DECODE_ERROR;
-                                               return 0;
-                                               }
-                                       }
-                               }
-                       }
-
                /* If this ClientHello extension was unhandled and this is 
                 * a nonresumed connection, check whether the extension is a 
                 * custom TLS Extension (has a custom_srv_ext_record), and if
@@ -2618,6 +2496,10 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char
                                        }                                               
                                }
                        }
+#ifdef TLSEXT_TYPE_encrypt_then_mac
+               else if (type == TLSEXT_TYPE_encrypt_then_mac)
+                       s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
+#endif
 
                data+=size;
                }
@@ -2704,6 +2586,10 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
                               SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
 #endif
 
+#ifdef TLSEXT_TYPE_encrypt_then_mac
+       s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
+#endif
+
        if (data >= (d+n-2))
                goto ri_check;
 
@@ -2936,46 +2822,6 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
                                                              al))
                                 return 0;
                         }
-
-               else if (type == TLSEXT_TYPE_server_authz)
-                       {
-                       /* We only support audit proofs. It's an error to send
-                        * an authz hello extension if the client
-                        * didn't request a proof. */
-                       unsigned char *sdata = data;
-                       unsigned char server_authz_dataformatlist_length;
-
-                       if (!s->ctx->tlsext_authz_server_audit_proof_cb)
-                               {
-                               *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-                               return 0;
-                               }
-
-                       if (!size)
-                               {
-                               *al = TLS1_AD_DECODE_ERROR;
-                               return 0;
-                               }
-
-                       server_authz_dataformatlist_length = *(sdata++);
-                       if (server_authz_dataformatlist_length != size - 1)
-                               {
-                               *al = TLS1_AD_DECODE_ERROR;
-                               return 0;
-                               }
-
-                       /* We only support audit proofs, so a legal ServerHello
-                        * authz list contains exactly one entry. */
-                       if (server_authz_dataformatlist_length != 1 ||
-                               sdata[0] != TLSEXT_AUTHZDATAFORMAT_audit_proof)
-                               {
-                               *al = TLS1_AD_UNSUPPORTED_EXTENSION;
-                               return 0;
-                               }
-
-                       s->s3->tlsext_authz_server_promised = 1;
-                       }
-
                /* If this extension type was not otherwise handled, but 
                 * matches a custom_cli_ext_record, then send it to the c
                 * callback */
@@ -2995,6 +2841,14 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char
                                        }
                                }                       
                        }
+#ifdef TLSEXT_TYPE_encrypt_then_mac
+               else if (type == TLSEXT_TYPE_encrypt_then_mac)
+                       {
+                       /* Ignore if inappropriate ciphersuite */
+                       if (s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD)
+                               s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC;
+                       }
+#endif
  
                data += size;
                }