Replace key_exchange_info with group_id.

The only accessor for this field is the group/curve ID. Switch to only
storing that so no cipher checks are needed to interpret it. Instead,
ignore older values at parse time.

Change-Id: Id0946d4ac9e7482c69e64cc368a9d0cddf328bd3
Reviewed-on: https://boringssl-review.googlesource.com/12693
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index a12af77..defe2cc 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -119,7 +119,10 @@
  *     ocspResponse            [16] OCTET STRING OPTIONAL,
  *                                  -- stapled OCSP response from the server
  *     extendedMasterSecret    [17] BOOLEAN OPTIONAL,
- *     keyExchangeInfo         [18] INTEGER OPTIONAL,
+ *     groupID                 [18] INTEGER OPTIONAL,
+ *                                  -- For historical reasons, for legacy DHE or
+ *                                  -- static RSA ciphers, this field contains
+ *                                  -- another value to be discarded.
  *     certChain               [19] SEQUENCE OF Certificate OPTIONAL,
  *     ticketAgeAdd            [21] OCTET STRING OPTIONAL,
  *     isServer                [22] BOOLEAN DEFAULT TRUE,
@@ -165,7 +168,7 @@
     CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 16;
 static const int kExtendedMasterSecretTag =
     CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 17;
-static const int kKeyExchangeInfoTag =
+static const int kGroupIDTag =
     CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 18;
 static const int kCertChainTag =
     CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 19;
@@ -334,9 +337,9 @@
     }
   }
 
-  if (in->key_exchange_info > 0 &&
-      (!CBB_add_asn1(&session, &child, kKeyExchangeInfoTag) ||
-       !CBB_add_asn1_uint64(&child, in->key_exchange_info))) {
+  if (in->group_id > 0 &&
+      (!CBB_add_asn1(&session, &child, kGroupIDTag) ||
+       !CBB_add_asn1_uint64(&child, in->group_id))) {
     OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
     goto err;
   }
@@ -650,12 +653,24 @@
   }
   ret->extended_master_secret = !!extended_master_secret;
 
-  if (!SSL_SESSION_parse_u32(&session, &ret->key_exchange_info,
-                             kKeyExchangeInfoTag, 0)) {
+  uint32_t value;
+  if (!SSL_SESSION_parse_u32(&session, &value, kGroupIDTag, 0)) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
     goto err;
   }
 
+  /* Historically, the group_id field was used for key-exchange-specific
+   * information. Discard all but the group ID. */
+  if (ret->cipher->algorithm_mkey & (SSL_kRSA | SSL_kDHE)) {
+    value = 0;
+  }
+
+  if (value > 0xffff) {
+    OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+    goto err;
+  }
+  ret->group_id = (uint16_t)value;
+
   CBS cert_chain;
   CBS_init(&cert_chain, NULL, 0);
   int has_cert_chain;