1 /* 2 * Copyright (c) 2015, 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 sun.security.action.GetPropertyAction; 29 30 import java.io.File; 31 import java.io.FilePermission; 32 import java.io.IOException; 33 import java.security.AccessControlContext; 34 import java.security.AccessController; 35 import java.security.Principal; 36 import java.security.PrivilegedAction; 37 import java.security.SecureRandom; 38 import java.util.*; 39 40 /** 41 * Models a service that provides support for a particular client key exchange 42 * mode. Currently used to implement Kerberos-related cipher suites. 43 * 44 * @since 9 45 */ 46 public interface ClientKeyExchangeService { 47 48 static class Loader { 49 private static final Map<String,ClientKeyExchangeService> 50 providers = new HashMap<>(); 51 52 static { 53 String path = GetPropertyAction.privilegedGetProperty("java.home"); 54 ServiceLoader<ClientKeyExchangeService> sc = 55 AccessController.doPrivileged( 56 (PrivilegedAction<ServiceLoader<ClientKeyExchangeService>>) 57 () -> ServiceLoader.loadInstalled(ClientKeyExchangeService.class), 58 null, 59 new FilePermission(new File(path, "-").toString(), "read")); 60 Iterator<ClientKeyExchangeService> iter = sc.iterator(); 61 while (iter.hasNext()) { 62 ClientKeyExchangeService cs = iter.next(); 63 for (String ex: cs.supported()) { 64 providers.put(ex, cs); 65 } 66 } 67 } 68 69 } 70 71 public static ClientKeyExchangeService find(String ex) { 72 return Loader.providers.get(ex); 73 } 74 75 76 /** 77 * Returns the supported key exchange modes by this provider. 78 * @return the supported key exchange modes 79 */ 80 String[] supported(); 81 82 /** 83 * Returns a generalized credential object on the server side. The server 84 * side can use the info to determine if a cipher suite can be enabled. 85 * @param acc the AccessControlContext of the SSL session 86 * @return the credential object 87 */ 88 Object getServiceCreds(AccessControlContext acc); 89 90 /** 91 * Returns the host name for a service principal. The info can be used in 92 * SNI or host name verifier. 93 * @param principal the principal of a service 94 * @return the string formed host name 95 */ 96 String getServiceHostName(Principal principal); 97 98 /** 99 * Returns whether the specified principal is related to the current 100 * SSLSession. The info can be used to verify a SSL resume. 101 * @param isClient if true called from client side, otherwise from server 102 * @param acc the AccessControlContext of the SSL session 103 * @param p the specified principal 104 * @return true if related 105 */ 106 boolean isRelated(boolean isClient, AccessControlContext acc, Principal p); 107 108 /** 109 * Creates the ClientKeyExchange object on the client side. 110 * @param serverName the intented peer name 111 * @param acc the AccessControlContext of the SSL session 112 * @param protocolVersion the TLS protocol version 113 * @param rand the SecureRandom that will used to generate the premaster 114 * @return the new Exchanger object 115 * @throws IOException if there is an error 116 */ 117 ClientKeyExchange createClientExchange(String serverName, AccessControlContext acc, 118 ProtocolVersion protocolVersion, SecureRandom rand) throws IOException; 119 120 /** 121 * Create the ClientKeyExchange on the server side. 122 * @param protocolVersion the protocol version 123 * @param clientVersion the input protocol version 124 * @param rand a SecureRandom object used to generate premaster 125 * (if the server has to create one) 126 * @param encodedTicket the ticket from client 127 * @param encrypted the encrypted premaster secret from client 128 * @param acc the AccessControlContext of the SSL session 129 * @param ServiceCreds the service side credentials object as retrived from 130 * {@link #getServiceCreds} 131 * @return the new Exchanger object 132 * @throws IOException if there is an error 133 */ 134 ClientKeyExchange createServerExchange( 135 ProtocolVersion protocolVersion, ProtocolVersion clientVersion, 136 SecureRandom rand, byte[] encodedTicket, byte[] encrypted, 137 AccessControlContext acc, Object ServiceCreds) throws IOException; 138 } | 1 /* 2 * Copyright (c) 2003, 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 SSLKeyAgreement { 41 private final SSLAuthentication authentication; 42 private final SSLKeyAgreement keyAgreement; 43 44 SSLKeyExchange(X509Authentication authentication, 45 SSLKeyAgreement keyAgreement) { 46 this.authentication = authentication; 47 this.keyAgreement = keyAgreement; 48 } 49 50 SSLPossession[] createPossessions(HandshakeContext context) { 51 // authentication 52 SSLPossession authPossession = null; 53 if (authentication != null) { 54 authPossession = authentication.createPossession(context); 55 if (authPossession == null) { 56 return new SSLPossession[0]; 57 } else if (context instanceof ServerHandshakeContext) { 58 // The authentication information may be used further for 59 // key agreement parameters negotiation. 60 ServerHandshakeContext shc = (ServerHandshakeContext)context; 61 shc.interimAuthn = authPossession; 62 } 63 } 64 65 // key agreement 66 SSLPossession kaPossession; 67 if (keyAgreement == T12KeyAgreement.RSA_EXPORT) { 68 // a special case 69 X509Possession x509Possession = (X509Possession)authPossession; 70 if (JsseJce.getRSAKeyLength( 71 x509Possession.popCerts[0].getPublicKey()) > 512) { 72 kaPossession = keyAgreement.createPossession(context); 73 74 if (kaPossession == null) { 75 return new SSLPossession[0]; 76 } else { 77 return authentication != null ? 78 new SSLPossession[] {authPossession, kaPossession} : 79 new SSLPossession[] {kaPossession}; 80 } 81 } else { 82 return authentication != null ? 83 new SSLPossession[] {authPossession} : 84 new SSLPossession[0]; 85 } 86 } else { 87 kaPossession = keyAgreement.createPossession(context); 88 if (kaPossession == null) { 89 // special cases 90 if (keyAgreement == T12KeyAgreement.RSA || 91 keyAgreement == T12KeyAgreement.ECDH) { 92 return authentication != null ? 93 new SSLPossession[] {authPossession} : 94 new SSLPossession[0]; 95 } else { 96 return new SSLPossession[0]; 97 } 98 } else { 99 return authentication != null ? 100 new SSLPossession[] {authPossession, kaPossession} : 101 new SSLPossession[] {kaPossession}; 102 } 103 } 104 } 105 106 @Override 107 public SSLPossession createPossession(HandshakeContext handshakeContext) { 108 // Please call createPossessions() so that the SSLAuthentication 109 // is counted. 110 throw new UnsupportedOperationException( 111 "SSLKeyExchange.createPossessions() should be used instead"); 112 } 113 114 @Override 115 public SSLKeyDerivation createKeyDerivation( 116 HandshakeContext handshakeContext) throws IOException { 117 return keyAgreement.createKeyDerivation(handshakeContext); 118 } 119 120 @Override 121 public SSLHandshake[] getRelatedHandshakers( 122 HandshakeContext handshakeContext) { 123 SSLHandshake[] auHandshakes; 124 if (authentication != null) { 125 auHandshakes = 126 authentication.getRelatedHandshakers(handshakeContext); 127 } else { 128 auHandshakes = null; 129 } 130 131 SSLHandshake[] kaHandshakes = 132 keyAgreement.getRelatedHandshakers(handshakeContext); 133 134 if (auHandshakes == null || auHandshakes.length == 0) { 135 return kaHandshakes; 136 } else if (kaHandshakes == null || kaHandshakes.length == 0) { 137 return auHandshakes; 138 } else { 139 SSLHandshake[] producers = Arrays.copyOf( 140 auHandshakes, auHandshakes.length + kaHandshakes.length); 141 System.arraycopy(kaHandshakes, 0, 142 producers, auHandshakes.length, kaHandshakes.length); 143 return producers; 144 } 145 } 146 147 @Override 148 public Map.Entry<Byte, HandshakeProducer>[] getHandshakeProducers( 149 HandshakeContext handshakeContext) { 150 Map.Entry<Byte, HandshakeProducer>[] auProducers; 151 if (authentication != null) { 152 auProducers = 153 authentication.getHandshakeProducers(handshakeContext); 154 } else { 155 auProducers = null; 156 } 157 158 Map.Entry<Byte, HandshakeProducer>[] kaProducers = 159 keyAgreement.getHandshakeProducers(handshakeContext); 160 161 if (auProducers == null || auProducers.length == 0) { 162 return kaProducers; 163 } else if (kaProducers == null || kaProducers.length == 0) { 164 return auProducers; 165 } else { 166 Map.Entry<Byte, HandshakeProducer>[] producers = Arrays.copyOf( 167 auProducers, auProducers.length + kaProducers.length); 168 System.arraycopy(kaProducers, 0, 169 producers, auProducers.length, kaProducers.length); 170 return producers; 171 } 172 } 173 174 @Override 175 public Map.Entry<Byte, SSLConsumer>[] getHandshakeConsumers( 176 HandshakeContext handshakeContext) { 177 Map.Entry<Byte, SSLConsumer>[] auConsumers; 178 if (authentication != null) { 179 auConsumers = 180 authentication.getHandshakeConsumers(handshakeContext); 181 } else { 182 auConsumers = null; 183 } 184 185 Map.Entry<Byte, SSLConsumer>[] kaConsumers = 186 keyAgreement.getHandshakeConsumers(handshakeContext); 187 188 if (auConsumers == null || auConsumers.length == 0) { 189 return kaConsumers; 190 } else if (kaConsumers == null || kaConsumers.length == 0) { 191 return auConsumers; 192 } else { 193 Map.Entry<Byte, SSLConsumer>[] producers = Arrays.copyOf( 194 auConsumers, auConsumers.length + kaConsumers.length); 195 System.arraycopy(kaConsumers, 0, 196 producers, auConsumers.length, kaConsumers.length); 197 return producers; 198 } 199 } 200 201 // SSL 3.0 - (D)TLS 1.2 202 static SSLKeyExchange valueOf( 203 CipherSuite.KeyExchange keyExchange) { 204 if (keyExchange == null) { 205 return null; 206 } 207 208 switch (keyExchange) { 209 case K_RSA: 210 return SSLKeyExRSA.KE; 211 case K_RSA_EXPORT: 212 return SSLKeyExRSAExport.KE; 213 case K_DHE_DSS: 214 return SSLKeyExDHEDSS.KE; 215 case K_DHE_DSS_EXPORT: 216 return SSLKeyExDHEDSSExport.KE; 217 case K_DHE_RSA: 218 return SSLKeyExDHERSA.KE; 219 case K_DHE_RSA_EXPORT: 220 return SSLKeyExDHERSAExport.KE; 221 case K_DH_ANON: 222 return SSLKeyExDHANON.KE; 223 case K_DH_ANON_EXPORT: 224 return SSLKeyExDHANONExport.KE; 225 case K_ECDH_ECDSA: 226 return SSLKeyExECDHECDSA.KE; 227 case K_ECDH_RSA: 228 return SSLKeyExECDHRSA.KE; 229 case K_ECDHE_ECDSA: 230 return SSLKeyExECDHEECDSA.KE; 231 case K_ECDHE_RSA: 232 return SSLKeyExECDHERSA.KE; 233 case K_ECDH_ANON: 234 return SSLKeyExECDHANON.KE; 235 } 236 237 return null; 238 } 239 240 // TLS 1.3 241 static SSLKeyExchange valueOf(NamedGroup namedGroup) { 242 SSLKeyAgreement ka = T13KeyAgreement.valueOf(namedGroup); 243 if (ka != null) { 244 return new SSLKeyExchange( 245 null, T13KeyAgreement.valueOf(namedGroup)); 246 } 247 248 return null; 249 } 250 251 private static class SSLKeyExRSA { 252 private static SSLKeyExchange KE = new SSLKeyExchange( 253 X509Authentication.RSA, T12KeyAgreement.RSA); 254 } 255 256 private static class SSLKeyExRSAExport { 257 private static SSLKeyExchange KE = new SSLKeyExchange( 258 X509Authentication.RSA, T12KeyAgreement.RSA_EXPORT); 259 } 260 261 private static class SSLKeyExDHEDSS { 262 private static SSLKeyExchange KE = new SSLKeyExchange( 263 X509Authentication.DSA, T12KeyAgreement.DHE); 264 } 265 266 private static class SSLKeyExDHEDSSExport { 267 private static SSLKeyExchange KE = new SSLKeyExchange( 268 X509Authentication.DSA, T12KeyAgreement.DHE_EXPORT); 269 } 270 271 private static class SSLKeyExDHERSA { 272 private static SSLKeyExchange KE = new SSLKeyExchange( 273 X509Authentication.RSA, T12KeyAgreement.DHE); 274 } 275 276 private static class SSLKeyExDHERSAExport { 277 private static SSLKeyExchange KE = new SSLKeyExchange( 278 X509Authentication.RSA, T12KeyAgreement.DHE_EXPORT); 279 } 280 281 private static class SSLKeyExDHANON { 282 private static SSLKeyExchange KE = new SSLKeyExchange( 283 null, T12KeyAgreement.DHE); 284 } 285 286 private static class SSLKeyExDHANONExport { 287 private static SSLKeyExchange KE = new SSLKeyExchange( 288 null, T12KeyAgreement.DHE_EXPORT); 289 } 290 291 private static class SSLKeyExECDHECDSA { 292 private static SSLKeyExchange KE = new SSLKeyExchange( 293 X509Authentication.EC, T12KeyAgreement.ECDH); 294 } 295 296 private static class SSLKeyExECDHRSA { 297 private static SSLKeyExchange KE = new SSLKeyExchange( 298 X509Authentication.EC, T12KeyAgreement.ECDH); 299 } 300 301 private static class SSLKeyExECDHEECDSA { 302 private static SSLKeyExchange KE = new SSLKeyExchange( 303 X509Authentication.EC, T12KeyAgreement.ECDHE); 304 } 305 306 private static class SSLKeyExECDHERSA { 307 private static SSLKeyExchange KE = new SSLKeyExchange( 308 X509Authentication.RSA, T12KeyAgreement.ECDHE); 309 } 310 311 private static class SSLKeyExECDHANON { 312 private static SSLKeyExchange KE = new SSLKeyExchange( 313 null, T12KeyAgreement.ECDHE); 314 } 315 316 private enum T12KeyAgreement implements SSLKeyAgreement { 317 RSA ("rsa", null, 318 RSAKeyExchange.kaGenerator), 319 RSA_EXPORT ("rsa_export", RSAKeyExchange.poGenerator, 320 RSAKeyExchange.kaGenerator), 321 DHE ("dhe", DHKeyExchange.poGenerator, 322 DHKeyExchange.kaGenerator), 323 DHE_EXPORT ("dhe_export", DHKeyExchange.poExportableGenerator, 324 DHKeyExchange.kaGenerator), 325 ECDH ("ecdh", null, 326 ECDHKeyExchange.ecdhKAGenerator), 327 ECDHE ("ecdhe", ECDHKeyExchange.poGenerator, 328 ECDHKeyExchange.ecdheKAGenerator); 329 330 final String name; 331 final SSLPossessionGenerator possessionGenerator; 332 final SSLKeyAgreementGenerator keyAgreementGenerator; 333 334 T12KeyAgreement(String name, 335 SSLPossessionGenerator possessionGenerator, 336 SSLKeyAgreementGenerator keyAgreementGenerator) { 337 this.name = name; 338 this.possessionGenerator = possessionGenerator; 339 this.keyAgreementGenerator = keyAgreementGenerator; 340 } 341 342 @Override 343 public SSLPossession createPossession(HandshakeContext context) { 344 if (possessionGenerator != null) { 345 return possessionGenerator.createPossession(context); 346 } 347 348 return null; 349 } 350 351 @Override 352 public SSLKeyDerivation createKeyDerivation( 353 HandshakeContext context) throws IOException { 354 return keyAgreementGenerator.createKeyDerivation(context); 355 } 356 357 @Override 358 public SSLHandshake[] getRelatedHandshakers( 359 HandshakeContext handshakeContext) { 360 if (!handshakeContext.negotiatedProtocol.useTLS13PlusSpec()) { 361 if (this.possessionGenerator != null) { 362 return new SSLHandshake[] { 363 SSLHandshake.SERVER_KEY_EXCHANGE 364 }; 365 } 366 } 367 368 return new SSLHandshake[0]; 369 } 370 371 @Override 372 @SuppressWarnings({"unchecked", "rawtypes"}) 373 public Map.Entry<Byte, HandshakeProducer>[] getHandshakeProducers( 374 HandshakeContext handshakeContext) { 375 if (handshakeContext.negotiatedProtocol.useTLS13PlusSpec()) { 376 return (Map.Entry<Byte, HandshakeProducer>[])(new Map.Entry[0]); 377 } 378 379 if (handshakeContext.sslConfig.isClientMode) { 380 switch (this) { 381 case RSA: 382 case RSA_EXPORT: 383 return (Map.Entry<Byte, 384 HandshakeProducer>[])(new Map.Entry[] { 385 new SimpleImmutableEntry<>( 386 SSLHandshake.CLIENT_KEY_EXCHANGE.id, 387 RSAClientKeyExchange.rsaHandshakeProducer 388 ) 389 }); 390 391 case DHE: 392 case DHE_EXPORT: 393 return (Map.Entry<Byte, 394 HandshakeProducer>[])(new Map.Entry[] { 395 new SimpleImmutableEntry<Byte, HandshakeProducer>( 396 SSLHandshake.CLIENT_KEY_EXCHANGE.id, 397 DHClientKeyExchange.dhHandshakeProducer 398 ) 399 }); 400 401 case ECDH: 402 return (Map.Entry<Byte, 403 HandshakeProducer>[])(new Map.Entry[] { 404 new SimpleImmutableEntry<>( 405 SSLHandshake.CLIENT_KEY_EXCHANGE.id, 406 ECDHClientKeyExchange.ecdhHandshakeProducer 407 ) 408 }); 409 410 case ECDHE: 411 return (Map.Entry<Byte, 412 HandshakeProducer>[])(new Map.Entry[] { 413 new SimpleImmutableEntry<>( 414 SSLHandshake.CLIENT_KEY_EXCHANGE.id, 415 ECDHClientKeyExchange.ecdheHandshakeProducer 416 ) 417 }); 418 } 419 } else { 420 switch (this) { 421 case RSA_EXPORT: 422 return (Map.Entry<Byte, 423 HandshakeProducer>[])(new Map.Entry[] { 424 new SimpleImmutableEntry<>( 425 SSLHandshake.SERVER_KEY_EXCHANGE.id, 426 RSAServerKeyExchange.rsaHandshakeProducer 427 ) 428 }); 429 430 case DHE: 431 case DHE_EXPORT: 432 return (Map.Entry<Byte, 433 HandshakeProducer>[])(new Map.Entry[] { 434 new SimpleImmutableEntry<>( 435 SSLHandshake.SERVER_KEY_EXCHANGE.id, 436 DHServerKeyExchange.dhHandshakeProducer 437 ) 438 }); 439 440 case ECDHE: 441 return (Map.Entry<Byte, 442 HandshakeProducer>[])(new Map.Entry[] { 443 new SimpleImmutableEntry<>( 444 SSLHandshake.SERVER_KEY_EXCHANGE.id, 445 ECDHServerKeyExchange.ecdheHandshakeProducer 446 ) 447 }); 448 } 449 } 450 451 return (Map.Entry<Byte, HandshakeProducer>[])(new Map.Entry[0]); 452 } 453 454 @Override 455 @SuppressWarnings({"unchecked", "rawtypes"}) 456 public Map.Entry<Byte, SSLConsumer>[] getHandshakeConsumers( 457 HandshakeContext handshakeContext) { 458 if (handshakeContext.negotiatedProtocol.useTLS13PlusSpec()) { 459 return (Map.Entry<Byte, SSLConsumer>[])(new Map.Entry[0]); 460 } 461 462 if (handshakeContext.sslConfig.isClientMode) { 463 switch (this) { 464 case RSA_EXPORT: 465 return (Map.Entry<Byte, 466 SSLConsumer>[])(new Map.Entry[] { 467 new SimpleImmutableEntry<>( 468 SSLHandshake.SERVER_KEY_EXCHANGE.id, 469 RSAServerKeyExchange.rsaHandshakeConsumer 470 ) 471 }); 472 473 case DHE: 474 case DHE_EXPORT: 475 return (Map.Entry<Byte, 476 SSLConsumer>[])(new Map.Entry[] { 477 new SimpleImmutableEntry<>( 478 SSLHandshake.SERVER_KEY_EXCHANGE.id, 479 DHServerKeyExchange.dhHandshakeConsumer 480 ) 481 }); 482 483 case ECDHE: 484 return (Map.Entry<Byte, 485 SSLConsumer>[])(new Map.Entry[] { 486 new SimpleImmutableEntry<>( 487 SSLHandshake.SERVER_KEY_EXCHANGE.id, 488 ECDHServerKeyExchange.ecdheHandshakeConsumer 489 ) 490 }); 491 } 492 } else { 493 switch (this) { 494 case RSA: 495 case RSA_EXPORT: 496 return (Map.Entry<Byte, 497 SSLConsumer>[])(new Map.Entry[] { 498 new SimpleImmutableEntry<>( 499 SSLHandshake.CLIENT_KEY_EXCHANGE.id, 500 RSAClientKeyExchange.rsaHandshakeConsumer 501 ) 502 }); 503 504 case DHE: 505 case DHE_EXPORT: 506 return (Map.Entry<Byte, 507 SSLConsumer>[])(new Map.Entry[] { 508 new SimpleImmutableEntry<>( 509 SSLHandshake.CLIENT_KEY_EXCHANGE.id, 510 DHClientKeyExchange.dhHandshakeConsumer 511 ) 512 }); 513 514 case ECDH: 515 return (Map.Entry<Byte, 516 SSLConsumer>[])(new Map.Entry[] { 517 new SimpleImmutableEntry<>( 518 SSLHandshake.CLIENT_KEY_EXCHANGE.id, 519 ECDHClientKeyExchange.ecdhHandshakeConsumer 520 ) 521 }); 522 523 case ECDHE: 524 return (Map.Entry<Byte, 525 SSLConsumer>[])(new Map.Entry[] { 526 new SimpleImmutableEntry<>( 527 SSLHandshake.CLIENT_KEY_EXCHANGE.id, 528 ECDHClientKeyExchange.ecdheHandshakeConsumer 529 ) 530 }); 531 } 532 } 533 534 return (Map.Entry<Byte, SSLConsumer>[])(new Map.Entry[0]); 535 } 536 } 537 538 private static final class T13KeyAgreement implements SSLKeyAgreement { 539 private final NamedGroup namedGroup; 540 static final Map<NamedGroup, T13KeyAgreement> 541 supportedKeyShares = new HashMap<>(); 542 543 static { 544 for (NamedGroup namedGroup : 545 SupportedGroups.supportedNamedGroups) { 546 supportedKeyShares.put( 547 namedGroup, new T13KeyAgreement(namedGroup)); 548 } 549 } 550 551 private T13KeyAgreement(NamedGroup namedGroup) { 552 this.namedGroup = namedGroup; 553 } 554 555 static T13KeyAgreement valueOf(NamedGroup namedGroup) { 556 return supportedKeyShares.get(namedGroup); 557 } 558 559 @Override 560 public SSLPossession createPossession(HandshakeContext hc) { 561 if (namedGroup.type == NamedGroupType.NAMED_GROUP_ECDHE) { 562 return new ECDHEPossession( 563 namedGroup, hc.sslContext.getSecureRandom()); 564 } else if (namedGroup.type == NamedGroupType.NAMED_GROUP_FFDHE) { 565 return new DHEPossession( 566 namedGroup, hc.sslContext.getSecureRandom()); 567 } 568 569 return null; 570 } 571 572 @Override 573 public SSLKeyDerivation createKeyDerivation( 574 HandshakeContext hc) throws IOException { 575 if (namedGroup.type == NamedGroupType.NAMED_GROUP_ECDHE) { 576 return ECDHKeyExchange.ecdheKAGenerator.createKeyDerivation(hc); 577 } else if (namedGroup.type == NamedGroupType.NAMED_GROUP_FFDHE) { 578 return DHKeyExchange.kaGenerator.createKeyDerivation(hc); 579 } 580 581 return null; 582 } 583 } 584 } |