src/java.base/share/classes/sun/security/ssl/DHCrypt.java
changeset 50768 68fa3d4026ea
parent 50767 356eaea05bf0
child 50769 1bf8f9840705
--- a/src/java.base/share/classes/sun/security/ssl/DHCrypt.java	Mon Jun 25 21:22:16 2018 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/*
- * Copyright (c) 1996, 2017, 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 java.math.BigInteger;
-import java.security.*;
-import javax.net.ssl.SSLHandshakeException;
-import javax.crypto.SecretKey;
-import javax.crypto.KeyAgreement;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.*;
-import java.util.EnumSet;
-
-import sun.security.util.KeyUtil;
-
-/**
- * This class implements the Diffie-Hellman key exchange algorithm.
- * D-H means combining your private key with your partners public key to
- * generate a number. The peer does the same with its private key and our
- * public key. Through the magic of Diffie-Hellman we both come up with the
- * same number. This number is secret (discounting MITM attacks) and hence
- * called the shared secret. It has the same length as the modulus, e.g. 512
- * or 1024 bit. Man-in-the-middle attacks are typically countered by an
- * independent authentication step using certificates (RSA, DSA, etc.).
- *
- * The thing to note is that the shared secret is constant for two partners
- * with constant private keys. This is often not what we want, which is why
- * it is generally a good idea to create a new private key for each session.
- * Generating a private key involves one modular exponentiation assuming
- * suitable D-H parameters are available.
- *
- * General usage of this class (TLS DHE case):
- *  . if we are server, call DHCrypt(keyLength,random). This generates
- *    an ephemeral keypair of the request length.
- *  . if we are client, call DHCrypt(modulus, base, random). This
- *    generates an ephemeral keypair using the parameters specified by
- *    the server.
- *  . send parameters and public value to remote peer
- *  . receive peers ephemeral public key
- *  . call getAgreedSecret() to calculate the shared secret
- *
- * In TLS the server chooses the parameter values itself, the client must use
- * those sent to it by the server.
- *
- * The use of ephemeral keys as described above also achieves what is called
- * "forward secrecy". This means that even if the authentication keys are
- * broken at a later date, the shared secret remains secure. The session is
- * compromised only if the authentication keys are already broken at the
- * time the key exchange takes place and an active MITM attack is used.
- * This is in contrast to straightforward encrypting RSA key exchanges.
- *
- * @author David Brownell
- */
-final class DHCrypt {
-
-    // group parameters (prime modulus and generator)
-    private BigInteger modulus;                 // P (aka N)
-    private BigInteger base;                    // G (aka alpha)
-
-    // our private key (including private component x)
-    private PrivateKey privateKey;
-
-    // public component of our key, X = (g ^ x) mod p
-    private BigInteger publicValue;             // X (aka y)
-
-    // the times to recove from failure if public key validation
-    private static int MAX_FAILOVER_TIMES = 2;
-
-    /**
-     * Generate a Diffie-Hellman keypair of the specified size.
-     */
-    DHCrypt(int keyLength, SecureRandom random) {
-        this(keyLength,
-            PredefinedDHParameterSpecs.definedParams.get(keyLength), random);
-    }
-
-    /**
-     * Generate a Diffie-Hellman keypair using the specified parameters.
-     *
-     * @param modulus the Diffie-Hellman modulus P
-     * @param base the Diffie-Hellman base G
-     */
-    DHCrypt(BigInteger modulus, BigInteger base, SecureRandom random) {
-        this(modulus.bitLength(),
-                new DHParameterSpec(modulus, base), random);
-    }
-
-    /**
-     * Generate a Diffie-Hellman keypair using the named group.
-     */
-    DHCrypt(NamedGroup namedGroup, SecureRandom random) {
-        this(-1,        // The length (-1) is not used in the implementation.
-            SupportedGroupsExtension.getDHParameterSpec(namedGroup), random);
-    }
-
-    /**
-     * Generate a Diffie-Hellman keypair using the specified size and
-     * parameters.
-     */
-    private DHCrypt(int keyLength,
-            DHParameterSpec params, SecureRandom random) {
-
-        try {
-            KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
-            if (params != null) {
-                kpg.initialize(params, random);
-            } else {
-                kpg.initialize(keyLength, random);
-            }
-
-            DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
-            if (spec == null) {
-                throw new RuntimeException("Could not generate DH keypair");
-            }
-
-            publicValue = spec.getY();
-            modulus = spec.getP();
-            base = spec.getG();
-        } catch (GeneralSecurityException e) {
-            throw new RuntimeException("Could not generate DH keypair", e);
-        }
-    }
-
-    static DHPublicKeySpec getDHPublicKeySpec(PublicKey key) {
-        if (key instanceof DHPublicKey) {
-            DHPublicKey dhKey = (DHPublicKey)key;
-            DHParameterSpec params = dhKey.getParams();
-            return new DHPublicKeySpec(dhKey.getY(),
-                                    params.getP(), params.getG());
-        }
-        try {
-            KeyFactory factory = JsseJce.getKeyFactory("DiffieHellman");
-            return factory.getKeySpec(key, DHPublicKeySpec.class);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-
-    /** Returns the Diffie-Hellman modulus. */
-    BigInteger getModulus() {
-        return modulus;
-    }
-
-    /** Returns the Diffie-Hellman base (generator).  */
-    BigInteger getBase() {
-        return base;
-    }
-
-    /**
-     * Gets the public key of this end of the key exchange.
-     */
-    BigInteger getPublicKey() {
-        return publicValue;
-    }
-
-    /**
-     * Get the secret data that has been agreed on through Diffie-Hellman
-     * key agreement protocol.  Note that in the two party protocol, if
-     * the peer keys are already known, no other data needs to be sent in
-     * order to agree on a secret.  That is, a secured message may be
-     * sent without any mandatory round-trip overheads.
-     *
-     * <P>It is illegal to call this member function if the private key
-     * has not been set (or generated).
-     *
-     * @param  peerPublicKey the peer's public key.
-     * @param  keyIsValidated whether the {@code peerPublicKey} has beed
-     *         validated
-     * @return the secret, which is an unsigned big-endian integer
-     *         the same size as the Diffie-Hellman modulus.
-     */
-    SecretKey getAgreedSecret(BigInteger peerPublicValue,
-            boolean keyIsValidated) throws SSLHandshakeException {
-        try {
-            KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
-            DHPublicKeySpec spec =
-                        new DHPublicKeySpec(peerPublicValue, modulus, base);
-            PublicKey publicKey = kf.generatePublic(spec);
-            KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
-
-            // validate the Diffie-Hellman public key
-            if (!keyIsValidated &&
-                    !KeyUtil.isOracleJCEProvider(ka.getProvider().getName())) {
-                try {
-                    KeyUtil.validate(spec);
-                } catch (InvalidKeyException ike) {
-                    // prefer handshake_failure alert to internal_error alert
-                    throw new SSLHandshakeException(ike.getMessage());
-                }
-            }
-
-            ka.init(privateKey);
-            ka.doPhase(publicKey, true);
-            return ka.generateSecret("TlsPremasterSecret");
-        } catch (GeneralSecurityException e) {
-            throw (SSLHandshakeException) new SSLHandshakeException(
-                "Could not generate secret").initCause(e);
-        }
-    }
-
-    // Check constraints of the specified DH public key.
-    void checkConstraints(AlgorithmConstraints constraints,
-            BigInteger peerPublicValue) throws SSLHandshakeException {
-
-        try {
-            KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
-            DHPublicKeySpec spec =
-                        new DHPublicKeySpec(peerPublicValue, modulus, base);
-            DHPublicKey publicKey = (DHPublicKey)kf.generatePublic(spec);
-
-            // check constraints of DHPublicKey
-            if (!constraints.permits(
-                    EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), publicKey)) {
-                throw new SSLHandshakeException(
-                    "DHPublicKey does not comply to algorithm constraints");
-            }
-        } catch (GeneralSecurityException gse) {
-            throw (SSLHandshakeException) new SSLHandshakeException(
-                    "Could not generate DHPublicKey").initCause(gse);
-        }
-    }
-
-    // Generate and validate DHPublicKeySpec
-    private DHPublicKeySpec generateDHPublicKeySpec(KeyPairGenerator kpg)
-            throws GeneralSecurityException {
-
-        boolean doExtraValiadtion =
-                    (!KeyUtil.isOracleJCEProvider(kpg.getProvider().getName()));
-        for (int i = 0; i <= MAX_FAILOVER_TIMES; i++) {
-            KeyPair kp = kpg.generateKeyPair();
-            privateKey = kp.getPrivate();
-            DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
-
-            // validate the Diffie-Hellman public key
-            if (doExtraValiadtion) {
-                try {
-                    KeyUtil.validate(spec);
-                } catch (InvalidKeyException ivke) {
-                    if (i == MAX_FAILOVER_TIMES) {
-                        throw ivke;
-                    }
-                    // otherwise, ignore the exception and try the next one
-                    continue;
-                }
-            }
-
-            return spec;
-        }
-
-        return null;
-    }
-}
-