src/java.base/share/classes/sun/security/ssl/SupportedGroupsExtension.java
changeset 55353 946f7f2d321c
parent 53734 cb1642ccc732
child 57718 a93b7b28f644
equal deleted inserted replaced
55352:1357c4996b2e 55353:946f7f2d321c
    28 import java.io.IOException;
    28 import java.io.IOException;
    29 import java.nio.ByteBuffer;
    29 import java.nio.ByteBuffer;
    30 import java.security.AlgorithmConstraints;
    30 import java.security.AlgorithmConstraints;
    31 import java.security.AlgorithmParameters;
    31 import java.security.AlgorithmParameters;
    32 import java.security.CryptoPrimitive;
    32 import java.security.CryptoPrimitive;
    33 import java.security.NoSuchAlgorithmException;
       
    34 import java.security.spec.AlgorithmParameterSpec;
       
    35 import java.security.spec.ECGenParameterSpec;
    33 import java.security.spec.ECGenParameterSpec;
    36 import java.security.spec.ECParameterSpec;
       
    37 import java.security.spec.InvalidParameterSpecException;
    34 import java.security.spec.InvalidParameterSpecException;
    38 import java.text.MessageFormat;
    35 import java.text.MessageFormat;
    39 import java.util.ArrayList;
    36 import java.util.ArrayList;
    40 import java.util.Collections;
    37 import java.util.Collections;
    41 import java.util.EnumSet;
    38 import java.util.EnumSet;
    42 import java.util.HashMap;
       
    43 import java.util.LinkedList;
    39 import java.util.LinkedList;
    44 import java.util.List;
    40 import java.util.List;
    45 import java.util.Locale;
    41 import java.util.Locale;
    46 import java.util.Map;
       
    47 import javax.crypto.spec.DHParameterSpec;
       
    48 import javax.net.ssl.SSLProtocolException;
    42 import javax.net.ssl.SSLProtocolException;
    49 import sun.security.action.GetPropertyAction;
    43 import sun.security.action.GetPropertyAction;
       
    44 import sun.security.ssl.NamedGroup.NamedGroupType;
    50 import static sun.security.ssl.SSLExtension.CH_SUPPORTED_GROUPS;
    45 import static sun.security.ssl.SSLExtension.CH_SUPPORTED_GROUPS;
    51 import static sun.security.ssl.SSLExtension.EE_SUPPORTED_GROUPS;
    46 import static sun.security.ssl.SSLExtension.EE_SUPPORTED_GROUPS;
    52 import sun.security.ssl.SSLExtension.ExtensionConsumer;
    47 import sun.security.ssl.SSLExtension.ExtensionConsumer;
    53 import sun.security.ssl.SSLExtension.SSLExtensionSpec;
    48 import sun.security.ssl.SSLExtension.SSLExtensionSpec;
    54 import sun.security.ssl.SSLHandshake.HandshakeMessage;
    49 import sun.security.ssl.SSLHandshake.HandshakeMessage;
    55 import sun.security.util.ECUtil;
    50 
    56 
    51 
    57 /**
    52 /**
    58  * Pack of the "supported_groups" extensions [RFC 4492/7919].
    53  * Pack of the "supported_groups" extensions [RFC 4492/7919].
    59  */
    54  */
    60 final class SupportedGroupsExtension {
    55 final class SupportedGroupsExtension {
   156                 return ioe.getMessage();
   151                 return ioe.getMessage();
   157             }
   152             }
   158         }
   153         }
   159     }
   154     }
   160 
   155 
   161     static enum NamedGroupType {
       
   162         NAMED_GROUP_ECDHE     ("EC"),
       
   163         NAMED_GROUP_FFDHE     ("DiffieHellman"),
       
   164         NAMED_GROUP_X25519    ("x25519"),
       
   165         NAMED_GROUP_X448      ("x448"),
       
   166         NAMED_GROUP_ARBITRARY ("EC"),
       
   167         NAMED_GROUP_NONE      ("");
       
   168 
       
   169         private final String algorithm;
       
   170 
       
   171         private NamedGroupType(String algorithm) {
       
   172             this.algorithm = algorithm;
       
   173         }
       
   174 
       
   175         boolean isSupported(List<CipherSuite> cipherSuites) {
       
   176             for (CipherSuite cs : cipherSuites) {
       
   177                 if (cs.keyExchange == null ||
       
   178                         cs.keyExchange.groupType == this) {
       
   179                     return true;
       
   180                 }
       
   181             }
       
   182 
       
   183             return false;
       
   184         }
       
   185     }
       
   186 
       
   187     static enum NamedGroup {
       
   188         // Elliptic Curves (RFC 4492)
       
   189         //
       
   190         // See sun.security.util.CurveDB for the OIDs
       
   191         // NIST K-163
       
   192         SECT163_K1  (0x0001, "sect163k1", "1.3.132.0.1",
       
   193                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   194                             ProtocolVersion.PROTOCOLS_TO_12),
       
   195         SECT163_R1  (0x0002, "sect163r1", "1.3.132.0.2",
       
   196                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   197                             ProtocolVersion.PROTOCOLS_TO_12),
       
   198 
       
   199         // NIST B-163
       
   200         SECT163_R2  (0x0003, "sect163r2", "1.3.132.0.15",
       
   201                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   202                             ProtocolVersion.PROTOCOLS_TO_12),
       
   203         SECT193_R1  (0x0004, "sect193r1", "1.3.132.0.24",
       
   204                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   205                             ProtocolVersion.PROTOCOLS_TO_12),
       
   206         SECT193_R2  (0x0005, "sect193r2", "1.3.132.0.25",
       
   207                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   208                             ProtocolVersion.PROTOCOLS_TO_12),
       
   209 
       
   210         // NIST K-233
       
   211         SECT233_K1  (0x0006, "sect233k1", "1.3.132.0.26",
       
   212                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   213                             ProtocolVersion.PROTOCOLS_TO_12),
       
   214 
       
   215         // NIST B-233
       
   216         SECT233_R1  (0x0007, "sect233r1", "1.3.132.0.27",
       
   217                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   218                             ProtocolVersion.PROTOCOLS_TO_12),
       
   219         SECT239_K1  (0x0008, "sect239k1", "1.3.132.0.3",
       
   220                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   221                             ProtocolVersion.PROTOCOLS_TO_12),
       
   222 
       
   223         // NIST K-283
       
   224         SECT283_K1  (0x0009, "sect283k1", "1.3.132.0.16",
       
   225                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   226                             ProtocolVersion.PROTOCOLS_TO_12),
       
   227 
       
   228         // NIST B-283
       
   229         SECT283_R1  (0x000A, "sect283r1", "1.3.132.0.17",
       
   230                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   231                             ProtocolVersion.PROTOCOLS_TO_12),
       
   232 
       
   233         // NIST K-409
       
   234         SECT409_K1  (0x000B, "sect409k1", "1.3.132.0.36",
       
   235                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   236                             ProtocolVersion.PROTOCOLS_TO_12),
       
   237 
       
   238         // NIST B-409
       
   239         SECT409_R1  (0x000C, "sect409r1", "1.3.132.0.37",
       
   240                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   241                             ProtocolVersion.PROTOCOLS_TO_12),
       
   242 
       
   243         // NIST K-571
       
   244         SECT571_K1  (0x000D, "sect571k1", "1.3.132.0.38",
       
   245                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   246                             ProtocolVersion.PROTOCOLS_TO_12),
       
   247 
       
   248         // NIST B-571
       
   249         SECT571_R1  (0x000E, "sect571r1", "1.3.132.0.39",
       
   250                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   251                             ProtocolVersion.PROTOCOLS_TO_12),
       
   252         SECP160_K1  (0x000F, "secp160k1", "1.3.132.0.9",
       
   253                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   254                             ProtocolVersion.PROTOCOLS_TO_12),
       
   255         SECP160_R1  (0x0010, "secp160r1", "1.3.132.0.8",
       
   256                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   257                             ProtocolVersion.PROTOCOLS_TO_12),
       
   258         SECP160_R2  (0x0011, "secp160r2", "1.3.132.0.30",
       
   259                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   260                             ProtocolVersion.PROTOCOLS_TO_12),
       
   261         SECP192_K1  (0x0012, "secp192k1", "1.3.132.0.31",
       
   262                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   263                             ProtocolVersion.PROTOCOLS_TO_12),
       
   264 
       
   265         // NIST P-192
       
   266         SECP192_R1  (0x0013, "secp192r1", "1.2.840.10045.3.1.1",
       
   267                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   268                             ProtocolVersion.PROTOCOLS_TO_12),
       
   269         SECP224_K1  (0x0014, "secp224k1", "1.3.132.0.32",
       
   270                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   271                             ProtocolVersion.PROTOCOLS_TO_12),
       
   272         // NIST P-224
       
   273         SECP224_R1  (0x0015, "secp224r1", "1.3.132.0.33",
       
   274                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   275                             ProtocolVersion.PROTOCOLS_TO_12),
       
   276         SECP256_K1  (0x0016, "secp256k1", "1.3.132.0.10",
       
   277                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   278                             ProtocolVersion.PROTOCOLS_TO_12),
       
   279 
       
   280         // NIST P-256
       
   281         SECP256_R1  (0x0017, "secp256r1", "1.2.840.10045.3.1.7",
       
   282                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   283                             ProtocolVersion.PROTOCOLS_TO_13),
       
   284 
       
   285         // NIST P-384
       
   286         SECP384_R1  (0x0018, "secp384r1", "1.3.132.0.34",
       
   287                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   288                             ProtocolVersion.PROTOCOLS_TO_13),
       
   289 
       
   290         // NIST P-521
       
   291         SECP521_R1  (0x0019, "secp521r1", "1.3.132.0.35",
       
   292                             NamedGroupType.NAMED_GROUP_ECDHE,
       
   293                             ProtocolVersion.PROTOCOLS_TO_13),
       
   294 
       
   295         // x25519 and x448
       
   296         X25519      (0x001D, "x25519", null,
       
   297                             NamedGroupType.NAMED_GROUP_X25519,
       
   298                             ProtocolVersion.PROTOCOLS_TO_13),
       
   299         X448        (0x001E, "x448", null,
       
   300                             NamedGroupType.NAMED_GROUP_X448,
       
   301                             ProtocolVersion.PROTOCOLS_TO_13),
       
   302 
       
   303         // Finite Field Diffie-Hellman Ephemeral Parameters (RFC 7919)
       
   304         FFDHE_2048  (0x0100, "ffdhe2048", null,
       
   305                             NamedGroupType.NAMED_GROUP_FFDHE,
       
   306                             ProtocolVersion.PROTOCOLS_TO_13),
       
   307         FFDHE_3072  (0x0101, "ffdhe3072", null,
       
   308                             NamedGroupType.NAMED_GROUP_FFDHE,
       
   309                             ProtocolVersion.PROTOCOLS_TO_13),
       
   310         FFDHE_4096  (0x0102, "ffdhe4096", null,
       
   311                             NamedGroupType.NAMED_GROUP_FFDHE,
       
   312                             ProtocolVersion.PROTOCOLS_TO_13),
       
   313         FFDHE_6144  (0x0103, "ffdhe6144", null,
       
   314                             NamedGroupType.NAMED_GROUP_FFDHE,
       
   315                             ProtocolVersion.PROTOCOLS_TO_13),
       
   316         FFDHE_8192  (0x0104, "ffdhe8192", null,
       
   317                             NamedGroupType.NAMED_GROUP_FFDHE,
       
   318                             ProtocolVersion.PROTOCOLS_TO_13),
       
   319 
       
   320         // Elliptic Curves (RFC 4492)
       
   321         //
       
   322         // arbitrary prime and characteristic-2 curves
       
   323         ARBITRARY_PRIME  (0xFF01, "arbitrary_explicit_prime_curves", null,
       
   324                             NamedGroupType.NAMED_GROUP_ARBITRARY,
       
   325                             ProtocolVersion.PROTOCOLS_TO_12),
       
   326         ARBITRARY_CHAR2  (0xFF02, "arbitrary_explicit_char2_curves", null,
       
   327                             NamedGroupType.NAMED_GROUP_ARBITRARY,
       
   328                             ProtocolVersion.PROTOCOLS_TO_12);
       
   329 
       
   330         final int id;               // hash + signature
       
   331         final NamedGroupType type;  // group type
       
   332         final String name;          // literal name
       
   333         final String oid;           // object identifier of the named group
       
   334         final String algorithm;     // signature algorithm
       
   335         final ProtocolVersion[] supportedProtocols;
       
   336 
       
   337         private NamedGroup(int id, String name, String oid,
       
   338                 NamedGroupType namedGroupType,
       
   339                 ProtocolVersion[] supportedProtocols) {
       
   340             this.id = id;
       
   341             this.type = namedGroupType;
       
   342             this.name = name;
       
   343             this.oid = oid;
       
   344             this.algorithm = namedGroupType.algorithm;
       
   345             this.supportedProtocols = supportedProtocols;
       
   346         }
       
   347 
       
   348         static NamedGroup valueOf(int id) {
       
   349             for (NamedGroup group : NamedGroup.values()) {
       
   350                 if (group.id == id) {
       
   351                     return group;
       
   352                 }
       
   353             }
       
   354 
       
   355             return null;
       
   356         }
       
   357 
       
   358         static NamedGroup valueOf(ECParameterSpec params) {
       
   359             String oid = ECUtil.getCurveName(null, params);
       
   360             if ((oid != null) && (!oid.isEmpty())) {
       
   361                 for (NamedGroup group : NamedGroup.values()) {
       
   362                     if ((group.type == NamedGroupType.NAMED_GROUP_ECDHE) &&
       
   363                             oid.equals(group.oid)) {
       
   364                         return group;
       
   365                     }
       
   366                 }
       
   367             }
       
   368 
       
   369             return null;
       
   370         }
       
   371 
       
   372         static NamedGroup valueOf(DHParameterSpec params) {
       
   373             for (Map.Entry<NamedGroup, AlgorithmParameters> me :
       
   374                     SupportedGroups.namedGroupParams.entrySet()) {
       
   375                 NamedGroup ng = me.getKey();
       
   376                 if (ng.type != NamedGroupType.NAMED_GROUP_FFDHE) {
       
   377                     continue;
       
   378                 }
       
   379 
       
   380                 DHParameterSpec ngParams = null;
       
   381                 AlgorithmParameters aps = me.getValue();
       
   382                 try {
       
   383                     ngParams = aps.getParameterSpec(DHParameterSpec.class);
       
   384                 } catch (InvalidParameterSpecException ipse) {
       
   385                     // should be unlikely
       
   386                 }
       
   387 
       
   388                 if (ngParams == null) {
       
   389                     continue;
       
   390                 }
       
   391 
       
   392                 if (ngParams.getP().equals(params.getP()) &&
       
   393                         ngParams.getG().equals(params.getG())) {
       
   394                     return ng;
       
   395                 }
       
   396             }
       
   397 
       
   398             return null;
       
   399         }
       
   400 
       
   401         static NamedGroup nameOf(String name) {
       
   402             for (NamedGroup group : NamedGroup.values()) {
       
   403                 if (group.name.equals(name)) {
       
   404                     return group;
       
   405                 }
       
   406             }
       
   407 
       
   408             return null;
       
   409         }
       
   410 
       
   411         static String nameOf(int id) {
       
   412             for (NamedGroup group : NamedGroup.values()) {
       
   413                 if (group.id == id) {
       
   414                     return group.name;
       
   415                 }
       
   416             }
       
   417 
       
   418             return "UNDEFINED-NAMED-GROUP(" + id + ")";
       
   419         }
       
   420 
       
   421         boolean isAvailable(List<ProtocolVersion> protocolVersions) {
       
   422             for (ProtocolVersion pv : supportedProtocols) {
       
   423                 if (protocolVersions.contains(pv)) {
       
   424                     return true;
       
   425                 }
       
   426             }
       
   427             return false;
       
   428         }
       
   429 
       
   430         boolean isAvailable(ProtocolVersion protocolVersion) {
       
   431             for (ProtocolVersion pv : supportedProtocols) {
       
   432                 if (protocolVersion == pv) {
       
   433                     return true;
       
   434                 }
       
   435             }
       
   436             return false;
       
   437         }
       
   438 
       
   439         boolean isSupported(List<CipherSuite> cipherSuites) {
       
   440             for (CipherSuite cs : cipherSuites) {
       
   441                 boolean isMatch = isAvailable(cs.supportedProtocols);
       
   442                 if (isMatch && (cs.keyExchange == null ||
       
   443                         cs.keyExchange.groupType == type)) {
       
   444                     return true;
       
   445                 }
       
   446             }
       
   447             return false;
       
   448         }
       
   449 
       
   450         // lazy loading of parameters
       
   451         AlgorithmParameters getParameters() {
       
   452             return SupportedGroups.namedGroupParams.get(this);
       
   453         }
       
   454 
       
   455         AlgorithmParameterSpec getParameterSpec() {
       
   456             if (this.type == NamedGroupType.NAMED_GROUP_ECDHE) {
       
   457                 return SupportedGroups.getECGenParamSpec(this);
       
   458             } else if (this.type == NamedGroupType.NAMED_GROUP_FFDHE) {
       
   459                 return SupportedGroups.getDHParameterSpec(this);
       
   460             }
       
   461 
       
   462             return null;
       
   463         }
       
   464     }
       
   465 
       
   466     static class SupportedGroups {
   156     static class SupportedGroups {
   467         // To switch off the supported_groups extension for DHE cipher suite.
   157         // To switch off the supported_groups extension for DHE cipher suite.
   468         static final boolean enableFFDHE =
   158         static final boolean enableFFDHE =
   469                 Utilities.getBooleanProperty("jsse.enableFFDHE", true);
   159                 Utilities.getBooleanProperty("jsse.enableFFDHE", true);
   470 
       
   471         // cache to speed up the parameters construction
       
   472         static final Map<NamedGroup,
       
   473                     AlgorithmParameters> namedGroupParams = new HashMap<>();
       
   474 
   160 
   475         // the supported named groups
   161         // the supported named groups
   476         static final NamedGroup[] supportedNamedGroups;
   162         static final NamedGroup[] supportedNamedGroups;
   477 
   163 
   478         static {
   164         static {
   514                             "System property jdk.tls.namedGroups(" +
   200                             "System property jdk.tls.namedGroups(" +
   515                             property + ") contains no supported named groups");
   201                             property + ") contains no supported named groups");
   516                 }
   202                 }
   517             } else {        // default groups
   203             } else {        // default groups
   518                 NamedGroup[] groups = new NamedGroup[] {
   204                 NamedGroup[] groups = new NamedGroup[] {
   519                         // NIST curves first
   205 
       
   206                         // Primary XDH (RFC 7748) curves
       
   207                         NamedGroup.X25519,
       
   208 
       
   209                         // Primary NIST curves (e.g. used in TLSv1.3)
   520                         NamedGroup.SECP256_R1,
   210                         NamedGroup.SECP256_R1,
   521                         NamedGroup.SECP384_R1,
   211                         NamedGroup.SECP384_R1,
   522                         NamedGroup.SECP521_R1,
   212                         NamedGroup.SECP521_R1,
       
   213 
       
   214                         // Secondary XDH curves
       
   215                         NamedGroup.X448,
       
   216 
       
   217                         // Secondary NIST curves
   523                         NamedGroup.SECT283_K1,
   218                         NamedGroup.SECT283_K1,
   524                         NamedGroup.SECT283_R1,
   219                         NamedGroup.SECT283_R1,
   525                         NamedGroup.SECT409_K1,
   220                         NamedGroup.SECT409_K1,
   526                         NamedGroup.SECT409_R1,
   221                         NamedGroup.SECT409_R1,
   527                         NamedGroup.SECT571_K1,
   222                         NamedGroup.SECT571_K1,
   528                         NamedGroup.SECT571_R1,
   223                         NamedGroup.SECT571_R1,
   529 
   224 
   530                         // non-NIST curves
   225                         // non-NIST curves
   531                         NamedGroup.SECP256_K1,
   226                         NamedGroup.SECP256_K1,
   532 
   227 
   533                         // FFDHE 2048
   228                         // FFDHE (RFC 7919)
   534                         NamedGroup.FFDHE_2048,
   229                         NamedGroup.FFDHE_2048,
   535                         NamedGroup.FFDHE_3072,
   230                         NamedGroup.FFDHE_3072,
   536                         NamedGroup.FFDHE_4096,
   231                         NamedGroup.FFDHE_4096,
   537                         NamedGroup.FFDHE_6144,
   232                         NamedGroup.FFDHE_6144,
   538                         NamedGroup.FFDHE_8192,
   233                         NamedGroup.FFDHE_8192,
   558             }
   253             }
   559         }
   254         }
   560 
   255 
   561         // check whether the group is supported by the underlying providers
   256         // check whether the group is supported by the underlying providers
   562         private static boolean isAvailableGroup(NamedGroup namedGroup) {
   257         private static boolean isAvailableGroup(NamedGroup namedGroup) {
   563             AlgorithmParameters params = null;
   258             return namedGroup.isAvailableGroup();
   564             AlgorithmParameterSpec spec = null;
   259         }
   565             if (namedGroup.type == NamedGroupType.NAMED_GROUP_ECDHE) {
   260 
   566                 if (namedGroup.oid != null) {
   261         static ECGenParameterSpec getECGenParamSpec(NamedGroup ng) {
   567                     try {
   262             if (ng.type != NamedGroupType.NAMED_GROUP_ECDHE) {
   568                         params = AlgorithmParameters.getInstance("EC");
   263                  throw new RuntimeException(
   569                         spec = new ECGenParameterSpec(namedGroup.oid);
   264                          "Not a named EC group: " + ng);
   570                     } catch (NoSuchAlgorithmException e) {
   265             }
   571                         return false;
   266 
   572                     }
   267             // parameters are non-null
   573                 }
   268             AlgorithmParameters params = ng.getParameters();
   574             } else if (namedGroup.type == NamedGroupType.NAMED_GROUP_FFDHE) {
       
   575                 try {
       
   576                     params = AlgorithmParameters.getInstance("DiffieHellman");
       
   577                     spec = getFFDHEDHParameterSpec(namedGroup);
       
   578                 } catch (NoSuchAlgorithmException e) {
       
   579                     return false;
       
   580                 }
       
   581             }   // Otherwise, unsupported.
       
   582 
       
   583             if ((params != null) && (spec != null)) {
       
   584                 try {
       
   585                     params.init(spec);
       
   586                 } catch (InvalidParameterSpecException e) {
       
   587                     return false;
       
   588                 }
       
   589 
       
   590                 // cache the parameters
       
   591                 namedGroupParams.put(namedGroup, params);
       
   592 
       
   593                 return true;
       
   594             }
       
   595 
       
   596             return false;
       
   597         }
       
   598 
       
   599         private static DHParameterSpec getFFDHEDHParameterSpec(
       
   600                 NamedGroup namedGroup) {
       
   601             DHParameterSpec spec = null;
       
   602             switch (namedGroup) {
       
   603                 case FFDHE_2048:
       
   604                     spec = PredefinedDHParameterSpecs.ffdheParams.get(2048);
       
   605                     break;
       
   606                 case FFDHE_3072:
       
   607                     spec = PredefinedDHParameterSpecs.ffdheParams.get(3072);
       
   608                     break;
       
   609                 case FFDHE_4096:
       
   610                     spec = PredefinedDHParameterSpecs.ffdheParams.get(4096);
       
   611                     break;
       
   612                 case FFDHE_6144:
       
   613                     spec = PredefinedDHParameterSpecs.ffdheParams.get(6144);
       
   614                     break;
       
   615                 case FFDHE_8192:
       
   616                     spec = PredefinedDHParameterSpecs.ffdheParams.get(8192);
       
   617             }
       
   618 
       
   619             return spec;
       
   620         }
       
   621 
       
   622         private static DHParameterSpec getPredefinedDHParameterSpec(
       
   623                 NamedGroup namedGroup) {
       
   624             DHParameterSpec spec = null;
       
   625             switch (namedGroup) {
       
   626                 case FFDHE_2048:
       
   627                     spec = PredefinedDHParameterSpecs.definedParams.get(2048);
       
   628                     break;
       
   629                 case FFDHE_3072:
       
   630                     spec = PredefinedDHParameterSpecs.definedParams.get(3072);
       
   631                     break;
       
   632                 case FFDHE_4096:
       
   633                     spec = PredefinedDHParameterSpecs.definedParams.get(4096);
       
   634                     break;
       
   635                 case FFDHE_6144:
       
   636                     spec = PredefinedDHParameterSpecs.definedParams.get(6144);
       
   637                     break;
       
   638                 case FFDHE_8192:
       
   639                     spec = PredefinedDHParameterSpecs.definedParams.get(8192);
       
   640             }
       
   641 
       
   642             return spec;
       
   643         }
       
   644 
       
   645         static ECGenParameterSpec getECGenParamSpec(NamedGroup namedGroup) {
       
   646             if (namedGroup.type != NamedGroupType.NAMED_GROUP_ECDHE) {
       
   647                 throw new RuntimeException(
       
   648                         "Not a named EC group: " + namedGroup);
       
   649             }
       
   650 
       
   651             AlgorithmParameters params = namedGroupParams.get(namedGroup);
       
   652             if (params == null) {
       
   653                 throw new RuntimeException(
       
   654                         "Not a supported EC named group: " + namedGroup);
       
   655             }
       
   656 
       
   657             try {
   269             try {
   658                 return params.getParameterSpec(ECGenParameterSpec.class);
   270                 return params.getParameterSpec(ECGenParameterSpec.class);
   659             } catch (InvalidParameterSpecException ipse) {
   271             } catch (InvalidParameterSpecException ipse) {
   660                 // should be unlikely
   272                 // should be unlikely
   661                 return new ECGenParameterSpec(namedGroup.oid);
   273                 return new ECGenParameterSpec(ng.oid);
   662             }
   274             }
   663         }
   275         }
   664 
   276 
   665         static DHParameterSpec getDHParameterSpec(NamedGroup namedGroup) {
   277         static AlgorithmParameters getParameters(NamedGroup ng) {
   666             if (namedGroup.type != NamedGroupType.NAMED_GROUP_FFDHE) {
   278             return ng.getParameters();
   667                 throw new RuntimeException(
       
   668                         "Not a named DH group: " + namedGroup);
       
   669             }
       
   670 
       
   671             AlgorithmParameters params = namedGroupParams.get(namedGroup);
       
   672             if (params == null) {
       
   673                 throw new RuntimeException(
       
   674                         "Not a supported DH named group: " + namedGroup);
       
   675             }
       
   676 
       
   677             try {
       
   678                 return params.getParameterSpec(DHParameterSpec.class);
       
   679             } catch (InvalidParameterSpecException ipse) {
       
   680                 // should be unlikely
       
   681                 return getPredefinedDHParameterSpec(namedGroup);
       
   682             }
       
   683         }
   279         }
   684 
   280 
   685         // Is there any supported group permitted by the constraints?
   281         // Is there any supported group permitted by the constraints?
   686         static boolean isActivatable(
   282         static boolean isActivatable(
   687                 AlgorithmConstraints constraints, NamedGroupType type) {
   283                 AlgorithmConstraints constraints, NamedGroupType type) {
   690             for (NamedGroup namedGroup : supportedNamedGroups) {
   286             for (NamedGroup namedGroup : supportedNamedGroups) {
   691                 if (namedGroup.type == type) {
   287                 if (namedGroup.type == type) {
   692                     if (constraints.permits(
   288                     if (constraints.permits(
   693                             EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
   289                             EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
   694                             namedGroup.algorithm,
   290                             namedGroup.algorithm,
   695                             namedGroupParams.get(namedGroup))) {
   291                             getParameters(namedGroup))) {
   696 
   292 
   697                         return true;
   293                         return true;
   698                     }
   294                     }
   699 
   295 
   700                     if (!hasFFDHEGroups &&
   296                     if (!hasFFDHEGroups &&
   721             }
   317             }
   722 
   318 
   723             return constraints.permits(
   319             return constraints.permits(
   724                             EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
   320                             EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
   725                             namedGroup.algorithm,
   321                             namedGroup.algorithm,
   726                             namedGroupParams.get(namedGroup));
   322                             getParameters(namedGroup));
   727         }
   323         }
   728 
   324 
   729         // Is the named group supported?
   325         // Is the named group supported?
   730         static boolean isSupported(NamedGroup namedGroup) {
   326         static boolean isSupported(NamedGroup namedGroup) {
   731             for (NamedGroup group : supportedNamedGroups) {
   327             for (NamedGroup group : supportedNamedGroups) {
   737             return false;
   333             return false;
   738         }
   334         }
   739 
   335 
   740         static NamedGroup getPreferredGroup(
   336         static NamedGroup getPreferredGroup(
   741                 ProtocolVersion negotiatedProtocol,
   337                 ProtocolVersion negotiatedProtocol,
   742                 AlgorithmConstraints constraints, NamedGroupType type,
   338                 AlgorithmConstraints constraints, NamedGroupType[] types,
   743                 List<NamedGroup> requestedNamedGroups) {
   339                 List<NamedGroup> requestedNamedGroups) {
   744             for (NamedGroup namedGroup : requestedNamedGroups) {
   340             for (NamedGroup namedGroup : requestedNamedGroups) {
   745                 if ((namedGroup.type == type) &&
   341                 if ((NamedGroupType.arrayContains(types, namedGroup.type)) &&
   746                         namedGroup.isAvailable(negotiatedProtocol) &&
   342                         namedGroup.isAvailable(negotiatedProtocol) &&
   747                         isSupported(namedGroup) &&
   343                         isSupported(namedGroup) &&
   748                         constraints.permits(
   344                         constraints.permits(
   749                                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
   345                                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
   750                                 namedGroup.algorithm,
   346                                 namedGroup.algorithm,
   751                                 namedGroupParams.get(namedGroup))) {
   347                                 getParameters(namedGroup))) {
   752                     return namedGroup;
   348                     return namedGroup;
   753                 }
   349                 }
   754             }
   350             }
   755 
   351 
   756             return null;
   352             return null;
   757         }
   353         }
   758 
   354 
   759         static NamedGroup getPreferredGroup(
   355         static NamedGroup getPreferredGroup(
   760                 ProtocolVersion negotiatedProtocol,
   356                 ProtocolVersion negotiatedProtocol,
   761                 AlgorithmConstraints constraints, NamedGroupType type) {
   357                 AlgorithmConstraints constraints, NamedGroupType[] types) {
   762             for (NamedGroup namedGroup : supportedNamedGroups) {
   358             for (NamedGroup namedGroup : supportedNamedGroups) {
   763                 if ((namedGroup.type == type) &&
   359                 if ((NamedGroupType.arrayContains(types, namedGroup.type)) &&
   764                         namedGroup.isAvailable(negotiatedProtocol) &&
   360                         namedGroup.isAvailable(negotiatedProtocol) &&
   765                         constraints.permits(
   361                         constraints.permits(
   766                                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
   362                                 EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
   767                                 namedGroup.algorithm,
   363                                 namedGroup.algorithm,
   768                                 namedGroupParams.get(namedGroup))) {
   364                                 getParameters(namedGroup))) {
   769                     return namedGroup;
   365                     return namedGroup;
   770                 }
   366                 }
   771             }
   367             }
   772 
   368 
   773             return null;
   369             return null;
   811 
   407 
   812                 if (ng.isAvailable(chc.activeProtocols) &&
   408                 if (ng.isAvailable(chc.activeProtocols) &&
   813                         ng.isSupported(chc.activeCipherSuites) &&
   409                         ng.isSupported(chc.activeCipherSuites) &&
   814                         chc.algorithmConstraints.permits(
   410                         chc.algorithmConstraints.permits(
   815                             EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
   411                             EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
   816                             ng.algorithm, namedGroupParams.get(ng))) {
   412                             ng.algorithm, getParameters(ng))) {
   817                     namedGroups.add(ng);
   413                     namedGroups.add(ng);
   818                 } else if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
   414                 } else if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
   819                     SSLLogger.fine(
   415                     SSLLogger.fine(
   820                         "Ignore inactive or disabled named group: " + ng.name);
   416                         "Ignore inactive or disabled named group: " + ng.name);
   821                 }
   417                 }
   938 
   534 
   939                 if (ng.isAvailable(shc.activeProtocols) &&
   535                 if (ng.isAvailable(shc.activeProtocols) &&
   940                         ng.isSupported(shc.activeCipherSuites) &&
   536                         ng.isSupported(shc.activeCipherSuites) &&
   941                         shc.algorithmConstraints.permits(
   537                         shc.algorithmConstraints.permits(
   942                             EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
   538                             EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
   943                             ng.algorithm, namedGroupParams.get(ng))) {
   539                             ng.algorithm, getParameters(ng))) {
   944                     namedGroups.add(ng);
   540                     namedGroups.add(ng);
   945                 } else if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
   541                 } else if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
   946                     SSLLogger.fine(
   542                     SSLLogger.fine(
   947                         "Ignore inactive or disabled named group: " + ng.name);
   543                         "Ignore inactive or disabled named group: " + ng.name);
   948                 }
   544                 }