Factoring out some duplicate code.
--- a/src/java.base/share/classes/sun/security/ssl/DHKeyExchange.java Fri Aug 17 14:37:01 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/DHKeyExchange.java Mon Aug 20 13:16:49 2018 -0400
@@ -406,7 +406,7 @@
@Override
public SSLKeyDerivation createKeyDerivation(
- HandshakeContext context) throws IOException {
+ HandshakeContext context) throws IOException {
DHEPossession dhePossession = null;
DHECredentials dheCredentials = null;
for (SSLPossession poss : context.handshakePossessions) {
@@ -414,126 +414,41 @@
continue;
}
- DHEPossession dhep = (DHEPossession)poss;
+ DHEPossession dhep = (DHEPossession) poss;
for (SSLCredentials cred : context.handshakeCredentials) {
if (!(cred instanceof DHECredentials)) {
continue;
}
- DHECredentials dhec = (DHECredentials)cred;
+ DHECredentials dhec = (DHECredentials) cred;
if (dhep.namedGroup != null && dhec.namedGroup != null) {
if (dhep.namedGroup.equals(dhec.namedGroup)) {
- dheCredentials = (DHECredentials)cred;
+ dheCredentials = (DHECredentials) cred;
break;
}
} else {
DHParameterSpec pps = dhep.publicKey.getParams();
DHParameterSpec cps = dhec.popPublicKey.getParams();
if (pps.getP().equals(cps.getP()) &&
- pps.getG().equals(cps.getG())) {
- dheCredentials = (DHECredentials)cred;
+ pps.getG().equals(cps.getG())) {
+ dheCredentials = (DHECredentials) cred;
break;
}
}
}
if (dheCredentials != null) {
- dhePossession = (DHEPossession)poss;
+ dhePossession = (DHEPossession) poss;
break;
}
}
if (dhePossession == null || dheCredentials == null) {
context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
- "No sufficient DHE key agreement parameters negotiated");
- }
-
- return new DHEKAKeyDerivation(context,
- dhePossession.privateKey, dheCredentials.popPublicKey);
- }
-
- private static final
- class DHEKAKeyDerivation implements SSLKeyDerivation {
- private final HandshakeContext context;
- private final PrivateKey localPrivateKey;
- private final PublicKey peerPublicKey;
-
- DHEKAKeyDerivation(HandshakeContext context,
- PrivateKey localPrivateKey,
- PublicKey peerPublicKey) {
- this.context = context;
- this.localPrivateKey = localPrivateKey;
- this.peerPublicKey = peerPublicKey;
- }
-
- @Override
- public SecretKey deriveKey(String algorithm,
- AlgorithmParameterSpec params) throws IOException {
- if (!context.negotiatedProtocol.useTLS13PlusSpec()) {
- return t12DeriveKey(algorithm, params);
- } else {
- return t13DeriveKey(algorithm, params);
- }
+ "No sufficient DHE key agreement parameters negotiated");
}
- private SecretKey t12DeriveKey(String algorithm,
- AlgorithmParameterSpec params) throws IOException {
- try {
- KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
- ka.init(localPrivateKey);
- ka.doPhase(peerPublicKey, true);
- SecretKey preMasterSecret =
- ka.generateSecret("TlsPremasterSecret");
- SSLMasterKeyDerivation mskd =
- SSLMasterKeyDerivation.valueOf(
- context.negotiatedProtocol);
- if (mskd == null) {
- // unlikely
- throw new SSLHandshakeException(
- "No expected master key derivation for protocol: " +
- context.negotiatedProtocol.name);
- }
- SSLKeyDerivation kd = mskd.createKeyDerivation(
- context, preMasterSecret);
- return kd.deriveKey("MasterSecret", params);
- } catch (GeneralSecurityException gse) {
- throw (SSLHandshakeException) new SSLHandshakeException(
- "Could not generate secret").initCause(gse);
- }
- }
-
- private SecretKey t13DeriveKey(String algorithm,
- AlgorithmParameterSpec params) throws IOException {
- try {
- KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
- ka.init(localPrivateKey);
- ka.doPhase(peerPublicKey, true);
- SecretKey sharedSecret =
- ka.generateSecret("TlsPremasterSecret");
-
- HashAlg hashAlg = context.negotiatedCipherSuite.hashAlg;
- SSLKeyDerivation kd = context.handshakeKeyDerivation;
- HKDF hkdf = new HKDF(hashAlg.name);
- if (kd == null) { // No PSK is in use.
- // If PSK is not in use Early Secret will still be
- // HKDF-Extract(0, 0).
- byte[] zeros = new byte[hashAlg.hashLength];
- SecretKeySpec ikm =
- new SecretKeySpec(zeros, "TlsPreSharedSecret");
- SecretKey earlySecret =
- hkdf.extract(zeros, ikm, "TlsEarlySecret");
- kd = new SSLSecretDerivation(context, earlySecret);
- }
-
- // derive salt secret
- SecretKey saltSecret = kd.deriveKey("TlsSaltSecret", null);
-
- // derive handshake secret
- return hkdf.extract(saltSecret, sharedSecret, algorithm);
- } catch (GeneralSecurityException gse) {
- throw (SSLHandshakeException) new SSLHandshakeException(
- "Could not generate secret").initCause(gse);
- }
- }
+ return new KAKeyDerivation("DiffieHellman", context,
+ dhePossession.privateKey, dheCredentials.popPublicKey);
}
}
}
--- a/src/java.base/share/classes/sun/security/ssl/ECDHKeyExchange.java Fri Aug 17 14:37:01 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/ECDHKeyExchange.java Mon Aug 20 13:16:49 2018 -0400
@@ -304,7 +304,7 @@
"No sufficient ECDHE key agreement parameters negotiated");
}
- return new ECDHEKAKeyDerivation(shc,
+ return new KAKeyDerivation("ECDH", shc,
x509Possession.popPrivateKey, ecdheCredentials.popPublicKey);
}
@@ -353,7 +353,7 @@
"No sufficient ECDH key agreement parameters negotiated");
}
- return new ECDHEKAKeyDerivation(chc,
+ return new KAKeyDerivation("ECDH", chc,
ecdhePossession.privateKey, x509Credentials.popPublicKey);
}
}
@@ -397,94 +397,8 @@
"No sufficient ECDHE key agreement parameters negotiated");
}
- return new ECDHEKAKeyDerivation(context,
+ return new KAKeyDerivation("ECDH", context,
ecdhePossession.privateKey, ecdheCredentials.popPublicKey);
}
}
-
- private static final
- class ECDHEKAKeyDerivation implements SSLKeyDerivation {
- private final HandshakeContext context;
- private final PrivateKey localPrivateKey;
- private final PublicKey peerPublicKey;
-
- ECDHEKAKeyDerivation(HandshakeContext context,
- PrivateKey localPrivateKey,
- PublicKey peerPublicKey) {
- this.context = context;
- this.localPrivateKey = localPrivateKey;
- this.peerPublicKey = peerPublicKey;
- }
-
- @Override
- public SecretKey deriveKey(String algorithm,
- AlgorithmParameterSpec params) throws IOException {
- if (!context.negotiatedProtocol.useTLS13PlusSpec()) {
- return t12DeriveKey(algorithm, params);
- } else {
- return t13DeriveKey(algorithm, params);
- }
- }
-
- private SecretKey t12DeriveKey(String algorithm,
- AlgorithmParameterSpec params) throws IOException {
- try {
- KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
- ka.init(localPrivateKey);
- ka.doPhase(peerPublicKey, true);
- SecretKey preMasterSecret =
- ka.generateSecret("TlsPremasterSecret");
-
- SSLMasterKeyDerivation mskd =
- SSLMasterKeyDerivation.valueOf(
- context.negotiatedProtocol);
- if (mskd == null) {
- // unlikely
- throw new SSLHandshakeException(
- "No expected master key derivation for protocol: " +
- context.negotiatedProtocol.name);
- }
- SSLKeyDerivation kd = mskd.createKeyDerivation(
- context, preMasterSecret);
- return kd.deriveKey("MasterSecret", params);
- } catch (GeneralSecurityException gse) {
- throw (SSLHandshakeException) new SSLHandshakeException(
- "Could not generate secret").initCause(gse);
- }
- }
-
- private SecretKey t13DeriveKey(String algorithm,
- AlgorithmParameterSpec params) throws IOException {
- try {
- KeyAgreement ka = JsseJce.getKeyAgreement("ECDH");
- ka.init(localPrivateKey);
- ka.doPhase(peerPublicKey, true);
- SecretKey sharedSecret =
- ka.generateSecret("TlsPremasterSecret");
-
- HashAlg hashAlg = context.negotiatedCipherSuite.hashAlg;
- SSLKeyDerivation kd = context.handshakeKeyDerivation;
- HKDF hkdf = new HKDF(hashAlg.name);
- if (kd == null) { // No PSK is in use.
- // If PSK is not in use Early Secret will still be
- // HKDF-Extract(0, 0).
- byte[] zeros = new byte[hashAlg.hashLength];
- SecretKeySpec ikm =
- new SecretKeySpec(zeros, "TlsPreSharedSecret");
- SecretKey earlySecret =
- hkdf.extract(zeros, ikm, "TlsEarlySecret");
- kd = new SSLSecretDerivation(context, earlySecret);
- }
-
- // derive salt secret
- SecretKey saltSecret = kd.deriveKey("TlsSaltSecret", null);
-
- // derive handshake secret
- return hkdf.extract(saltSecret, sharedSecret, algorithm);
- } catch (GeneralSecurityException gse) {
- throw (SSLHandshakeException) new SSLHandshakeException(
- "Could not generate secret").initCause(gse);
- }
- }
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/KAKeyDerivation.java Mon Aug 20 13:16:49 2018 -0400
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.ssl;
+
+import javax.crypto.KeyAgreement;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.net.ssl.SSLHandshakeException;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+
+public class KAKeyDerivation implements SSLKeyDerivation {
+
+ private final String algorithmName;
+ private final HandshakeContext context;
+ private final PrivateKey localPrivateKey;
+ private final PublicKey peerPublicKey;
+
+ KAKeyDerivation(String algorithmName,
+ HandshakeContext context,
+ PrivateKey localPrivateKey,
+ PublicKey peerPublicKey) {
+ this.algorithmName = algorithmName;
+ this.context = context;
+ this.localPrivateKey = localPrivateKey;
+ this.peerPublicKey = peerPublicKey;
+ }
+
+ @Override
+ public SecretKey deriveKey(String algorithm,
+ AlgorithmParameterSpec params) throws IOException {
+ if (!context.negotiatedProtocol.useTLS13PlusSpec()) {
+ return t12DeriveKey(algorithm, params);
+ } else {
+ return t13DeriveKey(algorithm, params);
+ }
+ }
+
+ private SecretKey t12DeriveKey(String algorithm,
+ AlgorithmParameterSpec params) throws IOException {
+ try {
+ KeyAgreement ka = JsseJce.getKeyAgreement(algorithmName);
+ ka.init(localPrivateKey);
+ ka.doPhase(peerPublicKey, true);
+ SecretKey preMasterSecret =
+ ka.generateSecret("TlsPremasterSecret");
+ SSLMasterKeyDerivation mskd =
+ SSLMasterKeyDerivation.valueOf(
+ context.negotiatedProtocol);
+ if (mskd == null) {
+ // unlikely
+ throw new SSLHandshakeException(
+ "No expected master key derivation for protocol: " +
+ context.negotiatedProtocol.name);
+ }
+ SSLKeyDerivation kd = mskd.createKeyDerivation(
+ context, preMasterSecret);
+ return kd.deriveKey("MasterSecret", params);
+ } catch (GeneralSecurityException gse) {
+ throw (SSLHandshakeException) new SSLHandshakeException(
+ "Could not generate secret").initCause(gse);
+ }
+ }
+
+ private SecretKey t13DeriveKey(String algorithm,
+ AlgorithmParameterSpec params) throws IOException {
+ try {
+ KeyAgreement ka = JsseJce.getKeyAgreement(algorithmName);
+ ka.init(localPrivateKey);
+ ka.doPhase(peerPublicKey, true);
+ SecretKey sharedSecret =
+ ka.generateSecret("TlsPremasterSecret");
+
+ CipherSuite.HashAlg hashAlg = context.negotiatedCipherSuite.hashAlg;
+ SSLKeyDerivation kd = context.handshakeKeyDerivation;
+ HKDF hkdf = new HKDF(hashAlg.name);
+ if (kd == null) { // No PSK is in use.
+ // If PSK is not in use Early Secret will still be
+ // HKDF-Extract(0, 0).
+ byte[] zeros = new byte[hashAlg.hashLength];
+ SecretKeySpec ikm =
+ new SecretKeySpec(zeros, "TlsPreSharedSecret");
+ SecretKey earlySecret =
+ hkdf.extract(zeros, ikm, "TlsEarlySecret");
+ kd = new SSLSecretDerivation(context, earlySecret);
+ }
+
+ // derive salt secret
+ SecretKey saltSecret = kd.deriveKey("TlsSaltSecret", null);
+
+ // derive handshake secret
+ return hkdf.extract(saltSecret, sharedSecret, algorithm);
+ } catch (GeneralSecurityException gse) {
+ throw (SSLHandshakeException) new SSLHandshakeException(
+ "Could not generate secret").initCause(gse);
+ }
+ }
+}
\ No newline at end of file
--- a/src/java.base/share/classes/sun/security/ssl/SupportedGroupsExtension.java Fri Aug 17 14:37:01 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/SupportedGroupsExtension.java Mon Aug 20 13:16:49 2018 -0400
@@ -193,6 +193,7 @@
}
public AlgorithmParameters getParameters() {
+
AlgorithmParameters result = namedGroupParams.get(ng);
if (result == null) {
Optional<AlgorithmParameters> paramsOpt = getParametersImpl();
@@ -201,6 +202,7 @@
namedGroupParams.put(ng, result);
}
}
+
return result;
}
@@ -313,22 +315,18 @@
@Override
public boolean isAvailable() {
- try {
- AlgorithmParameters params = getParameters();
- AlgorithmParameterSpec spec = getFFDHEDHParameterSpec(getNamedGroup());
- params.init(spec);
- return true;
- } catch (InvalidParameterSpecException e) {
- return false;
- }
+ AlgorithmParameters params = getParameters();
+ return params != null;
}
@Override
protected Optional<AlgorithmParameters> getParametersImpl() {
try {
- return Optional.of(
- JsseJce.getAlgorithmParameters("DiffieHellman"));
- } catch(NoSuchAlgorithmException ex) {
+ AlgorithmParameters params = JsseJce.getAlgorithmParameters("DiffieHellman");
+ AlgorithmParameterSpec spec = getFFDHEDHParameterSpec(getNamedGroup());
+ params.init(spec);
+ return Optional.of(params);
+ } catch(InvalidParameterSpecException | NoSuchAlgorithmException ex) {
return Optional.empty();
}
}
@@ -366,22 +364,18 @@
@Override
public boolean isAvailable() {
- try {
- AlgorithmParameters params = getParameters();
- AlgorithmParameterSpec spec = new ECGenParameterSpec(getNamedGroup().oid);
- params.init(spec);
- return true;
- } catch (InvalidParameterSpecException e) {
- return false;
- }
+ AlgorithmParameters params = getParameters();
+ return params != null;
}
@Override
protected Optional<AlgorithmParameters> getParametersImpl() {
try {
- return Optional.of(
- JsseJce.getAlgorithmParameters("EC"));
- } catch(NoSuchAlgorithmException ex) {
+ AlgorithmParameters params = JsseJce.getAlgorithmParameters("EC");
+ AlgorithmParameterSpec spec = new ECGenParameterSpec(getNamedGroup().oid);
+ params.init(spec);
+ return Optional.of(params);
+ } catch(InvalidParameterSpecException | NoSuchAlgorithmException ex) {
return Optional.empty();
}
}
@@ -849,11 +843,12 @@
// check whether the group is supported by the underlying providers
public static boolean isAvailableGroup(NamedGroup namedGroup) {
- Optional<NamedGroupFunctions> ngf = namedGroup.getFunctions();
- if (ngf.isEmpty()) {
+ Optional<NamedGroupFunctions> ngfOpt = namedGroup.getFunctions();
+ if (ngfOpt.isEmpty()) {
return false;
}
- return ngf.get().isAvailable();
+ NamedGroupFunctions ngf = ngfOpt.get();
+ return ngf.isAvailable();
}
--- a/src/java.base/share/classes/sun/security/ssl/XDHKeyExchange.java Fri Aug 17 14:37:01 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/XDHKeyExchange.java Mon Aug 20 13:16:49 2018 -0400
@@ -26,8 +26,6 @@
package sun.security.ssl;
import java.io.IOException;
-import java.security.AlgorithmConstraints;
-import java.security.CryptoPrimitive;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
@@ -35,29 +33,15 @@
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
-import java.security.interfaces.XECPrivateKey;
import java.security.interfaces.XECPublicKey;
import java.security.spec.*;
-import java.util.EnumSet;
-import javax.crypto.KeyAgreement;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.SSLHandshakeException;
-import sun.security.ssl.CipherSuite.HashAlg;
import sun.security.ssl.SupportedGroupsExtension.NamedGroup;
import sun.security.ssl.SupportedGroupsExtension.NamedGroupType;
-import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
-import sun.security.ssl.X509Authentication.X509Credentials;
-import sun.security.ssl.X509Authentication.X509Possession;
import sun.security.util.ECUtil;
final class XDHKeyExchange {
- static final SSLPossessionGenerator poGenerator =
- new XDHEPossessionGenerator();
static final SSLKeyAgreementGenerator xdheKAGenerator =
new XDHEKAGenerator();
- static final SSLKeyAgreementGenerator xdhKAGenerator =
- new XDHKAGenerator();
static final class XDHECredentials implements SSLKeyAgreementCredentials {
final XECPublicKey popPublicKey;
@@ -115,22 +99,6 @@
this.namedGroup = namedGroup;
}
- XDHEPossession(XDHECredentials credentials, SecureRandom random) {
- AlgorithmParameterSpec params = credentials.popPublicKey.getParams();
- try {
- KeyPairGenerator kpg = JsseJce.getKeyPairGenerator(credentials.namedGroup.algorithm);
- kpg.initialize(params, random);
- KeyPair kp = kpg.generateKeyPair();
- privateKey = kp.getPrivate();
- publicKey = (XECPublicKey)kp.getPublic();
- } catch (GeneralSecurityException e) {
- throw new RuntimeException(
- "Could not generate XDH keypair", e);
- }
-
- this.namedGroup = credentials.namedGroup;
- }
-
@Override
public byte[] encode() {
try {
@@ -139,222 +107,6 @@
throw new RuntimeException(ex);
}
}
-
- // called by client handshaker
- SecretKey getAgreedSecret(
- PublicKey peerPublicKey) throws SSLHandshakeException {
-
- try {
- KeyAgreement ka = JsseJce.getKeyAgreement("XDH");
- ka.init(privateKey);
- ka.doPhase(peerPublicKey, true);
- return ka.generateSecret("TlsPremasterSecret");
- } catch (GeneralSecurityException e) {
- throw (SSLHandshakeException) new SSLHandshakeException(
- "Could not generate secret").initCause(e);
- }
- }
-
- // called by ServerHandshaker
- SecretKey getAgreedSecret(
- byte[] encodedKey) throws SSLHandshakeException {
- try {
- AlgorithmParameterSpec params = publicKey.getParams();
-
- KeyFactory kf = JsseJce.getKeyFactory("XDH");
- XECPublicKeySpec spec = ECUtil.decodeXecPublicKey(encodedKey, params);
- PublicKey peerPublicKey = kf.generatePublic(spec);
- return getAgreedSecret(peerPublicKey);
- } catch (GeneralSecurityException | java.io.IOException e) {
- throw (SSLHandshakeException) new SSLHandshakeException(
- "Could not generate secret").initCause(e);
- }
- }
-
- // Check constraints of the specified EC public key.
- void checkConstraints(AlgorithmConstraints constraints,
- byte[] encodedKey) throws SSLHandshakeException {
- try {
-
- AlgorithmParameterSpec params = publicKey.getParams();
- XECPublicKeySpec spec = ECUtil.decodeXecPublicKey(encodedKey, params);
-
- KeyFactory kf = JsseJce.getKeyFactory("XDH");
- PublicKey pubKey = kf.generatePublic(spec);
-
- // check constraints of ECPublicKey
- if (!constraints.permits(
- EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), pubKey)) {
- throw new SSLHandshakeException(
- "ECPublicKey does not comply to algorithm constraints");
- }
- } catch (GeneralSecurityException | java.io.IOException e) {
- throw (SSLHandshakeException) new SSLHandshakeException(
- "Could not generate ECPublicKey").initCause(e);
- }
- }
- }
-
- private static final
- class XDHEPossessionGenerator implements SSLPossessionGenerator {
- // Prevent instantiation of this class.
- private XDHEPossessionGenerator() {
- // blank
- }
-
- @Override
- public SSLPossession createPossession(HandshakeContext context) {
- NamedGroup preferableNamedGroup = null;
- if ((context.clientRequestedNamedGroups != null) &&
- (!context.clientRequestedNamedGroups.isEmpty())) {
- preferableNamedGroup = SupportedGroups.getPreferredGroup(
- context.negotiatedProtocol,
- context.algorithmConstraints,
- NamedGroupType.NAMED_GROUP_XDH,
- context.clientRequestedNamedGroups);
- } else {
- preferableNamedGroup = SupportedGroups.getPreferredGroup(
- context.negotiatedProtocol,
- context.algorithmConstraints,
- NamedGroupType.NAMED_GROUP_XDH);
- }
-
- if (preferableNamedGroup != null) {
- return new XDHEPossession(preferableNamedGroup,
- context.sslContext.getSecureRandom());
- }
-
- // no match found, cannot use this cipher suite.
- //
- return null;
- }
- }
-
- private static final
- class XDHKAGenerator implements SSLKeyAgreementGenerator {
- // Prevent instantiation of this class.
- private XDHKAGenerator() {
- // blank
- }
-
- @Override
- public SSLKeyDerivation createKeyDerivation(
- HandshakeContext context) throws IOException {
- if (context instanceof ServerHandshakeContext) {
- return createServerKeyDerivation(
- (ServerHandshakeContext)context);
- } else {
- return createClientKeyDerivation(
- (ClientHandshakeContext)context);
- }
- }
-
- private SSLKeyDerivation createServerKeyDerivation(
- ServerHandshakeContext shc) throws IOException {
- X509Possession x509Possession = null;
- XDHECredentials xdheCredentials = null;
- for (SSLPossession poss : shc.handshakePossessions) {
- if (!(poss instanceof X509Possession)) {
- continue;
- }
-
- PrivateKey privateKey = ((X509Possession)poss).popPrivateKey;
- if (! (privateKey instanceof XECPrivateKey)) {
- continue;
- }
- AlgorithmParameterSpec params = ((XECPrivateKey)privateKey).getParams();
- // group must be specified by name
- if (!(params instanceof NamedParameterSpec)) {
- continue;
- }
- NamedParameterSpec namedParams = (NamedParameterSpec) params;
- NamedGroup ng = NamedGroup.valueOf(namedParams.getName());
- if (ng == null) {
- // unlikely, have been checked during cipher suite negotiation.
- shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
- "Unsupported server cert for XDH key exchange");
- }
-
- for (SSLCredentials cred : shc.handshakeCredentials) {
- if (!(cred instanceof XDHECredentials)) {
- continue;
- }
- if (ng.equals(((XDHECredentials)cred).namedGroup)) {
- xdheCredentials = (XDHECredentials)cred;
- break;
- }
- }
-
- if (xdheCredentials != null) {
- x509Possession = (X509Possession)poss;
- break;
- }
- }
-
- if (x509Possession == null || xdheCredentials == null) {
- shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
- "No sufficient XDHE key agreement parameters negotiated");
- }
-
- return new XDHEKAKeyDerivation(shc,
- x509Possession.popPrivateKey, xdheCredentials.popPublicKey);
- }
-
- private SSLKeyDerivation createClientKeyDerivation(
- ClientHandshakeContext chc) throws IOException {
-
- XDHEPossession xdhePossession = null;
- X509Credentials x509Credentials = null;
- for (SSLPossession poss : chc.handshakePossessions) {
- if (!(poss instanceof XDHEPossession)) {
- continue;
- }
-
- NamedGroup ng = ((XDHEPossession)poss).namedGroup;
- for (SSLCredentials cred : chc.handshakeCredentials) {
- if (!(cred instanceof X509Credentials)) {
- continue;
- }
-
- PublicKey publicKey = ((X509Credentials)cred).popPublicKey;
- if (!(publicKey instanceof XECPublicKey)) {
- continue;
- }
- XECPublicKey xecPublicKey = (XECPublicKey) publicKey;
- AlgorithmParameterSpec params = xecPublicKey.getParams();
- // group must be specified by name
- if (!(params instanceof NamedParameterSpec)) {
- continue;
- }
- NamedParameterSpec namedParams = (NamedParameterSpec) params;
-
- NamedGroup namedGroup = NamedGroup.valueOf(namedParams.getName());
- if (namedGroup == null) {
- // unlikely, should have been checked previously
- chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
- "Unsupported EC server cert for XDH key exchange");
- }
-
- if (ng.equals(namedGroup)) {
- x509Credentials = (X509Credentials)cred;
- break;
- }
- }
-
- if (x509Credentials != null) {
- xdhePossession = (XDHEPossession)poss;
- break;
- }
- }
-
- if (xdhePossession == null || x509Credentials == null) {
- chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
- "No sufficient XDH key agreement parameters negotiated");
- }
-
- return new XDHEKAKeyDerivation(chc,
- xdhePossession.privateKey, x509Credentials.popPublicKey);
- }
}
private static final
@@ -396,88 +148,9 @@
"No sufficient XDHE key agreement parameters negotiated");
}
- return new XDHEKAKeyDerivation(context,
+ return new KAKeyDerivation("XDH", context,
xdhePossession.privateKey, xdheCredentials.popPublicKey);
}
}
- private static final
- class XDHEKAKeyDerivation implements SSLKeyDerivation {
- private final HandshakeContext context;
- private final PrivateKey localPrivateKey;
- private final PublicKey peerPublicKey;
-
- XDHEKAKeyDerivation(HandshakeContext context,
- PrivateKey localPrivateKey,
- PublicKey peerPublicKey) {
- this.context = context;
- this.localPrivateKey = localPrivateKey;
- this.peerPublicKey = peerPublicKey;
- }
-
- @Override
- public SecretKey deriveKey(String algorithm,
- AlgorithmParameterSpec params) throws IOException {
- if (!context.negotiatedProtocol.useTLS13PlusSpec()) {
- return t12DeriveKey(algorithm, params);
- } else {
- return t13DeriveKey(algorithm, params);
- }
- }
-
- private SecretKey t12DeriveKey(String algorithm,
- AlgorithmParameterSpec params) throws IOException {
- try {
- KeyAgreement ka = JsseJce.getKeyAgreement("XDH");
- ka.init(localPrivateKey);
- ka.doPhase(peerPublicKey, true);
- SecretKey preMasterSecret =
- ka.generateSecret("TlsPremasterSecret");
-
- SSLMasterKeyDerivation mskd =
- SSLMasterKeyDerivation.valueOf(
- context.negotiatedProtocol);
- SSLKeyDerivation kd = mskd.createKeyDerivation(
- context, preMasterSecret);
- return kd.deriveKey("TODO", params);
- } catch (GeneralSecurityException gse) {
- throw (SSLHandshakeException) new SSLHandshakeException(
- "Could not generate secret").initCause(gse);
- }
- }
-
- private SecretKey t13DeriveKey(String algorithm,
- AlgorithmParameterSpec params) throws IOException {
- try {
- KeyAgreement ka = JsseJce.getKeyAgreement("XDH");
- ka.init(localPrivateKey);
- ka.doPhase(peerPublicKey, true);
- SecretKey sharedSecret =
- ka.generateSecret("TlsPremasterSecret");
-
- HashAlg hashAlg = context.negotiatedCipherSuite.hashAlg;
- SSLKeyDerivation kd = context.handshakeKeyDerivation;
- HKDF hkdf = new HKDF(hashAlg.name);
- if (kd == null) { // No PSK is in use.
- // If PSK is not in use Early Secret will still be
- // HKDF-Extract(0, 0).
- byte[] zeros = new byte[hashAlg.hashLength];
- SecretKeySpec ikm =
- new SecretKeySpec(zeros, "TlsPreSharedSecret");
- SecretKey earlySecret =
- hkdf.extract(zeros, ikm, "TlsEarlySecret");
- kd = new SSLSecretDerivation(context, earlySecret);
- }
-
- // derive salt secret
- SecretKey saltSecret = kd.deriveKey("TlsSaltSecret", null);
-
- // derive handshake secret
- return hkdf.extract(saltSecret, sharedSecret, algorithm);
- } catch (GeneralSecurityException gse) {
- throw (SSLHandshakeException) new SSLHandshakeException(
- "Could not generate secret").initCause(gse);
- }
- }
- }
}