src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java
changeset 50768 68fa3d4026ea
parent 47216 71c04702a3d5
child 55353 946f7f2d321c
child 56858 829e9b5ace08
equal deleted inserted replaced
50767:356eaea05bf0 50768:68fa3d4026ea
       
     1 /*
       
     2  * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package sun.security.ssl;
       
    27 
       
    28 import java.io.IOException;
       
    29 import java.util.AbstractMap.SimpleImmutableEntry;
       
    30 import java.util.Arrays;
       
    31 import java.util.HashMap;
       
    32 import java.util.Map;
       
    33 import sun.security.ssl.DHKeyExchange.DHEPossession;
       
    34 import sun.security.ssl.ECDHKeyExchange.ECDHEPossession;
       
    35 import sun.security.ssl.SupportedGroupsExtension.NamedGroup;
       
    36 import sun.security.ssl.SupportedGroupsExtension.NamedGroupType;
       
    37 import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
       
    38 import sun.security.ssl.X509Authentication.X509Possession;
       
    39 
       
    40 final class SSLKeyExchange implements SSLKeyAgreementGenerator,
       
    41         SSLHandshakeBinding {
       
    42     private final SSLAuthentication authentication;
       
    43     private final SSLKeyAgreement keyAgreement;
       
    44 
       
    45     SSLKeyExchange(X509Authentication authentication,
       
    46             SSLKeyAgreement keyAgreement) {
       
    47         this.authentication = authentication;
       
    48         this.keyAgreement = keyAgreement;
       
    49     }
       
    50 
       
    51     SSLPossession[] createPossessions(HandshakeContext context) {
       
    52         // authentication
       
    53         SSLPossession authPossession = null;
       
    54         if (authentication != null) {
       
    55             authPossession = authentication.createPossession(context);
       
    56             if (authPossession == null) {
       
    57                 return new SSLPossession[0];
       
    58             } else if (context instanceof ServerHandshakeContext) {
       
    59                 // The authentication information may be used further for
       
    60                 // key agreement parameters negotiation.
       
    61                 ServerHandshakeContext shc = (ServerHandshakeContext)context;
       
    62                 shc.interimAuthn = authPossession;
       
    63             }
       
    64         }
       
    65 
       
    66         // key agreement
       
    67         SSLPossession kaPossession;
       
    68         if (keyAgreement == T12KeyAgreement.RSA_EXPORT) {
       
    69             // a special case
       
    70             X509Possession x509Possession = (X509Possession)authPossession;
       
    71             if (JsseJce.getRSAKeyLength(
       
    72                     x509Possession.popCerts[0].getPublicKey()) > 512) {
       
    73                 kaPossession = keyAgreement.createPossession(context);
       
    74 
       
    75                 if (kaPossession == null) {
       
    76                     return new SSLPossession[0];
       
    77                 } else {
       
    78                     return authentication != null ?
       
    79                             new SSLPossession[] {authPossession, kaPossession} :
       
    80                             new SSLPossession[] {kaPossession};
       
    81                 }
       
    82             } else {
       
    83                 return authentication != null ?
       
    84                         new SSLPossession[] {authPossession} :
       
    85                         new SSLPossession[0];
       
    86             }
       
    87         } else {
       
    88             kaPossession = keyAgreement.createPossession(context);
       
    89             if (kaPossession == null) {
       
    90                 // special cases
       
    91                 if (keyAgreement == T12KeyAgreement.RSA ||
       
    92                         keyAgreement == T12KeyAgreement.ECDH) {
       
    93                     return authentication != null ?
       
    94                             new SSLPossession[] {authPossession} :
       
    95                             new SSLPossession[0];
       
    96                 } else {
       
    97                     return new SSLPossession[0];
       
    98                 }
       
    99             } else {
       
   100                 return authentication != null ?
       
   101                         new SSLPossession[] {authPossession, kaPossession} :
       
   102                         new SSLPossession[] {kaPossession};
       
   103             }
       
   104         }
       
   105     }
       
   106 
       
   107     @Override
       
   108     public SSLKeyDerivation createKeyDerivation(
       
   109             HandshakeContext handshakeContext) throws IOException {
       
   110         return keyAgreement.createKeyDerivation(handshakeContext);
       
   111     }
       
   112 
       
   113     @Override
       
   114     public SSLHandshake[] getRelatedHandshakers(
       
   115             HandshakeContext handshakeContext) {
       
   116         SSLHandshake[] auHandshakes;
       
   117         if (authentication != null) {
       
   118             auHandshakes =
       
   119                 authentication.getRelatedHandshakers(handshakeContext);
       
   120         } else {
       
   121             auHandshakes = null;
       
   122         }
       
   123 
       
   124         SSLHandshake[] kaHandshakes =
       
   125                 keyAgreement.getRelatedHandshakers(handshakeContext);
       
   126 
       
   127         if (auHandshakes == null || auHandshakes.length == 0) {
       
   128             return kaHandshakes;
       
   129         } else if (kaHandshakes == null || kaHandshakes.length == 0) {
       
   130             return auHandshakes;
       
   131         } else {
       
   132             SSLHandshake[] producers = Arrays.copyOf(
       
   133                      auHandshakes, auHandshakes.length + kaHandshakes.length);
       
   134             System.arraycopy(kaHandshakes, 0,
       
   135                     producers, auHandshakes.length, kaHandshakes.length);
       
   136             return producers;
       
   137         }
       
   138     }
       
   139 
       
   140     @Override
       
   141     public Map.Entry<Byte, HandshakeProducer>[] getHandshakeProducers(
       
   142             HandshakeContext handshakeContext) {
       
   143         Map.Entry<Byte, HandshakeProducer>[] auProducers;
       
   144         if (authentication != null) {
       
   145             auProducers =
       
   146                 authentication.getHandshakeProducers(handshakeContext);
       
   147         } else {
       
   148             auProducers = null;
       
   149         }
       
   150 
       
   151         Map.Entry<Byte, HandshakeProducer>[] kaProducers =
       
   152                 keyAgreement.getHandshakeProducers(handshakeContext);
       
   153 
       
   154         if (auProducers == null || auProducers.length == 0) {
       
   155             return kaProducers;
       
   156         } else if (kaProducers == null || kaProducers.length == 0) {
       
   157             return auProducers;
       
   158         } else {
       
   159             Map.Entry<Byte, HandshakeProducer>[] producers = Arrays.copyOf(
       
   160                      auProducers, auProducers.length + kaProducers.length);
       
   161             System.arraycopy(kaProducers, 0,
       
   162                     producers, auProducers.length, kaProducers.length);
       
   163             return producers;
       
   164         }
       
   165     }
       
   166 
       
   167     @Override
       
   168     public Map.Entry<Byte, SSLConsumer>[] getHandshakeConsumers(
       
   169             HandshakeContext handshakeContext) {
       
   170         Map.Entry<Byte, SSLConsumer>[] auConsumers;
       
   171         if (authentication != null) {
       
   172             auConsumers =
       
   173                 authentication.getHandshakeConsumers(handshakeContext);
       
   174         } else {
       
   175             auConsumers = null;
       
   176         }
       
   177 
       
   178         Map.Entry<Byte, SSLConsumer>[] kaConsumers =
       
   179                 keyAgreement.getHandshakeConsumers(handshakeContext);
       
   180 
       
   181         if (auConsumers == null || auConsumers.length == 0) {
       
   182             return kaConsumers;
       
   183         } else if (kaConsumers == null || kaConsumers.length == 0) {
       
   184             return auConsumers;
       
   185         } else {
       
   186             Map.Entry<Byte, SSLConsumer>[] producers = Arrays.copyOf(
       
   187                      auConsumers, auConsumers.length + kaConsumers.length);
       
   188             System.arraycopy(kaConsumers, 0,
       
   189                     producers, auConsumers.length, kaConsumers.length);
       
   190             return producers;
       
   191         }
       
   192     }
       
   193 
       
   194     // SSL 3.0 - (D)TLS 1.2
       
   195     static SSLKeyExchange valueOf(
       
   196             CipherSuite.KeyExchange keyExchange,
       
   197             ProtocolVersion protocolVersion) {
       
   198         if (keyExchange == null || protocolVersion == null) {
       
   199             return null;
       
   200         }
       
   201 
       
   202         switch (keyExchange) {
       
   203             case K_RSA:
       
   204                 return SSLKeyExRSA.KE;
       
   205             case K_RSA_EXPORT:
       
   206                 return SSLKeyExRSAExport.KE;
       
   207             case K_DHE_DSS:
       
   208                 return SSLKeyExDHEDSS.KE;
       
   209             case K_DHE_DSS_EXPORT:
       
   210                 return SSLKeyExDHEDSSExport.KE;
       
   211             case K_DHE_RSA:
       
   212                 if (protocolVersion.useTLS12PlusSpec()) {   // (D)TLS 1.2
       
   213                     return SSLKeyExDHERSAOrPSS.KE;
       
   214                 } else {    // SSL 3.0, TLS 1.0/1.1
       
   215                     return SSLKeyExDHERSA.KE;
       
   216                 }
       
   217             case K_DHE_RSA_EXPORT:
       
   218                 return SSLKeyExDHERSAExport.KE;
       
   219             case K_DH_ANON:
       
   220                 return SSLKeyExDHANON.KE;
       
   221             case K_DH_ANON_EXPORT:
       
   222                 return SSLKeyExDHANONExport.KE;
       
   223             case K_ECDH_ECDSA:
       
   224                 return SSLKeyExECDHECDSA.KE;
       
   225             case K_ECDH_RSA:
       
   226                 return SSLKeyExECDHRSA.KE;
       
   227             case K_ECDHE_ECDSA:
       
   228                 return SSLKeyExECDHEECDSA.KE;
       
   229             case K_ECDHE_RSA:
       
   230                 if (protocolVersion.useTLS12PlusSpec()) {   // (D)TLS 1.2
       
   231                     return SSLKeyExECDHERSAOrPSS.KE;
       
   232                 } else {    // SSL 3.0, TLS 1.0/1.1
       
   233                     return SSLKeyExECDHERSA.KE;
       
   234                 }
       
   235             case K_ECDH_ANON:
       
   236                 return SSLKeyExECDHANON.KE;
       
   237         }
       
   238 
       
   239         return null;
       
   240     }
       
   241 
       
   242     // TLS 1.3
       
   243     static SSLKeyExchange valueOf(NamedGroup namedGroup) {
       
   244         SSLKeyAgreement ka = T13KeyAgreement.valueOf(namedGroup);
       
   245         if (ka != null) {
       
   246             return new SSLKeyExchange(
       
   247                 null, T13KeyAgreement.valueOf(namedGroup));
       
   248         }
       
   249 
       
   250         return null;
       
   251     }
       
   252 
       
   253     private static class SSLKeyExRSA {
       
   254         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   255                 X509Authentication.RSA, T12KeyAgreement.RSA);
       
   256     }
       
   257 
       
   258     private static class SSLKeyExRSAExport {
       
   259         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   260                 X509Authentication.RSA, T12KeyAgreement.RSA_EXPORT);
       
   261     }
       
   262 
       
   263     private static class SSLKeyExDHEDSS {
       
   264         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   265                 X509Authentication.DSA, T12KeyAgreement.DHE);
       
   266     }
       
   267 
       
   268     private static class SSLKeyExDHEDSSExport {
       
   269         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   270                 X509Authentication.DSA, T12KeyAgreement.DHE_EXPORT);
       
   271     }
       
   272 
       
   273     private static class SSLKeyExDHERSA {
       
   274         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   275                 X509Authentication.RSA, T12KeyAgreement.DHE);
       
   276     }
       
   277 
       
   278     private static class SSLKeyExDHERSAOrPSS {
       
   279         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   280                 X509Authentication.RSA_OR_PSS, T12KeyAgreement.DHE);
       
   281     }
       
   282 
       
   283     private static class SSLKeyExDHERSAExport {
       
   284         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   285                 X509Authentication.RSA, T12KeyAgreement.DHE_EXPORT);
       
   286     }
       
   287 
       
   288     private static class SSLKeyExDHANON {
       
   289         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   290                 null, T12KeyAgreement.DHE);
       
   291     }
       
   292 
       
   293     private static class SSLKeyExDHANONExport {
       
   294         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   295                 null, T12KeyAgreement.DHE_EXPORT);
       
   296     }
       
   297 
       
   298     private static class SSLKeyExECDHECDSA {
       
   299         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   300                 X509Authentication.EC, T12KeyAgreement.ECDH);
       
   301     }
       
   302 
       
   303     private static class SSLKeyExECDHRSA {
       
   304         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   305                 X509Authentication.EC, T12KeyAgreement.ECDH);
       
   306     }
       
   307 
       
   308     private static class SSLKeyExECDHEECDSA {
       
   309         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   310                 X509Authentication.EC, T12KeyAgreement.ECDHE);
       
   311     }
       
   312 
       
   313     private static class SSLKeyExECDHERSA {
       
   314         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   315                 X509Authentication.RSA, T12KeyAgreement.ECDHE);
       
   316     }
       
   317 
       
   318     private static class SSLKeyExECDHERSAOrPSS {
       
   319         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   320                 X509Authentication.RSA_OR_PSS, T12KeyAgreement.ECDHE);
       
   321     }
       
   322 
       
   323     private static class SSLKeyExECDHANON {
       
   324         private static SSLKeyExchange KE = new SSLKeyExchange(
       
   325                 null, T12KeyAgreement.ECDHE);
       
   326     }
       
   327 
       
   328     private enum T12KeyAgreement implements SSLKeyAgreement {
       
   329         RSA             ("rsa",         null,
       
   330                                         RSAKeyExchange.kaGenerator),
       
   331         RSA_EXPORT      ("rsa_export",  RSAKeyExchange.poGenerator,
       
   332                                         RSAKeyExchange.kaGenerator),
       
   333         DHE             ("dhe",         DHKeyExchange.poGenerator,
       
   334                                         DHKeyExchange.kaGenerator),
       
   335         DHE_EXPORT      ("dhe_export",  DHKeyExchange.poExportableGenerator,
       
   336                                         DHKeyExchange.kaGenerator),
       
   337         ECDH            ("ecdh",        null,
       
   338                                         ECDHKeyExchange.ecdhKAGenerator),
       
   339         ECDHE           ("ecdhe",       ECDHKeyExchange.poGenerator,
       
   340                                         ECDHKeyExchange.ecdheKAGenerator);
       
   341 
       
   342         final String name;
       
   343         final SSLPossessionGenerator possessionGenerator;
       
   344         final SSLKeyAgreementGenerator keyAgreementGenerator;
       
   345 
       
   346         T12KeyAgreement(String name,
       
   347                 SSLPossessionGenerator possessionGenerator,
       
   348                 SSLKeyAgreementGenerator keyAgreementGenerator) {
       
   349             this.name = name;
       
   350             this.possessionGenerator = possessionGenerator;
       
   351             this.keyAgreementGenerator = keyAgreementGenerator;
       
   352         }
       
   353 
       
   354         @Override
       
   355         public SSLPossession createPossession(HandshakeContext context) {
       
   356             if (possessionGenerator != null) {
       
   357                 return possessionGenerator.createPossession(context);
       
   358             }
       
   359 
       
   360             return null;
       
   361         }
       
   362 
       
   363         @Override
       
   364         public SSLKeyDerivation createKeyDerivation(
       
   365                 HandshakeContext context) throws IOException {
       
   366             return keyAgreementGenerator.createKeyDerivation(context);
       
   367         }
       
   368 
       
   369         @Override
       
   370         public SSLHandshake[] getRelatedHandshakers(
       
   371                 HandshakeContext handshakeContext) {
       
   372             if (!handshakeContext.negotiatedProtocol.useTLS13PlusSpec()) {
       
   373                 if (this.possessionGenerator != null) {
       
   374                     return new SSLHandshake[] {
       
   375                             SSLHandshake.SERVER_KEY_EXCHANGE
       
   376                         };
       
   377                 }
       
   378             }
       
   379 
       
   380             return new SSLHandshake[0];
       
   381         }
       
   382 
       
   383         @Override
       
   384         @SuppressWarnings({"unchecked", "rawtypes"})
       
   385         public Map.Entry<Byte, HandshakeProducer>[] getHandshakeProducers(
       
   386                 HandshakeContext handshakeContext) {
       
   387             if (handshakeContext.negotiatedProtocol.useTLS13PlusSpec()) {
       
   388                 return (Map.Entry<Byte, HandshakeProducer>[])(new Map.Entry[0]);
       
   389             }
       
   390 
       
   391             if (handshakeContext.sslConfig.isClientMode) {
       
   392                 switch (this) {
       
   393                     case RSA:
       
   394                     case RSA_EXPORT:
       
   395                         return (Map.Entry<Byte,
       
   396                                 HandshakeProducer>[])(new Map.Entry[] {
       
   397                             new SimpleImmutableEntry<>(
       
   398                                     SSLHandshake.CLIENT_KEY_EXCHANGE.id,
       
   399                                     RSAClientKeyExchange.rsaHandshakeProducer
       
   400                             )
       
   401                         });
       
   402 
       
   403                     case DHE:
       
   404                     case DHE_EXPORT:
       
   405                         return (Map.Entry<Byte,
       
   406                                 HandshakeProducer>[])(new Map.Entry[] {
       
   407                             new SimpleImmutableEntry<Byte, HandshakeProducer>(
       
   408                                     SSLHandshake.CLIENT_KEY_EXCHANGE.id,
       
   409                                     DHClientKeyExchange.dhHandshakeProducer
       
   410                             )
       
   411                         });
       
   412 
       
   413                     case ECDH:
       
   414                         return (Map.Entry<Byte,
       
   415                                 HandshakeProducer>[])(new Map.Entry[] {
       
   416                             new SimpleImmutableEntry<>(
       
   417                                 SSLHandshake.CLIENT_KEY_EXCHANGE.id,
       
   418                                 ECDHClientKeyExchange.ecdhHandshakeProducer
       
   419                             )
       
   420                         });
       
   421 
       
   422                     case ECDHE:
       
   423                         return (Map.Entry<Byte,
       
   424                                 HandshakeProducer>[])(new Map.Entry[] {
       
   425                             new SimpleImmutableEntry<>(
       
   426                                 SSLHandshake.CLIENT_KEY_EXCHANGE.id,
       
   427                                 ECDHClientKeyExchange.ecdheHandshakeProducer
       
   428                             )
       
   429                         });
       
   430                 }
       
   431             } else {
       
   432                 switch (this) {
       
   433                     case RSA_EXPORT:
       
   434                         return (Map.Entry<Byte,
       
   435                                 HandshakeProducer>[])(new Map.Entry[] {
       
   436                             new SimpleImmutableEntry<>(
       
   437                                     SSLHandshake.SERVER_KEY_EXCHANGE.id,
       
   438                                     RSAServerKeyExchange.rsaHandshakeProducer
       
   439                             )
       
   440                         });
       
   441 
       
   442                     case DHE:
       
   443                     case DHE_EXPORT:
       
   444                         return (Map.Entry<Byte,
       
   445                                 HandshakeProducer>[])(new Map.Entry[] {
       
   446                             new SimpleImmutableEntry<>(
       
   447                                     SSLHandshake.SERVER_KEY_EXCHANGE.id,
       
   448                                     DHServerKeyExchange.dhHandshakeProducer
       
   449                             )
       
   450                         });
       
   451 
       
   452                     case ECDHE:
       
   453                         return (Map.Entry<Byte,
       
   454                                 HandshakeProducer>[])(new Map.Entry[] {
       
   455                             new SimpleImmutableEntry<>(
       
   456                                     SSLHandshake.SERVER_KEY_EXCHANGE.id,
       
   457                                     ECDHServerKeyExchange.ecdheHandshakeProducer
       
   458                             )
       
   459                         });
       
   460                 }
       
   461             }
       
   462 
       
   463             return (Map.Entry<Byte, HandshakeProducer>[])(new Map.Entry[0]);
       
   464         }
       
   465 
       
   466         @Override
       
   467         @SuppressWarnings({"unchecked", "rawtypes"})
       
   468         public Map.Entry<Byte, SSLConsumer>[] getHandshakeConsumers(
       
   469                 HandshakeContext handshakeContext) {
       
   470             if (handshakeContext.negotiatedProtocol.useTLS13PlusSpec()) {
       
   471                 return (Map.Entry<Byte, SSLConsumer>[])(new Map.Entry[0]);
       
   472             }
       
   473 
       
   474             if (handshakeContext.sslConfig.isClientMode) {
       
   475                 switch (this) {
       
   476                     case RSA_EXPORT:
       
   477                         return (Map.Entry<Byte,
       
   478                                 SSLConsumer>[])(new Map.Entry[] {
       
   479                             new SimpleImmutableEntry<>(
       
   480                                     SSLHandshake.SERVER_KEY_EXCHANGE.id,
       
   481                                     RSAServerKeyExchange.rsaHandshakeConsumer
       
   482                             )
       
   483                         });
       
   484 
       
   485                     case DHE:
       
   486                     case DHE_EXPORT:
       
   487                         return (Map.Entry<Byte,
       
   488                                 SSLConsumer>[])(new Map.Entry[] {
       
   489                             new SimpleImmutableEntry<>(
       
   490                                     SSLHandshake.SERVER_KEY_EXCHANGE.id,
       
   491                                     DHServerKeyExchange.dhHandshakeConsumer
       
   492                             )
       
   493                         });
       
   494 
       
   495                     case ECDHE:
       
   496                         return (Map.Entry<Byte,
       
   497                                 SSLConsumer>[])(new Map.Entry[] {
       
   498                             new SimpleImmutableEntry<>(
       
   499                                     SSLHandshake.SERVER_KEY_EXCHANGE.id,
       
   500                                     ECDHServerKeyExchange.ecdheHandshakeConsumer
       
   501                             )
       
   502                         });
       
   503                 }
       
   504             } else {
       
   505                 switch (this) {
       
   506                     case RSA:
       
   507                     case RSA_EXPORT:
       
   508                         return (Map.Entry<Byte,
       
   509                                 SSLConsumer>[])(new Map.Entry[] {
       
   510                             new SimpleImmutableEntry<>(
       
   511                                     SSLHandshake.CLIENT_KEY_EXCHANGE.id,
       
   512                                     RSAClientKeyExchange.rsaHandshakeConsumer
       
   513                             )
       
   514                         });
       
   515 
       
   516                     case DHE:
       
   517                     case DHE_EXPORT:
       
   518                         return (Map.Entry<Byte,
       
   519                                 SSLConsumer>[])(new Map.Entry[] {
       
   520                             new SimpleImmutableEntry<>(
       
   521                                     SSLHandshake.CLIENT_KEY_EXCHANGE.id,
       
   522                                     DHClientKeyExchange.dhHandshakeConsumer
       
   523                             )
       
   524                         });
       
   525 
       
   526                     case ECDH:
       
   527                         return (Map.Entry<Byte,
       
   528                                 SSLConsumer>[])(new Map.Entry[] {
       
   529                             new SimpleImmutableEntry<>(
       
   530                                 SSLHandshake.CLIENT_KEY_EXCHANGE.id,
       
   531                                 ECDHClientKeyExchange.ecdhHandshakeConsumer
       
   532                             )
       
   533                         });
       
   534 
       
   535                     case ECDHE:
       
   536                         return (Map.Entry<Byte,
       
   537                                 SSLConsumer>[])(new Map.Entry[] {
       
   538                             new SimpleImmutableEntry<>(
       
   539                                 SSLHandshake.CLIENT_KEY_EXCHANGE.id,
       
   540                                 ECDHClientKeyExchange.ecdheHandshakeConsumer
       
   541                             )
       
   542                         });
       
   543                 }
       
   544             }
       
   545 
       
   546             return (Map.Entry<Byte, SSLConsumer>[])(new Map.Entry[0]);
       
   547         }
       
   548     }
       
   549 
       
   550     private static final class T13KeyAgreement implements SSLKeyAgreement {
       
   551         private final NamedGroup namedGroup;
       
   552         static final Map<NamedGroup, T13KeyAgreement>
       
   553                 supportedKeyShares = new HashMap<>();
       
   554 
       
   555         static {
       
   556             for (NamedGroup namedGroup :
       
   557                     SupportedGroups.supportedNamedGroups) {
       
   558                 supportedKeyShares.put(
       
   559                         namedGroup, new T13KeyAgreement(namedGroup));
       
   560             }
       
   561         }
       
   562 
       
   563         private T13KeyAgreement(NamedGroup namedGroup) {
       
   564             this.namedGroup = namedGroup;
       
   565         }
       
   566 
       
   567         static T13KeyAgreement valueOf(NamedGroup namedGroup) {
       
   568             return supportedKeyShares.get(namedGroup);
       
   569         }
       
   570 
       
   571         @Override
       
   572         public SSLPossession createPossession(HandshakeContext hc) {
       
   573             if (namedGroup.type == NamedGroupType.NAMED_GROUP_ECDHE) {
       
   574                 return new ECDHEPossession(
       
   575                         namedGroup, hc.sslContext.getSecureRandom());
       
   576             } else if (namedGroup.type == NamedGroupType.NAMED_GROUP_FFDHE) {
       
   577                 return new DHEPossession(
       
   578                         namedGroup, hc.sslContext.getSecureRandom());
       
   579             }
       
   580 
       
   581             return null;
       
   582         }
       
   583 
       
   584         @Override
       
   585         public SSLKeyDerivation createKeyDerivation(
       
   586                 HandshakeContext hc) throws IOException {
       
   587             if (namedGroup.type == NamedGroupType.NAMED_GROUP_ECDHE) {
       
   588                 return ECDHKeyExchange.ecdheKAGenerator.createKeyDerivation(hc);
       
   589             } else if (namedGroup.type == NamedGroupType.NAMED_GROUP_FFDHE) {
       
   590                 return DHKeyExchange.kaGenerator.createKeyDerivation(hc);
       
   591             }
       
   592 
       
   593             return null;
       
   594         }
       
   595     }
       
   596 }