1 /* 2 * Copyright (c) 2019, 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 package sun.security.ssl; 26 27 import javax.crypto.spec.DHParameterSpec; 28 import javax.net.ssl.SSLException; 29 import java.io.IOException; 30 import java.security.*; 31 import java.security.spec.*; 32 import java.util.Collections; 33 import java.util.EnumSet; 34 import java.util.List; 35 import java.util.Set; 36 import javax.crypto.KeyAgreement; 37 import sun.security.ssl.DHKeyExchange.DHEPossession; 38 import sun.security.ssl.ECDHKeyExchange.ECDHEPossession; 39 import sun.security.util.CurveDB; 40 41 42 /** 43 * An enum containing all known named groups for use in TLS. 44 * 45 * The enum also contains the required properties of each group and the 46 * required functions (e.g. encoding/decoding). 47 */ 48 enum NamedGroup { 49 // Elliptic Curves (RFC 4492) 50 // 51 // See sun.security.util.CurveDB for the OIDs 52 // NIST K-163 53 54 SECT163_K1(0x0001, "sect163k1", 55 NamedGroupSpec.NAMED_GROUP_ECDHE, 56 ProtocolVersion.PROTOCOLS_TO_12, 57 CurveDB.lookup("sect163k1")), 58 SECT163_R1(0x0002, "sect163r1", 59 NamedGroupSpec.NAMED_GROUP_ECDHE, 60 ProtocolVersion.PROTOCOLS_TO_12, 61 CurveDB.lookup("sect163r1")), 62 63 // NIST B-163 64 SECT163_R2(0x0003, "sect163r2", 65 NamedGroupSpec.NAMED_GROUP_ECDHE, 66 ProtocolVersion.PROTOCOLS_TO_12, 67 CurveDB.lookup("sect163r2")), 68 SECT193_R1(0x0004, "sect193r1", 69 NamedGroupSpec.NAMED_GROUP_ECDHE, 70 ProtocolVersion.PROTOCOLS_TO_12, 71 CurveDB.lookup("sect193r1")), 72 SECT193_R2(0x0005, "sect193r2", 73 NamedGroupSpec.NAMED_GROUP_ECDHE, 74 ProtocolVersion.PROTOCOLS_TO_12, 75 CurveDB.lookup("sect193r2")), 76 77 // NIST K-233 78 SECT233_K1(0x0006, "sect233k1", 79 NamedGroupSpec.NAMED_GROUP_ECDHE, 80 ProtocolVersion.PROTOCOLS_TO_12, 81 CurveDB.lookup("sect233k1")), 82 83 // NIST B-233 84 SECT233_R1(0x0007, "sect233r1", 85 NamedGroupSpec.NAMED_GROUP_ECDHE, 86 ProtocolVersion.PROTOCOLS_TO_12, 87 CurveDB.lookup("sect233r1")), 88 SECT239_K1(0x0008, "sect239k1", 89 NamedGroupSpec.NAMED_GROUP_ECDHE, 90 ProtocolVersion.PROTOCOLS_TO_12, 91 CurveDB.lookup("sect239k1")), 92 93 // NIST K-283 94 SECT283_K1(0x0009, "sect283k1", 95 NamedGroupSpec.NAMED_GROUP_ECDHE, 96 ProtocolVersion.PROTOCOLS_TO_12, 97 CurveDB.lookup("sect283k1")), 98 99 // NIST B-283 100 SECT283_R1(0x000A, "sect283r1", 101 NamedGroupSpec.NAMED_GROUP_ECDHE, 102 ProtocolVersion.PROTOCOLS_TO_12, 103 CurveDB.lookup("sect283r1")), 104 105 // NIST K-409 106 SECT409_K1(0x000B, "sect409k1", 107 NamedGroupSpec.NAMED_GROUP_ECDHE, 108 ProtocolVersion.PROTOCOLS_TO_12, 109 CurveDB.lookup("sect409k1")), 110 111 // NIST B-409 112 SECT409_R1(0x000C, "sect409r1", 113 NamedGroupSpec.NAMED_GROUP_ECDHE, 114 ProtocolVersion.PROTOCOLS_TO_12, 115 CurveDB.lookup("sect409r1")), 116 117 // NIST K-571 118 SECT571_K1(0x000D, "sect571k1", 119 NamedGroupSpec.NAMED_GROUP_ECDHE, 120 ProtocolVersion.PROTOCOLS_TO_12, 121 CurveDB.lookup("sect571k1")), 122 123 // NIST B-571 124 SECT571_R1(0x000E, "sect571r1", 125 NamedGroupSpec.NAMED_GROUP_ECDHE, 126 ProtocolVersion.PROTOCOLS_TO_12, 127 CurveDB.lookup("sect571r1")), 128 SECP160_K1(0x000F, "secp160k1", 129 NamedGroupSpec.NAMED_GROUP_ECDHE, 130 ProtocolVersion.PROTOCOLS_TO_12, 131 CurveDB.lookup("secp160k1")), 132 SECP160_R1(0x0010, "secp160r1", 133 NamedGroupSpec.NAMED_GROUP_ECDHE, 134 ProtocolVersion.PROTOCOLS_TO_12, 135 CurveDB.lookup("secp160r1")), 136 SECP160_R2(0x0011, "secp160r2", 137 NamedGroupSpec.NAMED_GROUP_ECDHE, 138 ProtocolVersion.PROTOCOLS_TO_12, 139 CurveDB.lookup("secp160r2")), 140 SECP192_K1(0x0012, "secp192k1", 141 NamedGroupSpec.NAMED_GROUP_ECDHE, 142 ProtocolVersion.PROTOCOLS_TO_12, 143 CurveDB.lookup("secp192k1")), 144 145 // NIST P-192 146 SECP192_R1(0x0013, "secp192r1", 147 NamedGroupSpec.NAMED_GROUP_ECDHE, 148 ProtocolVersion.PROTOCOLS_TO_12, 149 CurveDB.lookup("secp192r1")), 150 SECP224_K1(0x0014, "secp224k1", 151 NamedGroupSpec.NAMED_GROUP_ECDHE, 152 ProtocolVersion.PROTOCOLS_TO_12, 153 CurveDB.lookup("secp224k1")), 154 155 // NIST P-224 156 SECP224_R1(0x0015, "secp224r1", 157 NamedGroupSpec.NAMED_GROUP_ECDHE, 158 ProtocolVersion.PROTOCOLS_TO_12, 159 CurveDB.lookup("secp224r1")), 160 SECP256_K1(0x0016, "secp256k1", 161 NamedGroupSpec.NAMED_GROUP_ECDHE, 162 ProtocolVersion.PROTOCOLS_TO_12, 163 CurveDB.lookup("secp256k1")), 164 165 // NIST P-256 166 SECP256_R1(0x0017, "secp256r1", 167 NamedGroupSpec.NAMED_GROUP_ECDHE, 168 ProtocolVersion.PROTOCOLS_TO_13, 169 CurveDB.lookup("secp256r1")), 170 171 // NIST P-384 172 SECP384_R1(0x0018, "secp384r1", 173 NamedGroupSpec.NAMED_GROUP_ECDHE, 174 ProtocolVersion.PROTOCOLS_TO_13, 175 CurveDB.lookup("secp384r1")), 176 177 // NIST P-521 178 SECP521_R1(0x0019, "secp521r1", 179 NamedGroupSpec.NAMED_GROUP_ECDHE, 180 ProtocolVersion.PROTOCOLS_TO_13, 181 CurveDB.lookup("secp521r1")), 182 183 // x25519 and x448 (RFC 8422/8446) 184 X25519(0x001D, "x25519", 185 NamedGroupSpec.NAMED_GROUP_XDH, 186 ProtocolVersion.PROTOCOLS_TO_13, 187 NamedParameterSpec.X25519), 188 X448(0x001E, "x448", 189 NamedGroupSpec.NAMED_GROUP_XDH, 190 ProtocolVersion.PROTOCOLS_TO_13, 191 NamedParameterSpec.X448), 192 193 // Finite Field Diffie-Hellman Ephemeral Parameters (RFC 7919) 194 FFDHE_2048(0x0100, "ffdhe2048", 195 NamedGroupSpec.NAMED_GROUP_FFDHE, 196 ProtocolVersion.PROTOCOLS_TO_13, 197 PredefinedDHParameterSpecs.ffdheParams.get(2048)), 198 199 FFDHE_3072(0x0101, "ffdhe3072", 200 NamedGroupSpec.NAMED_GROUP_FFDHE, 201 ProtocolVersion.PROTOCOLS_TO_13, 202 PredefinedDHParameterSpecs.ffdheParams.get(3072)), 203 FFDHE_4096(0x0102, "ffdhe4096", 204 NamedGroupSpec.NAMED_GROUP_FFDHE, 205 ProtocolVersion.PROTOCOLS_TO_13, 206 PredefinedDHParameterSpecs.ffdheParams.get(4096)), 207 FFDHE_6144(0x0103, "ffdhe6144", 208 NamedGroupSpec.NAMED_GROUP_FFDHE, 209 ProtocolVersion.PROTOCOLS_TO_13, 210 PredefinedDHParameterSpecs.ffdheParams.get(6144)), 211 FFDHE_8192(0x0104, "ffdhe8192", 212 NamedGroupSpec.NAMED_GROUP_FFDHE, 213 ProtocolVersion.PROTOCOLS_TO_13, 214 PredefinedDHParameterSpecs.ffdheParams.get(8192)), 215 216 // Elliptic Curves (RFC 4492) 217 // 218 // arbitrary prime and characteristic-2 curves 219 ARBITRARY_PRIME(0xFF01, "arbitrary_explicit_prime_curves", 220 NamedGroupSpec.NAMED_GROUP_ARBITRARY, 221 ProtocolVersion.PROTOCOLS_TO_12, 222 null), 223 ARBITRARY_CHAR2(0xFF02, "arbitrary_explicit_char2_curves", 224 NamedGroupSpec.NAMED_GROUP_ARBITRARY, 225 ProtocolVersion.PROTOCOLS_TO_12, 226 null); 227 228 final int id; // hash + signature 229 final String name; // literal name 230 final NamedGroupSpec spec; // group type 231 final ProtocolVersion[] supportedProtocols; 232 final String algorithm; // key exchange algorithm 233 final AlgorithmParameterSpec keAlgParamSpec; 234 final AlgorithmParameters keAlgParams; 235 final boolean isAvailable; 236 237 // performance optimization 238 private static final Set<CryptoPrimitive> KEY_AGREEMENT_PRIMITIVE_SET = 239 Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.KEY_AGREEMENT)); 240 241 // Constructor used for all NamedGroup types NamedGroup(int id, String name, NamedGroupSpec namedGroupSpec, ProtocolVersion[] supportedProtocols, AlgorithmParameterSpec keAlgParamSpec)242 private NamedGroup(int id, String name, 243 NamedGroupSpec namedGroupSpec, 244 ProtocolVersion[] supportedProtocols, 245 AlgorithmParameterSpec keAlgParamSpec) { 246 this.id = id; 247 this.name = name; 248 this.spec = namedGroupSpec; 249 this.algorithm = namedGroupSpec.algorithm; 250 this.supportedProtocols = supportedProtocols; 251 this.keAlgParamSpec = keAlgParamSpec; 252 253 // Check if it is a supported named group. 254 AlgorithmParameters algParams = null; 255 boolean mediator = (keAlgParamSpec != null); 256 257 // An EC provider, for example the SunEC provider, may support 258 // AlgorithmParameters but not KeyPairGenerator or KeyAgreement. 259 // 260 // Note: Please be careful if removing this block! 261 if (mediator && (namedGroupSpec == NamedGroupSpec.NAMED_GROUP_ECDHE)) { 262 mediator = JsseJce.isEcAvailable(); 263 } 264 265 // Check the specific algorithm parameters. 266 if (mediator) { 267 try { 268 algParams = 269 AlgorithmParameters.getInstance(namedGroupSpec.algorithm); 270 algParams.init(keAlgParamSpec); 271 } catch (InvalidParameterSpecException 272 | NoSuchAlgorithmException exp) { 273 if (namedGroupSpec != NamedGroupSpec.NAMED_GROUP_XDH) { 274 mediator = false; 275 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 276 SSLLogger.warning( 277 "No AlgorithmParameters for " + name, exp); 278 } 279 } else { 280 // Please remove the following code if the XDH/X25519/X448 281 // AlgorithmParameters algorithms are supported in JDK. 282 // 283 // Note: Please be careful if removing this block! 284 algParams = null; 285 try { 286 KeyAgreement.getInstance(name); 287 288 // The following service is also needed. But for 289 // performance, check the KeyAgreement impl only. 290 // 291 // KeyFactory.getInstance(name); 292 // KeyPairGenerator.getInstance(name); 293 // AlgorithmParameters.getInstance(name); 294 } catch (NoSuchAlgorithmException nsae) { 295 mediator = false; 296 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { 297 SSLLogger.warning( 298 "No AlgorithmParameters for " + name, nsae); 299 } 300 } 301 } 302 } 303 } 304 305 this.isAvailable = mediator; 306 this.keAlgParams = mediator ? algParams : null; 307 } 308 309 // 310 // The next set of methods search & retrieve NamedGroups. 311 // valueOf(int id)312 static NamedGroup valueOf(int id) { 313 for (NamedGroup group : NamedGroup.values()) { 314 if (group.id == id) { 315 return group; 316 } 317 } 318 319 return null; 320 } 321 valueOf(ECParameterSpec params)322 static NamedGroup valueOf(ECParameterSpec params) { 323 for (NamedGroup ng : NamedGroup.values()) { 324 if (ng.spec == NamedGroupSpec.NAMED_GROUP_ECDHE) { 325 if ((params == ng.keAlgParamSpec) || 326 (ng.keAlgParamSpec == CurveDB.lookup(params))) { 327 return ng; 328 } 329 } 330 } 331 332 return null; 333 } 334 valueOf(DHParameterSpec params)335 static NamedGroup valueOf(DHParameterSpec params) { 336 for (NamedGroup ng : NamedGroup.values()) { 337 if (ng.spec != NamedGroupSpec.NAMED_GROUP_FFDHE) { 338 continue; 339 } 340 341 DHParameterSpec ngParams = (DHParameterSpec)ng.keAlgParamSpec; 342 if (ngParams.getP().equals(params.getP()) 343 && ngParams.getG().equals(params.getG())) { 344 return ng; 345 } 346 } 347 348 return null; 349 } 350 nameOf(String name)351 static NamedGroup nameOf(String name) { 352 for (NamedGroup group : NamedGroup.values()) { 353 if (group.name.equalsIgnoreCase(name)) { 354 return group; 355 } 356 } 357 358 return null; 359 } 360 nameOf(int id)361 static String nameOf(int id) { 362 for (NamedGroup group : NamedGroup.values()) { 363 if (group.id == id) { 364 return group.name; 365 } 366 } 367 368 return "UNDEFINED-NAMED-GROUP(" + id + ")"; 369 } 370 371 // Is the NamedGroup available for the protocols desired? isAvailable(List<ProtocolVersion> protocolVersions)372 boolean isAvailable(List<ProtocolVersion> protocolVersions) { 373 if (this.isAvailable) { 374 for (ProtocolVersion pv : supportedProtocols) { 375 if (protocolVersions.contains(pv)) { 376 return true; 377 } 378 } 379 } 380 381 return false; 382 } 383 isAvailable(ProtocolVersion protocolVersion)384 boolean isAvailable(ProtocolVersion protocolVersion) { 385 if (this.isAvailable) { 386 for (ProtocolVersion pv : supportedProtocols) { 387 if (protocolVersion == pv) { 388 return true; 389 } 390 } 391 } 392 393 return false; 394 } 395 396 // Are the NamedGroups available for the ciphersuites desired? isSupported(List<CipherSuite> cipherSuites)397 boolean isSupported(List<CipherSuite> cipherSuites) { 398 for (CipherSuite cs : cipherSuites) { 399 boolean isMatch = isAvailable(cs.supportedProtocols); 400 if (isMatch && ((cs.keyExchange == null) 401 || (NamedGroupSpec.arrayContains( 402 cs.keyExchange.groupTypes, spec)))) { 403 return true; 404 } 405 } 406 407 return false; 408 } 409 isPermitted(AlgorithmConstraints constraints)410 boolean isPermitted(AlgorithmConstraints constraints) { 411 return constraints.permits(KEY_AGREEMENT_PRIMITIVE_SET, 412 this.name, null) && 413 constraints.permits(KEY_AGREEMENT_PRIMITIVE_SET, 414 this.algorithm, this.keAlgParams); 415 } 416 encodePossessionPublicKey( NamedGroupPossession namedGroupPossession)417 byte[] encodePossessionPublicKey( 418 NamedGroupPossession namedGroupPossession) { 419 return spec.encodePossessionPublicKey(namedGroupPossession); 420 } 421 decodeCredentials( byte[] encoded)422 SSLCredentials decodeCredentials( 423 byte[] encoded) throws IOException, GeneralSecurityException { 424 return spec.decodeCredentials(this, encoded); 425 } 426 createPossession(SecureRandom random)427 SSLPossession createPossession(SecureRandom random) { 428 return spec.createPossession(this, random); 429 } 430 createKeyDerivation( HandshakeContext hc)431 SSLKeyDerivation createKeyDerivation( 432 HandshakeContext hc) throws IOException { 433 return spec.createKeyDerivation(hc); 434 } 435 436 // A list of operations related to named groups. 437 private interface NamedGroupScheme { encodePossessionPublicKey( NamedGroupPossession namedGroupPossession)438 byte[] encodePossessionPublicKey( 439 NamedGroupPossession namedGroupPossession); 440 decodeCredentials(NamedGroup ng, byte[] encoded)441 SSLCredentials decodeCredentials(NamedGroup ng, 442 byte[] encoded) throws IOException, GeneralSecurityException; 443 createPossession(NamedGroup ng, SecureRandom random)444 SSLPossession createPossession(NamedGroup ng, SecureRandom random); 445 createKeyDerivation( HandshakeContext hc)446 SSLKeyDerivation createKeyDerivation( 447 HandshakeContext hc) throws IOException; 448 } 449 450 enum NamedGroupSpec implements NamedGroupScheme { 451 // Elliptic Curve Groups (ECDHE) 452 NAMED_GROUP_ECDHE("EC", ECDHEScheme.instance), 453 454 // Finite Field Groups (DHE) 455 NAMED_GROUP_FFDHE("DiffieHellman", FFDHEScheme.instance), 456 457 // Finite Field Groups (XDH) 458 NAMED_GROUP_XDH("XDH", XDHScheme.instance), 459 460 // arbitrary prime and curves (ECDHE) 461 NAMED_GROUP_ARBITRARY("EC", null), 462 463 // Not predefined named group 464 NAMED_GROUP_NONE("", null); 465 466 private final String algorithm; // key exchange name 467 private final NamedGroupScheme scheme; // named group operations 468 NamedGroupSpec(String algorithm, NamedGroupScheme scheme)469 private NamedGroupSpec(String algorithm, NamedGroupScheme scheme) { 470 this.algorithm = algorithm; 471 this.scheme = scheme; 472 } 473 isSupported(List<CipherSuite> cipherSuites)474 boolean isSupported(List<CipherSuite> cipherSuites) { 475 for (CipherSuite cs : cipherSuites) { 476 if (cs.keyExchange == null || 477 arrayContains(cs.keyExchange.groupTypes, this)) { 478 return true; 479 } 480 } 481 482 return false; 483 } 484 arrayContains(NamedGroupSpec[] namedGroupTypes, NamedGroupSpec namedGroupType)485 static boolean arrayContains(NamedGroupSpec[] namedGroupTypes, 486 NamedGroupSpec namedGroupType) { 487 for (NamedGroupSpec ng : namedGroupTypes) { 488 if (ng == namedGroupType) { 489 return true; 490 } 491 } 492 493 return false; 494 } 495 496 @Override encodePossessionPublicKey( NamedGroupPossession namedGroupPossession)497 public byte[] encodePossessionPublicKey( 498 NamedGroupPossession namedGroupPossession) { 499 if (scheme != null) { 500 return scheme.encodePossessionPublicKey(namedGroupPossession); 501 } 502 503 return null; 504 } 505 506 @Override decodeCredentials(NamedGroup ng, byte[] encoded)507 public SSLCredentials decodeCredentials(NamedGroup ng, 508 byte[] encoded) throws IOException, GeneralSecurityException { 509 if (scheme != null) { 510 return scheme.decodeCredentials(ng, encoded); 511 } 512 513 return null; 514 } 515 516 @Override createPossession( NamedGroup ng, SecureRandom random)517 public SSLPossession createPossession( 518 NamedGroup ng, SecureRandom random) { 519 if (scheme != null) { 520 return scheme.createPossession(ng, random); 521 } 522 523 return null; 524 } 525 526 @Override createKeyDerivation( HandshakeContext hc)527 public SSLKeyDerivation createKeyDerivation( 528 HandshakeContext hc) throws IOException { 529 if (scheme != null) { 530 return scheme.createKeyDerivation(hc); 531 } 532 533 return null; 534 } 535 } 536 537 private static class FFDHEScheme implements NamedGroupScheme { 538 private static final FFDHEScheme instance = new FFDHEScheme(); 539 540 @Override encodePossessionPublicKey( NamedGroupPossession namedGroupPossession)541 public byte[] encodePossessionPublicKey( 542 NamedGroupPossession namedGroupPossession) { 543 return ((DHEPossession)namedGroupPossession).encode(); 544 } 545 546 @Override decodeCredentials(NamedGroup ng, byte[] encoded)547 public SSLCredentials decodeCredentials(NamedGroup ng, 548 byte[] encoded) throws IOException, GeneralSecurityException { 549 return DHKeyExchange.DHECredentials.valueOf(ng, encoded); 550 } 551 552 @Override createPossession( NamedGroup ng, SecureRandom random)553 public SSLPossession createPossession( 554 NamedGroup ng, SecureRandom random) { 555 return new DHKeyExchange.DHEPossession(ng, random); 556 } 557 558 @Override createKeyDerivation( HandshakeContext hc)559 public SSLKeyDerivation createKeyDerivation( 560 HandshakeContext hc) throws IOException { 561 562 return DHKeyExchange.kaGenerator.createKeyDerivation(hc); 563 } 564 } 565 566 private static class ECDHEScheme implements NamedGroupScheme { 567 private static final ECDHEScheme instance = new ECDHEScheme(); 568 569 @Override encodePossessionPublicKey( NamedGroupPossession namedGroupPossession)570 public byte[] encodePossessionPublicKey( 571 NamedGroupPossession namedGroupPossession) { 572 return ((ECDHEPossession)namedGroupPossession).encode(); 573 } 574 575 @Override decodeCredentials(NamedGroup ng, byte[] encoded)576 public SSLCredentials decodeCredentials(NamedGroup ng, 577 byte[] encoded) throws IOException, GeneralSecurityException { 578 return ECDHKeyExchange.ECDHECredentials.valueOf(ng, encoded); 579 } 580 581 @Override createPossession( NamedGroup ng, SecureRandom random)582 public SSLPossession createPossession( 583 NamedGroup ng, SecureRandom random) { 584 return new ECDHKeyExchange.ECDHEPossession(ng, random); 585 } 586 587 @Override createKeyDerivation( HandshakeContext hc)588 public SSLKeyDerivation createKeyDerivation( 589 HandshakeContext hc) throws IOException { 590 return ECDHKeyExchange.ecdheKAGenerator.createKeyDerivation(hc); 591 } 592 } 593 594 private static class XDHScheme implements NamedGroupScheme { 595 private static final XDHScheme instance = new XDHScheme(); 596 597 @Override encodePossessionPublicKey(NamedGroupPossession poss)598 public byte[] encodePossessionPublicKey(NamedGroupPossession poss) { 599 return ((XDHKeyExchange.XDHEPossession)poss).encode(); 600 } 601 602 @Override decodeCredentials(NamedGroup ng, byte[] encoded)603 public SSLCredentials decodeCredentials(NamedGroup ng, 604 byte[] encoded) throws IOException, GeneralSecurityException { 605 return XDHKeyExchange.XDHECredentials.valueOf(ng, encoded); 606 } 607 608 @Override createPossession( NamedGroup ng, SecureRandom random)609 public SSLPossession createPossession( 610 NamedGroup ng, SecureRandom random) { 611 return new XDHKeyExchange.XDHEPossession(ng, random); 612 } 613 614 @Override createKeyDerivation( HandshakeContext hc)615 public SSLKeyDerivation createKeyDerivation( 616 HandshakeContext hc) throws IOException { 617 return XDHKeyExchange.xdheKAGenerator.createKeyDerivation(hc); 618 } 619 } 620 } 621