jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java
author martin
Thu, 30 Oct 2014 07:31:41 -0700
changeset 28059 e576535359cc
parent 25859 3317bb8137f4
child 28550 003089aca6b9
permissions -rw-r--r--
8067377: My hobby: caning, then then canning, the the can-can Summary: Fix ALL the stutters! Reviewed-by: rriggs, mchung, lancea
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
18283
f842a42076b9 7188658: Add possibility to disable client initiated renegotiation
xuelei
parents: 17189
diff changeset
     2
 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5182
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5182
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5182
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5182
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5182
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
package sun.security.ssl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.security.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.security.cert.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.security.interfaces.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.security.spec.ECParameterSpec;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import javax.crypto.SecretKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import javax.crypto.spec.SecretKeySpec;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import javax.net.ssl.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import javax.security.auth.Subject;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
20539
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
    43
import sun.security.util.KeyUtil;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
    44
import sun.security.action.GetPropertyAction;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import sun.security.ssl.HandshakeMessage.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import sun.security.ssl.CipherSuite.*;
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
    47
import sun.security.ssl.SignatureAndHashAlgorithm.*;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
import static sun.security.ssl.CipherSuite.KeyExchange.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * ServerHandshaker does the protocol handshaking from the point
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * of view of a server.  It is driven asychronously by handshake messages
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * as delivered by the parent Handshaker class, and also uses
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * common functionality (e.g. key generation) that is provided there.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * @author David Brownell
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
final class ServerHandshaker extends Handshaker {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    // is the server going to require the client to authenticate?
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    private byte                doClientAuth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    // our authentication info
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    private X509Certificate[]   certs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    private PrivateKey          privateKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
    67
    private Object              serviceCreds;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    // flag to check for clientCertificateVerify message
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    private boolean             needClientVerify = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
     * For exportable ciphersuites using non-exportable key sizes, we use
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
     * ephemeral RSA keys. We could also do anonymous RSA in the same way
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
     * but there are no such ciphersuites currently defined.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    private PrivateKey          tempPrivateKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    private PublicKey           tempPublicKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     * For anonymous and ephemeral Diffie-Hellman key exchange, we use
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
     * ephemeral Diffie-Hellman keys.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    private DHCrypt dh;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    // Helper for ECDH based key exchanges
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    private ECDHCrypt ecdh;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    // version request by the client in its ClientHello
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    // we remember it for the RSA premaster secret version check
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    private ProtocolVersion clientRequestedVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    private SupportedEllipticCurvesExtension supportedCurves;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
    95
    // the preferable signature algorithm used by ServerKeyExchange message
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
    96
    SignatureAndHashAlgorithm preferableSignatureAlgorithm;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
    97
20539
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
    98
    // Flag to use smart ephemeral DH key which size matches the corresponding
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
    99
    // authentication key
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   100
    private static final boolean useSmartEphemeralDHKeys;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   101
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   102
    // Flag to use legacy ephemeral DH key which size is 512 bits for
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   103
    // exportable cipher suites, and 768 bits for others
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   104
    private static final boolean useLegacyEphemeralDHKeys;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   105
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   106
    // The customized ephemeral DH key size for non-exportable cipher suites.
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   107
    private static final int customizedDHKeySize;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   108
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   109
    static {
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   110
        String property = AccessController.doPrivileged(
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   111
                    new GetPropertyAction("jdk.tls.ephemeralDHKeySize"));
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   112
        if (property == null || property.length() == 0) {
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   113
            useLegacyEphemeralDHKeys = false;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   114
            useSmartEphemeralDHKeys = false;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   115
            customizedDHKeySize = -1;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   116
        } else if ("matched".equals(property)) {
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   117
            useLegacyEphemeralDHKeys = false;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   118
            useSmartEphemeralDHKeys = true;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   119
            customizedDHKeySize = -1;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   120
        } else if ("legacy".equals(property)) {
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   121
            useLegacyEphemeralDHKeys = true;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   122
            useSmartEphemeralDHKeys = false;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   123
            customizedDHKeySize = -1;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   124
        } else {
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   125
            useLegacyEphemeralDHKeys = false;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   126
            useSmartEphemeralDHKeys = false;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   127
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   128
            try {
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   129
                customizedDHKeySize = Integer.parseUnsignedInt(property);
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   130
                if (customizedDHKeySize < 1024 || customizedDHKeySize > 2048) {
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   131
                    throw new IllegalArgumentException(
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   132
                        "Customized DH key size should be positive integer " +
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   133
                        "between 1024 and 2048 bits, inclusive");
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   134
                }
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   135
            } catch (NumberFormatException nfe) {
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   136
                throw new IllegalArgumentException(
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   137
                        "Invalid system property jdk.tls.ephemeralDHKeySize");
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   138
            }
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   139
        }
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   140
    }
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
   141
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * Constructor ... use the keys found in the auth context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    ServerHandshaker(SSLSocketImpl socket, SSLContextImpl context,
5182
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   146
            ProtocolList enabledProtocols, byte clientAuth,
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   147
            ProtocolVersion activeProtocolVersion, boolean isInitialHandshake,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   148
            boolean secureRenegotiation,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   149
            byte[] clientVerifyData, byte[] serverVerifyData) {
5182
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   150
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        super(socket, context, enabledProtocols,
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   152
                (clientAuth != SSLEngineImpl.clauth_none), false,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   153
                activeProtocolVersion, isInitialHandshake, secureRenegotiation,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   154
                clientVerifyData, serverVerifyData);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        doClientAuth = clientAuth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * Constructor ... use the keys found in the auth context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    ServerHandshaker(SSLEngineImpl engine, SSLContextImpl context,
5182
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   162
            ProtocolList enabledProtocols, byte clientAuth,
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   163
            ProtocolVersion activeProtocolVersion,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   164
            boolean isInitialHandshake, boolean secureRenegotiation,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   165
            byte[] clientVerifyData, byte[] serverVerifyData) {
5182
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   166
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        super(engine, context, enabledProtocols,
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   168
                (clientAuth != SSLEngineImpl.clauth_none), false,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   169
                activeProtocolVersion, isInitialHandshake, secureRenegotiation,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   170
                clientVerifyData, serverVerifyData);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        doClientAuth = clientAuth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     * As long as handshaking has not started, we can change
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     * whether client authentication is required.  Otherwise,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
     * we will need to wait for the next handshake.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    void setClientAuth(byte clientAuth) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        doClientAuth = clientAuth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     * This routine handles all the server side handshake messages, one at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     * a time.  Given the message type (and in some cases the pending cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     * spec) it parses the type-specific message.  Then it calls a function
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     * that handles that specific message.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * It updates the state machine as each message is processed, and writes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     * responses as needed using the connection in the constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     */
14664
e71aa0962e70 8003950: Adds missing Override annotations and removes unnecessary imports in sun.security.ssl
xuelei
parents: 14194
diff changeset
   192
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    void processMessage(byte type, int message_len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        // In SSLv3 and TLS, messages follow strictly increasing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        // numerical order _except_ for one annoying special case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        //
16071
8b0a4953189c 7192393: Better Checking of order of TLS Messages
xuelei
parents: 12874
diff changeset
   199
        if ((state >= type)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                && (state != HandshakeMessage.ht_client_key_exchange
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
                    && type != HandshakeMessage.ht_certificate_verify)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            throw new SSLProtocolException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                    "Handshake message sequence violation, state = " + state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                    + ", type = " + type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            case HandshakeMessage.ht_client_hello:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                ClientHello ch = new ClientHello(input, message_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                 * send it off for processing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                this.clientHello(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            case HandshakeMessage.ht_certificate:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                if (doClientAuth == SSLEngineImpl.clauth_none) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                    fatalSE(Alerts.alert_unexpected_message,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                                "client sent unsolicited cert chain");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                    // NOTREACHED
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                this.clientCertificate(new CertificateMsg(input));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
            case HandshakeMessage.ht_client_key_exchange:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                SecretKey preMasterSecret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                switch (keyExchange) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
                case K_RSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                case K_RSA_EXPORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                     * The client's pre-master secret is decrypted using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                     * either the server's normal private RSA key, or the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                     * temporary one used for non-export or signing-only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                     * certificates/keys.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                     */
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
   236
                    RSAClientKeyExchange pms = new RSAClientKeyExchange(
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
   237
                            protocolVersion, clientRequestedVersion,
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
   238
                            sslContext.getSecureRandom(), input,
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
   239
                            message_len, privateKey);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                    preMasterSecret = this.clientKeyExchange(pms);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                case K_KRB5:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                case K_KRB5_EXPORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                    preMasterSecret = this.clientKeyExchange(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                        new KerberosClientKeyExchange(protocolVersion,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                            clientRequestedVersion,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                            sslContext.getSecureRandom(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                            input,
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
   249
                            this.getAccSE(),
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
   250
                            serviceCreds));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
                case K_DHE_RSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
                case K_DHE_DSS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
                case K_DH_ANON:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
                    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                     * The pre-master secret is derived using the normal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                     * Diffie-Hellman calculation.   Note that the main
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                     * protocol difference in these five flavors is in how
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                     * the ServerKeyExchange message was constructed!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                    preMasterSecret = this.clientKeyExchange(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                            new DHClientKeyExchange(input));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                case K_ECDH_RSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                case K_ECDH_ECDSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                case K_ECDHE_RSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                case K_ECDHE_ECDSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                case K_ECDH_ANON:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                    preMasterSecret = this.clientKeyExchange
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                                            (new ECDHClientKeyExchange(input));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                    throw new SSLProtocolException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                        ("Unrecognized key exchange: " + keyExchange);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
                //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                // All keys are calculated from the premaster secret
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                // and the exchanged nonces in the same way.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                calculateKeys(preMasterSecret, clientRequestedVersion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            case HandshakeMessage.ht_certificate_verify:
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   285
                this.clientCertificateVerify(new CertificateVerify(input,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   286
                            localSupportedSignAlgs, protocolVersion));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            case HandshakeMessage.ht_finished:
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   290
                this.clientFinished(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   291
                    new Finished(protocolVersion, input, cipherSuite));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                throw new SSLProtocolException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                        "Illegal server handshake msg, " + type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        //
16071
8b0a4953189c 7192393: Better Checking of order of TLS Messages
xuelei
parents: 12874
diff changeset
   300
        // Move state machine forward if the message handling
8b0a4953189c 7192393: Better Checking of order of TLS Messages
xuelei
parents: 12874
diff changeset
   301
        // code didn't already do so
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        //
16071
8b0a4953189c 7192393: Better Checking of order of TLS Messages
xuelei
parents: 12874
diff changeset
   303
        if (state < type) {
8b0a4953189c 7192393: Better Checking of order of TLS Messages
xuelei
parents: 12874
diff changeset
   304
            if(type == HandshakeMessage.ht_certificate_verify) {
8b0a4953189c 7192393: Better Checking of order of TLS Messages
xuelei
parents: 12874
diff changeset
   305
                state = type + 2;    // an annoying special case
8b0a4953189c 7192393: Better Checking of order of TLS Messages
xuelei
parents: 12874
diff changeset
   306
            } else {
8b0a4953189c 7192393: Better Checking of order of TLS Messages
xuelei
parents: 12874
diff changeset
   307
                state = type;
8b0a4953189c 7192393: Better Checking of order of TLS Messages
xuelei
parents: 12874
diff changeset
   308
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     * ClientHello presents the server with a bunch of options, to which the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     * server replies with a ServerHello listing the ones which this session
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     * will use.  If needed, it also writes its Certificate plus in some cases
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
     * a ServerKeyExchange message.  It may also write a CertificateRequest,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * to elicit a client certificate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * All these messages are terminated by a ServerHelloDone message.  In
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * most cases, all this can be sent in a single Record.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    private void clientHello(ClientHello mesg) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            mesg.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        }
5182
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   327
18283
f842a42076b9 7188658: Add possibility to disable client initiated renegotiation
xuelei
parents: 17189
diff changeset
   328
        // Reject client initiated renegotiation?
f842a42076b9 7188658: Add possibility to disable client initiated renegotiation
xuelei
parents: 17189
diff changeset
   329
        //
18570
9078dc28a187 8019359: To comment why not use no_renegotiation to reject client initiated renegotiation
xuelei
parents: 18283
diff changeset
   330
        // If server side should reject client-initiated renegotiation,
9078dc28a187 8019359: To comment why not use no_renegotiation to reject client initiated renegotiation
xuelei
parents: 18283
diff changeset
   331
        // send an alert_handshake_failure fatal alert, not a no_renegotiation
9078dc28a187 8019359: To comment why not use no_renegotiation to reject client initiated renegotiation
xuelei
parents: 18283
diff changeset
   332
        // warning alert (no_renegotiation must be a warning: RFC 2246).
9078dc28a187 8019359: To comment why not use no_renegotiation to reject client initiated renegotiation
xuelei
parents: 18283
diff changeset
   333
        // no_renegotiation might seem more natural at first, but warnings
9078dc28a187 8019359: To comment why not use no_renegotiation to reject client initiated renegotiation
xuelei
parents: 18283
diff changeset
   334
        // are not appropriate because the sending party does not know how
9078dc28a187 8019359: To comment why not use no_renegotiation to reject client initiated renegotiation
xuelei
parents: 18283
diff changeset
   335
        // the receiving party will behave.  This state must be treated as
9078dc28a187 8019359: To comment why not use no_renegotiation to reject client initiated renegotiation
xuelei
parents: 18283
diff changeset
   336
        // a fatal server condition.
9078dc28a187 8019359: To comment why not use no_renegotiation to reject client initiated renegotiation
xuelei
parents: 18283
diff changeset
   337
        //
9078dc28a187 8019359: To comment why not use no_renegotiation to reject client initiated renegotiation
xuelei
parents: 18283
diff changeset
   338
        // This will not have any impact on server initiated renegotiation.
18283
f842a42076b9 7188658: Add possibility to disable client initiated renegotiation
xuelei
parents: 17189
diff changeset
   339
        if (rejectClientInitiatedRenego && !isInitialHandshake &&
f842a42076b9 7188658: Add possibility to disable client initiated renegotiation
xuelei
parents: 17189
diff changeset
   340
                state != HandshakeMessage.ht_hello_request) {
f842a42076b9 7188658: Add possibility to disable client initiated renegotiation
xuelei
parents: 17189
diff changeset
   341
            fatalSE(Alerts.alert_handshake_failure,
f842a42076b9 7188658: Add possibility to disable client initiated renegotiation
xuelei
parents: 17189
diff changeset
   342
                "Client initiated renegotiation is not allowed");
f842a42076b9 7188658: Add possibility to disable client initiated renegotiation
xuelei
parents: 17189
diff changeset
   343
        }
f842a42076b9 7188658: Add possibility to disable client initiated renegotiation
xuelei
parents: 17189
diff changeset
   344
14194
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   345
        // check the server name indication if required
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   346
        ServerNameExtension clientHelloSNIExt = (ServerNameExtension)
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   347
                    mesg.extensions.get(ExtensionType.EXT_SERVER_NAME);
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   348
        if (!sniMatchers.isEmpty()) {
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   349
            // we do not reject client without SNI extension
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   350
            if (clientHelloSNIExt != null &&
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   351
                        !clientHelloSNIExt.isMatched(sniMatchers)) {
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   352
                fatalSE(Alerts.alert_unrecognized_name,
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   353
                    "Unrecognized server name indication");
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   354
            }
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   355
        }
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   356
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   357
        // Does the message include security renegotiation indication?
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   358
        boolean renegotiationIndicated = false;
5182
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   359
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   360
        // check the TLS_EMPTY_RENEGOTIATION_INFO_SCSV
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   361
        CipherSuiteList cipherSuites = mesg.getCipherSuites();
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   362
        if (cipherSuites.contains(CipherSuite.C_SCSV)) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   363
            renegotiationIndicated = true;
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   364
            if (isInitialHandshake) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   365
                secureRenegotiation = true;
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   366
            } else {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   367
                // abort the handshake with a fatal handshake_failure alert
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   368
                if (secureRenegotiation) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   369
                    fatalSE(Alerts.alert_handshake_failure,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   370
                        "The SCSV is present in a secure renegotiation");
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   371
                } else {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   372
                    fatalSE(Alerts.alert_handshake_failure,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   373
                        "The SCSV is present in a insecure renegotiation");
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   374
                }
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   375
            }
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   376
        }
5182
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   377
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   378
        // check the "renegotiation_info" extension
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   379
        RenegotiationInfoExtension clientHelloRI = (RenegotiationInfoExtension)
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   380
                    mesg.extensions.get(ExtensionType.EXT_RENEGOTIATION_INFO);
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   381
        if (clientHelloRI != null) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   382
            renegotiationIndicated = true;
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   383
            if (isInitialHandshake) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   384
                // verify the length of the "renegotiated_connection" field
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   385
                if (!clientHelloRI.isEmpty()) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   386
                    // abort the handshake with a fatal handshake_failure alert
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   387
                    fatalSE(Alerts.alert_handshake_failure,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   388
                        "The renegotiation_info field is not empty");
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   389
                }
5182
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   390
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   391
                secureRenegotiation = true;
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   392
            } else {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   393
                if (!secureRenegotiation) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   394
                    // unexpected RI extension for insecure renegotiation,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   395
                    // abort the handshake with a fatal handshake_failure alert
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   396
                    fatalSE(Alerts.alert_handshake_failure,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   397
                        "The renegotiation_info is present in a insecure " +
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   398
                        "renegotiation");
5182
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   399
                }
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   400
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   401
                // verify the client_verify_data value
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   402
                if (!Arrays.equals(clientVerifyData,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   403
                                clientHelloRI.getRenegotiatedConnection())) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   404
                    fatalSE(Alerts.alert_handshake_failure,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   405
                        "Incorrect verify data in ClientHello " +
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   406
                        "renegotiation_info message");
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   407
                }
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   408
            }
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   409
        } else if (!isInitialHandshake && secureRenegotiation) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   410
           // if the connection's "secure_renegotiation" flag is set to TRUE
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   411
           // and the "renegotiation_info" extension is not present, abort
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   412
           // the handshake.
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   413
            fatalSE(Alerts.alert_handshake_failure,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   414
                        "Inconsistent secure renegotiation indication");
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   415
        }
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   416
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   417
        // if there is no security renegotiation indication or the previous
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   418
        // handshake is insecure.
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   419
        if (!renegotiationIndicated || !secureRenegotiation) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   420
            if (isInitialHandshake) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   421
                if (!allowLegacyHelloMessages) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   422
                    // abort the handshake with a fatal handshake_failure alert
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   423
                    fatalSE(Alerts.alert_handshake_failure,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   424
                        "Failed to negotiate the use of secure renegotiation");
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   425
                }
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   426
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   427
                // continue with legacy ClientHello
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   428
                if (debug != null && Debug.isOn("handshake")) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   429
                    System.out.println("Warning: No renegotiation " +
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   430
                        "indication in ClientHello, allow legacy ClientHello");
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   431
                }
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   432
            } else if (!allowUnsafeRenegotiation) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   433
                // abort the handshake
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   434
                if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) {
18283
f842a42076b9 7188658: Add possibility to disable client initiated renegotiation
xuelei
parents: 17189
diff changeset
   435
                    // respond with a no_renegotiation warning
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   436
                    warningSE(Alerts.alert_no_renegotiation);
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   437
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   438
                    // invalidate the handshake so that the caller can
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   439
                    // dispose this object.
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   440
                    invalidated = true;
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   441
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   442
                    // If there is still unread block in the handshake
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   443
                    // input stream, it would be truncated with the disposal
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   444
                    // and the next handshake message will become incomplete.
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   445
                    //
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   446
                    // However, according to SSL/TLS specifications, no more
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   447
                    // handshake message could immediately follow ClientHello
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   448
                    // or HelloRequest. But in case of any improper messages,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   449
                    // we'd better check to ensure there is no remaining bytes
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   450
                    // in the handshake input stream.
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   451
                    if (input.available() > 0) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   452
                        fatalSE(Alerts.alert_unexpected_message,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   453
                            "ClientHello followed by an unexpected  " +
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   454
                            "handshake message");
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   455
                    }
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   456
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   457
                    return;
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   458
                } else {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   459
                    // For SSLv3, send the handshake_failure fatal error.
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   460
                    // Note that SSLv3 does not define a no_renegotiation
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   461
                    // alert like TLSv1. However we cannot ignore the message
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   462
                    // simply, otherwise the other side was waiting for a
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   463
                    // response that would never come.
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   464
                    fatalSE(Alerts.alert_handshake_failure,
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   465
                        "Renegotiation is not allowed");
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   466
                }
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   467
            } else {   // !isInitialHandshake && allowUnsafeRenegotiation
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   468
                // continue with unsafe renegotiation.
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   469
                if (debug != null && Debug.isOn("handshake")) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   470
                    System.out.println(
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   471
                            "Warning: continue with insecure renegotiation");
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   472
                }
5182
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   473
            }
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   474
        }
62836694baeb 6898739: TLS renegotiation issue
xuelei
parents: 4236
diff changeset
   475
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
         * Always make sure this entire record has been digested before we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
         * start emitting output, to ensure correct digesting order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        input.digestNow();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
         * FIRST, construct the ServerHello using the options and priorities
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
         * from the ClientHello.  Update the (pending) cipher spec as we do
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
         * so, and save the client's version to protect against rollback
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
         * attacks.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
         * There are a bunch of minor tasks here, and one major one: deciding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
         * if the short or the full handshake sequence will be used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        ServerHello m1 = new ServerHello();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        clientRequestedVersion = mesg.protocolVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
   495
        // select a proper protocol version.
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
   496
        ProtocolVersion selectedVersion =
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
   497
               selectProtocolVersion(clientRequestedVersion);
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
   498
        if (selectedVersion == null ||
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
   499
                selectedVersion.v == ProtocolVersion.SSL20Hello.v) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            fatalSE(Alerts.alert_handshake_failure,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                "Client requested protocol " + clientRequestedVersion +
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
   502
                " not enabled or not supported");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        }
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   504
7804
c59149ba3780 6996367: improve HandshakeHash
weijun
parents: 7043
diff changeset
   505
        handshakeHash.protocolDetermined(selectedVersion);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        setVersion(selectedVersion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        m1.protocolVersion = protocolVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        // random ... save client and server values for later use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        // in computing the master secret (from pre-master secret)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        // and thence the other crypto keys.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        // NOTE:  this use of three inputs to generating _each_ set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        // of ciphers slows things down, but it does increase the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        // security since each connection in the session can hold
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        // its own authenticated (and strong) keys.  One could make
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        // creation of a session a rare thing...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        clnt_random = mesg.clnt_random;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
        svr_random = new RandomCookie(sslContext.getSecureRandom());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        m1.svr_random = svr_random;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        session = null; // forget about the current session
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        // Here we go down either of two paths:  (a) the fast one, where
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        // the client's asked to rejoin an existing session, and the server
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        // permits this; (b) the other one, where a new session is created.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        if (mesg.sessionId.length() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            // client is trying to resume a session, let's see...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
            SSLSessionImpl previous = ((SSLSessionContextImpl)sslContext
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                        .engineGetServerSessionContext())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                        .get(mesg.sessionId.getId());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            // Check if we can use the fast path, resuming a session.  We
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
            // can do so iff we have a valid record for that session, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            // the cipher suite for that session was on the list which the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            // client requested, and if we're not forgetting any needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            // authentication on the part of the client.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            if (previous != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                resumingSession = previous.isRejoinable();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                if (resumingSession) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                    ProtocolVersion oldVersion = previous.getProtocolVersion();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                    // cannot resume session with different version
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                    if (oldVersion != protocolVersion) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                        resumingSession = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
14194
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   555
                // cannot resume session with different server name indication
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   556
                if (resumingSession) {
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   557
                    List<SNIServerName> oldServerNames =
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   558
                            previous.getRequestedServerNames();
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   559
                    if (clientHelloSNIExt != null) {
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   560
                        if (!clientHelloSNIExt.isIdentical(oldServerNames)) {
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   561
                            resumingSession = false;
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   562
                        }
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   563
                    } else if (!oldServerNames.isEmpty()) {
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   564
                        resumingSession = false;
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   565
                    }
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   566
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   567
                    if (!resumingSession &&
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   568
                            debug != null && Debug.isOn("handshake")) {
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   569
                        System.out.println(
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   570
                            "The requested server name indication " +
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   571
                            "is not identical to the previous one");
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   572
                    }
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   573
                }
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   574
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                if (resumingSession &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                        (doClientAuth == SSLEngineImpl.clauth_required)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                    try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
                        previous.getPeerPrincipal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
                    } catch (SSLPeerUnverifiedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
                        resumingSession = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                // validate subject identity
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
                if (resumingSession) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                    CipherSuite suite = previous.getSuite();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                    if (suite.keyExchange == K_KRB5 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
                        suite.keyExchange == K_KRB5_EXPORT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
                        Principal localPrincipal = previous.getLocalPrincipal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
                        Subject subject = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                            subject = AccessController.doPrivileged(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                                new PrivilegedExceptionAction<Subject>() {
14664
e71aa0962e70 8003950: Adds missing Override annotations and removes unnecessary imports in sun.security.ssl
xuelei
parents: 14194
diff changeset
   595
                                @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
                                public Subject run() throws Exception {
4236
02f52c723b79 6894643: Separate out dependency on Kerberos
vinnie
parents: 2942
diff changeset
   597
                                    return
02f52c723b79 6894643: Separate out dependency on Kerberos
vinnie
parents: 2942
diff changeset
   598
                                        Krb5Helper.getServerSubject(getAccSE());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
                            }});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                        } catch (PrivilegedActionException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                            subject = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
                            if (debug != null && Debug.isOn("session")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
                                System.out.println("Attempt to obtain" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
                                                " subject failed!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                        if (subject != null) {
4236
02f52c723b79 6894643: Separate out dependency on Kerberos
vinnie
parents: 2942
diff changeset
   609
                            // Eliminate dependency on KerberosPrincipal
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
   610
                            if (Krb5Helper.isRelated(subject, localPrincipal)) {
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
   611
                                if (debug != null && Debug.isOn("session"))
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
   612
                                    System.out.println("Subject can" +
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
   613
                                            " provide creds for princ");
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
   614
                            } else {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
                                resumingSession = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
                                if (debug != null && Debug.isOn("session"))
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
   617
                                    System.out.println("Subject cannot" +
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
   618
                                            " provide creds for princ");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                            resumingSession = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                            if (debug != null && Debug.isOn("session"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
                                System.out.println("Kerberos credentials are" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                                    " not present in the current Subject;" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
                                    " check if " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                                    " javax.security.auth.useSubjectAsCreds" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                                    " system property has been set to false");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
                if (resumingSession) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                    CipherSuite suite = previous.getSuite();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                    // verify that the ciphersuite from the cached session
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
                    // is in the list of client requested ciphersuites and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
                    // we have it enabled
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   637
                    if ((isNegotiable(suite) == false) ||
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                            (mesg.getCipherSuites().contains(suite) == false)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
                        resumingSession = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
                        // everything looks ok, set the ciphersuite
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
                        // this should be done last when we are sure we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
                        // will resume
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
                        setCipherSuite(suite);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                if (resumingSession) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
                    session = previous;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
                    if (debug != null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                        (Debug.isOn("handshake") || Debug.isOn("session"))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                        System.out.println("%% Resuming " + session);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
        } // else client did not try to resume
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        // If client hasn't specified a session we can resume, start a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        // new one and choose its cipher suite and compression options.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
        // Unless new session creation is disabled for this connection!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        if (session == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            if (!enableNewSession) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
                throw new SSLException("Client did not resume a session");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
            }
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   667
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   668
            supportedCurves = (SupportedEllipticCurvesExtension)
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   669
                        mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES);
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   670
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   671
            // We only need to handle the "signature_algorithm" extension
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   672
            // for full handshakes and TLS 1.2 or later.
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   673
            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   674
                SignatureAlgorithmsExtension signAlgs =
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   675
                    (SignatureAlgorithmsExtension)mesg.extensions.get(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   676
                                    ExtensionType.EXT_SIGNATURE_ALGORITHMS);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   677
                if (signAlgs != null) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   678
                    Collection<SignatureAndHashAlgorithm> peerSignAlgs =
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   679
                                            signAlgs.getSignAlgorithms();
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   680
                    if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   681
                        throw new SSLHandshakeException(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   682
                            "No peer supported signature algorithms");
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   683
                    }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   684
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   685
                    Collection<SignatureAndHashAlgorithm>
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   686
                        supportedPeerSignAlgs =
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   687
                            SignatureAndHashAlgorithm.getSupportedAlgorithms(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   688
                                                            peerSignAlgs);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   689
                    if (supportedPeerSignAlgs.isEmpty()) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   690
                        throw new SSLHandshakeException(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   691
                            "No supported signature and hash algorithm " +
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   692
                            "in common");
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   693
                    }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   694
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   695
                    setPeerSupportedSignAlgs(supportedPeerSignAlgs);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   696
                } // else, need to use peer implicit supported signature algs
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   697
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   698
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   699
            session = new SSLSessionImpl(protocolVersion, CipherSuite.C_NULL,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   700
                        getLocalSupportedSignAlgs(),
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   701
                        sslContext.getSecureRandom(),
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   702
                        getHostAddressSE(), getPortSE());
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   703
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   704
            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   705
                if (peerSupportedSignAlgs != null) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   706
                    session.setPeerSupportedSignatureAlgorithms(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   707
                            peerSupportedSignAlgs);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   708
                }   // else, we will set the implicit peer supported signature
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   709
                    // algorithms in chooseCipherSuite()
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   710
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   711
14194
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   712
            // set the server name indication in the session
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   713
            List<SNIServerName> clientHelloSNI =
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   714
                    Collections.<SNIServerName>emptyList();
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   715
            if (clientHelloSNIExt != null) {
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   716
                clientHelloSNI = clientHelloSNIExt.getServerNames();
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   717
            }
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   718
            session.setRequestedServerNames(clientHelloSNI);
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   719
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   720
            // set the handshake session
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   721
            setHandshakeSessionSE(session);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   722
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   723
            // choose cipher suite and corresponding private key
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
            chooseCipherSuite(mesg);
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   725
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   726
            session.setSuite(cipherSuite);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
            session.setLocalPrivateKey(privateKey);
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   728
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            // chooseCompression(mesg);
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   730
        } else {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   731
            // set the handshake session
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   732
            setHandshakeSessionSE(session);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   733
        }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   734
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   735
        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   736
            handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        m1.cipherSuite = cipherSuite;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        m1.sessionId = session.getSessionId();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        m1.compression_method = session.getCompression();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   743
        if (secureRenegotiation) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   744
            // For ServerHellos that are initial handshakes, then the
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   745
            // "renegotiated_connection" field in "renegotiation_info"
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   746
            // extension is of zero length.
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   747
            //
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   748
            // For ServerHellos that are renegotiating, this field contains
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   749
            // the concatenation of client_verify_data and server_verify_data.
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   750
            //
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   751
            // Note that for initial handshakes, both the clientVerifyData
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   752
            // variable and serverVerifyData variable are of zero length.
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   753
            HelloExtension serverHelloRI = new RenegotiationInfoExtension(
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   754
                                        clientVerifyData, serverVerifyData);
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   755
            m1.extensions.add(serverHelloRI);
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   756
        }
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   757
14194
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   758
        if (!sniMatchers.isEmpty() && clientHelloSNIExt != null) {
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   759
            // When resuming a session, the server MUST NOT include a
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   760
            // server_name extension in the server hello.
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   761
            if (!resumingSession) {
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   762
                ServerNameExtension serverHelloSNI = new ServerNameExtension();
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   763
                m1.extensions.add(serverHelloSNI);
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   764
            }
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   765
        }
971f46db533d 7068321: Support TLS Server Name Indication (SNI) Extension in JSSE Server
xuelei
parents: 12874
diff changeset
   766
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
        if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
            m1.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
            System.out.println("Cipher suite:  " + session.getSuite());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
        m1.write(output);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
        // If we are resuming a session, we finish writing handshake
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
        // messages right now and then finish.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
        if (resumingSession) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
            calculateConnectionKeys(session.getMasterSecret());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
            sendChangeCipherAndFinish(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
         * SECOND, write the server Certificate(s) if we need to.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
         * NOTE:  while an "anonymous RSA" mode is explicitly allowed by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
         * the protocol, we can't support it since all of the SSL flavors
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
         * defined in the protocol spec are explicitly stated to require
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
         * using RSA certificates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
        if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
            // Server certificates are omitted for Kerberos ciphers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        } else if ((keyExchange != K_DH_ANON) && (keyExchange != K_ECDH_ANON)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
            if (certs == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
                throw new RuntimeException("no certificates");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
            CertificateMsg m2 = new CertificateMsg(certs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
             * Set local certs in the SSLSession, output
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
             * debug info, and then actually write to the client.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
            session.setLocalCertificates(certs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
            if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
                m2.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            m2.write(output);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
            // XXX has some side effects with OS TCP buffering,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
            // leave it out for now
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
            // let client verify chain in the meantime...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
            // output.flush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
            if (certs != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
                throw new RuntimeException("anonymous keyexchange with certs");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
         * THIRD, the ServerKeyExchange message ... iff it's needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
         * It's usually needed unless there's an encryption-capable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
         * RSA cert, or a D-H cert.  The notable exception is that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
         * exportable ciphers used with big RSA keys need to downgrade
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
         * to use short RSA keys, even when the key/cert encrypts OK.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
        ServerKeyExchange m3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
        switch (keyExchange) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        case K_RSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        case K_KRB5:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
        case K_KRB5_EXPORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
            // no server key exchange for RSA or KRB5 ciphersuites
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
            m3 = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
        case K_RSA_EXPORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
            if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                    m3 = new RSA_ServerKeyExchange(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
                        tempPublicKey, privateKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
                        clnt_random, svr_random,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
                        sslContext.getSecureRandom());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
                    privateKey = tempPrivateKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
                } catch (GeneralSecurityException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
                    throwSSLException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
                        ("Error generating RSA server key exchange", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
                    m3 = null; // make compiler happy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
                // RSA_EXPORT with short key, don't need ServerKeyExchange
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
                m3 = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
        case K_DHE_RSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
        case K_DHE_DSS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                m3 = new DH_ServerKeyExchange(dh,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                    privateKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    clnt_random.random_bytes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                    svr_random.random_bytes,
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   865
                    sslContext.getSecureRandom(),
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   866
                    preferableSignatureAlgorithm,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   867
                    protocolVersion);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
            } catch (GeneralSecurityException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
                throwSSLException("Error generating DH server key exchange", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
                m3 = null; // make compiler happy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
        case K_DH_ANON:
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   874
            m3 = new DH_ServerKeyExchange(dh, protocolVersion);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
        case K_ECDHE_RSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
        case K_ECDHE_ECDSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
        case K_ECDH_ANON:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
                m3 = new ECDH_ServerKeyExchange(ecdh,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                    privateKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
                    clnt_random.random_bytes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
                    svr_random.random_bytes,
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   884
                    sslContext.getSecureRandom(),
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   885
                    preferableSignatureAlgorithm,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   886
                    protocolVersion);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
            } catch (GeneralSecurityException e) {
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   888
                throwSSLException(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   889
                    "Error generating ECDH server key exchange", e);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
                m3 = null; // make compiler happy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
        case K_ECDH_RSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
        case K_ECDH_ECDSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
            // ServerKeyExchange not used for fixed ECDH
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
            m3 = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
            throw new RuntimeException("internal error: " + keyExchange);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
        if (m3 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
            if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
                m3.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
            m3.write(output);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
        // FOURTH, the CertificateRequest message.  The details of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
        // the message can be affected by the key exchange algorithm
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
        // in use.  For example, certs with fixed Diffie-Hellman keys
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
        // are only useful with the DH_DSS and DH_RSA key exchange
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
        // algorithms.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
        // Needed only if server requires client to authenticate self.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
        // Illegal for anonymous flavors, so we need to check that.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
        //
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   918
        // CertificateRequest is omitted for Kerberos ciphers
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   919
        if (doClientAuth != SSLEngineImpl.clauth_none &&
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   920
                keyExchange != K_DH_ANON && keyExchange != K_ECDH_ANON &&
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   921
                keyExchange != K_KRB5 && keyExchange != K_KRB5_EXPORT) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
            CertificateRequest m4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
            X509Certificate caCerts[];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   926
            Collection<SignatureAndHashAlgorithm> localSignAlgs = null;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   927
            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   928
                // We currently use all local upported signature and hash
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   929
                // algorithms. However, to minimize the computation cost
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   930
                // of requested hash algorithms, we may use a restricted
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   931
                // set of signature algorithms in the future.
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   932
                localSignAlgs = getLocalSupportedSignAlgs();
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   933
                if (localSignAlgs.isEmpty()) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   934
                    throw new SSLHandshakeException(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   935
                            "No supported signature algorithm");
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   936
                }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   937
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   938
                Set<String> localHashAlgs =
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   939
                    SignatureAndHashAlgorithm.getHashAlgorithmNames(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   940
                        localSignAlgs);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   941
                if (localHashAlgs.isEmpty()) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   942
                    throw new SSLHandshakeException(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   943
                            "No supported signature algorithm");
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   944
                }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   945
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   946
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
            caCerts = sslContext.getX509TrustManager().getAcceptedIssuers();
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   948
            m4 = new CertificateRequest(caCerts, keyExchange,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
   949
                                            localSignAlgs, protocolVersion);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
            if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
                m4.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
            m4.write(output);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
         * FIFTH, say ServerHelloDone.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
        ServerHelloDone m5 = new ServerHelloDone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
        if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
            m5.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
        m5.write(output);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
         * Flush any buffered messages so the client will see them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
         * Ideally, all the messages above go in a single network level
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
         * message to the client.  Without big Certificate chains, it's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
         * going to be the common case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
        output.flush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
     * Choose cipher suite from among those supported by client. Sets
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
     * the cipherSuite and keyExchange variables.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
    private void chooseCipherSuite(ClientHello mesg) throws IOException {
19823
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
   981
        CipherSuiteList prefered;
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
   982
        CipherSuiteList proposed;
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
   983
        if (preferLocalCipherSuites) {
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
   984
            prefered = getActiveCipherSuites();
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
   985
            proposed = mesg.getCipherSuites();
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
   986
        } else {
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
   987
            prefered = mesg.getCipherSuites();
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
   988
            proposed = getActiveCipherSuites();
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
   989
        }
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
   990
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
   991
        for (CipherSuite suite : prefered.collection()) {
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
   992
            if (isNegotiable(proposed, suite) == false) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
            }
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   995
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
            if (doClientAuth == SSLEngineImpl.clauth_required) {
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   997
                if ((suite.keyExchange == K_DH_ANON) ||
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
   998
                    (suite.keyExchange == K_ECDH_ANON)) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
            if (trySetCipherSuite(suite) == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
        }
19823
f0fd09e20528 7188657: There should be a way to reorder the JSSE ciphers
xuelei
parents: 18570
diff changeset
  1007
        fatalSE(Alerts.alert_handshake_failure, "no cipher suites in common");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
     * Set the given CipherSuite, if possible. Return the result.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
     * The call succeeds if the CipherSuite is available and we have
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
     * the necessary certificates to complete the handshake. We don't
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
     * check if the CipherSuite is actually enabled.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
     * If successful, this method also generates ephemeral keys if
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
     * required for this ciphersuite. This may take some time, so this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
     * method should only be called if you really want to use the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
     * CipherSuite.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
     *
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
  1021
     * This method is called from chooseCipherSuite() in this class.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
    boolean trySetCipherSuite(CipherSuite suite) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
         * If we're resuming a session we know we can
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
         * support this key exchange algorithm and in fact
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
         * have already cached the result of it in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
         * the session state.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
        if (resumingSession) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1034
        if (suite.isNegotiable() == false) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1038
        // must not negotiate the obsoleted weak cipher suites.
7039
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
  1039
        if (protocolVersion.v >= suite.obsoleted) {
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
  1040
            return false;
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
  1041
        }
6464c8e62a18 4873188: Support TLS 1.1
xuelei
parents: 6856
diff changeset
  1042
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1043
        // must not negotiate unsupported cipher suites.
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1044
        if (protocolVersion.v < suite.supported) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1045
            return false;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1046
        }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1047
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
        KeyExchange keyExchange = suite.keyExchange;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
        // null out any existing references
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
        privateKey = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
        certs = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
        dh = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
        tempPrivateKey = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
        tempPublicKey = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1057
        Collection<SignatureAndHashAlgorithm> supportedSignAlgs = null;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1058
        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1059
            if (peerSupportedSignAlgs != null) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1060
                supportedSignAlgs = peerSupportedSignAlgs;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1061
            } else {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1062
                SignatureAndHashAlgorithm algorithm = null;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1063
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1064
                // we may optimize the performance
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1065
                switch (keyExchange) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1066
                    // If the negotiated key exchange algorithm is one of
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1067
                    // (RSA, DHE_RSA, DH_RSA, RSA_PSK, ECDH_RSA, ECDHE_RSA),
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1068
                    // behave as if client had sent the value {sha1,rsa}.
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1069
                    case K_RSA:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1070
                    case K_DHE_RSA:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1071
                    case K_DH_RSA:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1072
                    // case K_RSA_PSK:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1073
                    case K_ECDH_RSA:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1074
                    case K_ECDHE_RSA:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1075
                        algorithm = SignatureAndHashAlgorithm.valueOf(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1076
                                HashAlgorithm.SHA1.value,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1077
                                SignatureAlgorithm.RSA.value, 0);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1078
                        break;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1079
                    // If the negotiated key exchange algorithm is one of
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1080
                    // (DHE_DSS, DH_DSS), behave as if the client had
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1081
                    // sent the value {sha1,dsa}.
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1082
                    case K_DHE_DSS:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1083
                    case K_DH_DSS:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1084
                        algorithm = SignatureAndHashAlgorithm.valueOf(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1085
                                HashAlgorithm.SHA1.value,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1086
                                SignatureAlgorithm.DSA.value, 0);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1087
                        break;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1088
                    // If the negotiated key exchange algorithm is one of
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1089
                    // (ECDH_ECDSA, ECDHE_ECDSA), behave as if the client
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1090
                    // had sent value {sha1,ecdsa}.
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1091
                    case K_ECDH_ECDSA:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1092
                    case K_ECDHE_ECDSA:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1093
                        algorithm = SignatureAndHashAlgorithm.valueOf(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1094
                                HashAlgorithm.SHA1.value,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1095
                                SignatureAlgorithm.ECDSA.value, 0);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1096
                        break;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1097
                    default:
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1098
                        // no peer supported signature algorithms
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1099
                }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1100
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1101
                if (algorithm == null) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1102
                    supportedSignAlgs =
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1103
                        Collections.<SignatureAndHashAlgorithm>emptySet();
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1104
                } else {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1105
                    supportedSignAlgs =
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1106
                        new ArrayList<SignatureAndHashAlgorithm>(1);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1107
                    supportedSignAlgs.add(algorithm);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1108
                }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1109
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1110
                // Sets the peer supported signature algorithm to use in KM
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1111
                // temporarily.
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1112
                session.setPeerSupportedSignatureAlgorithms(supportedSignAlgs);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1113
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1114
        }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1115
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
        switch (keyExchange) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
        case K_RSA:
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1118
            // need RSA certs for authentication
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1119
            if (setupPrivateKeyAndChain("RSA") == false) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1120
                return false;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1121
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1122
            break;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
        case K_RSA_EXPORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
            // need RSA certs for authentication
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
            if (setupPrivateKeyAndChain("RSA") == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1129
            try {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1130
               if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1131
                    if (!setupEphemeralRSAKeys(suite.exportable)) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1132
                        return false;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1133
                    }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1134
               }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1135
            } catch (RuntimeException e) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1136
                // could not determine keylength, ignore key
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1137
                return false;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1138
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1139
            break;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1140
        case K_DHE_RSA:
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9499
diff changeset
  1141
            // need RSA certs for authentication
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9499
diff changeset
  1142
            if (setupPrivateKeyAndChain("RSA") == false) {
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9499
diff changeset
  1143
                return false;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9499
diff changeset
  1144
            }
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9499
diff changeset
  1145
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1146
            // get preferable peer signature algorithm for server key exchange
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1147
            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1148
                preferableSignatureAlgorithm =
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1149
                    SignatureAndHashAlgorithm.getPreferableAlgorithm(
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9499
diff changeset
  1150
                                        supportedSignAlgs, "RSA", privateKey);
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1151
                if (preferableSignatureAlgorithm == null) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
                }
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1154
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1155
20539
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1156
            setupEphemeralDHKeys(suite.exportable, privateKey);
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9499
diff changeset
  1157
            break;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9499
diff changeset
  1158
        case K_ECDHE_RSA:
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1159
            // need RSA certs for authentication
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1160
            if (setupPrivateKeyAndChain("RSA") == false) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1161
                return false;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1162
            }
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9499
diff changeset
  1163
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1164
            // get preferable peer signature algorithm for server key exchange
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1165
            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1166
                preferableSignatureAlgorithm =
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1167
                    SignatureAndHashAlgorithm.getPreferableAlgorithm(
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9499
diff changeset
  1168
                                        supportedSignAlgs, "RSA", privateKey);
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1169
                if (preferableSignatureAlgorithm == null) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
                }
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1172
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1173
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1174
            if (setupEphemeralECDHKeys() == false) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1175
                return false;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1176
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
        case K_DHE_DSS:
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1179
            // get preferable peer signature algorithm for server key exchange
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1180
            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1181
                preferableSignatureAlgorithm =
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1182
                    SignatureAndHashAlgorithm.getPreferableAlgorithm(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1183
                                                supportedSignAlgs, "DSA");
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1184
                if (preferableSignatureAlgorithm == null) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1185
                    return false;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1186
                }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1187
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1188
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
            // need DSS certs for authentication
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
            if (setupPrivateKeyAndChain("DSA") == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
            }
20539
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1193
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1194
            setupEphemeralDHKeys(suite.exportable, privateKey);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
        case K_ECDHE_ECDSA:
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1197
            // get preferable peer signature algorithm for server key exchange
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1198
            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1199
                preferableSignatureAlgorithm =
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1200
                    SignatureAndHashAlgorithm.getPreferableAlgorithm(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1201
                                            supportedSignAlgs, "ECDSA");
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1202
                if (preferableSignatureAlgorithm == null) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1203
                    return false;
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1204
                }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1205
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1206
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
            // need EC cert signed using EC
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
            if (setupPrivateKeyAndChain("EC_EC") == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
            if (setupEphemeralECDHKeys() == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
        case K_ECDH_RSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
            // need EC cert signed using RSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
            if (setupPrivateKeyAndChain("EC_RSA") == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
            setupStaticECDHKeys();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
        case K_ECDH_ECDSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
            // need EC cert signed using EC
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
            if (setupPrivateKeyAndChain("EC_EC") == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
            setupStaticECDHKeys();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
        case K_KRB5:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
        case K_KRB5_EXPORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
            // need Kerberos Key
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
            if (!setupKerberosKeys()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
        case K_DH_ANON:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
            // no certs needed for anonymous
20539
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1238
            setupEphemeralDHKeys(suite.exportable, null);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
        case K_ECDH_ANON:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
            // no certs needed for anonymous
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
            if (setupEphemeralECDHKeys() == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
            // internal error, unknown key exchange
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
            throw new RuntimeException("Unrecognized cipherSuite: " + suite);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
        setCipherSuite(suite);
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1251
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1252
        // set the peer implicit supported signature algorithms
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1253
        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1254
            if (peerSupportedSignAlgs == null) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1255
                setPeerSupportedSignAlgs(supportedSignAlgs);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1256
                // we had alreay update the session
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1257
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1258
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
     * Get some "ephemeral" RSA keys for this context. This means
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
     * generating them if it's not already been done.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
     * Note that we currently do not implement any ciphersuites that use
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
     * strong ephemeral RSA. (We do not support the EXPORT1024 ciphersuites
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
     * and standard RSA ciphersuites prohibit ephemeral mode for some reason)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
     * This means that export is always true and 512 bit keys are generated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
    private boolean setupEphemeralRSAKeys(boolean export) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
        KeyPair kp = sslContext.getEphemeralKeyManager().
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
                        getRSAKeyPair(export, sslContext.getSecureRandom());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
        if (kp == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
            tempPublicKey = kp.getPublic();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
            tempPrivateKey = kp.getPrivate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
     * Acquire some "ephemeral" Diffie-Hellman  keys for this handshake.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
     * We don't reuse these, for improved forward secrecy.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
     */
20539
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1287
    private void setupEphemeralDHKeys(boolean export, Key key) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
        /*
20539
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1289
         * 768 bits ephemeral DH private keys were used to be used in
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1290
         * ServerKeyExchange except that exportable ciphers max out at 512
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1291
         * bits modulus values. We still adhere to this behavior in legacy
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1292
         * mode (system property "jdk.tls.ephemeralDHKeySize" is defined
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1293
         * as "legacy").
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1294
         *
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1295
         * Old JDK (JDK 7 and previous) releases don't support DH keys bigger
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1296
         * than 1024 bits. We have to consider the compatibility requirement.
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1297
         * 1024 bits DH key is always used for non-exportable cipher suites
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1298
         * in default mode (system property "jdk.tls.ephemeralDHKeySize"
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1299
         * is not defined).
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1300
         *
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1301
         * However, if applications want more stronger strength, setting
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1302
         * system property "jdk.tls.ephemeralDHKeySize" to "matched"
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1303
         * is a workaround to use ephemeral DH key which size matches the
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1304
         * corresponding authentication key. For example, if the public key
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1305
         * size of an authentication certificate is 2048 bits, then the
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1306
         * ephemeral DH key size should be 2048 bits accordingly unless
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1307
         * the cipher suite is exportable.  This key sizing scheme keeps
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1308
         * the cryptographic strength consistent between authentication
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1309
         * keys and key-exchange keys.
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1310
         *
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1311
         * Applications may also want to customize the ephemeral DH key size
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1312
         * to a fixed length for non-exportable cipher suites. This can be
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1313
         * approached by setting system property "jdk.tls.ephemeralDHKeySize"
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1314
         * to a valid positive integer between 1024 and 2048 bits, inclusive.
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1315
         *
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1316
         * Note that the minimum acceptable key size is 1024 bits except
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1317
         * exportable cipher suites or legacy mode.
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1318
         *
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1319
         * Note that the maximum acceptable key size is 2048 bits because
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1320
         * DH keys bigger than 2048 are not always supported by underlying
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1321
         * JCE providers.
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1322
         *
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1323
         * Note that per RFC 2246, the key size limit of DH is 512 bits for
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1324
         * exportable cipher suites.  Because of the weakness, exportable
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1325
         * cipher suites are deprecated since TLS v1.1 and they are not
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1326
         * enabled by default in Oracle provider. The legacy behavior is
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1327
         * reserved and 512 bits DH key is always used for exportable
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1328
         * cipher suites.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
         */
20539
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1330
        int keySize = export ? 512 : 1024;           // default mode
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1331
        if (!export) {
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1332
            if (useLegacyEphemeralDHKeys) {          // legacy mode
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1333
                keySize = 768;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1334
            } else if (useSmartEphemeralDHKeys) {    // matched mode
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1335
                if (key != null) {
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1336
                    int ks = KeyUtil.getKeySize(key);
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1337
                    // Note that SunJCE provider only supports 2048 bits DH
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1338
                    // keys bigger than 1024.  Please DON'T use value other
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1339
                    // than 1024 and 2048 at present.  We may improve the
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1340
                    // underlying providers and key size here in the future.
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1341
                    //
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1342
                    // keySize = ks <= 1024 ? 1024 : (ks >= 2048 ? 2048 : ks);
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1343
                    keySize = ks <= 1024 ? 1024 : 2048;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1344
                } // Otherwise, anonymous cipher suites, 1024-bit is used.
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1345
            } else if (customizedDHKeySize > 0) {    // customized mode
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1346
                keySize = customizedDHKeySize;
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1347
            }
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1348
        }
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1349
cbff16f695c6 6956398: make ephemeral DH key match the length of the certificate key
xuelei
parents: 19823
diff changeset
  1350
        dh = new DHCrypt(keySize, sslContext.getSecureRandom());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
    // Setup the ephemeral ECDH parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
    // If we cannot continue because we do not support any of the curves that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
    // the client requested, return false. Otherwise (all is well), return true.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
    private boolean setupEphemeralECDHKeys() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
        int index = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
        if (supportedCurves != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
            // if the client sent the supported curves extension, pick the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
            // first one that we support;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
            for (int curveId : supportedCurves.curveIds()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
                if (SupportedEllipticCurvesExtension.isSupported(curveId)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
                    index = curveId;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
            if (index < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
                // no match found, cannot use this ciphersuite
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
            // pick our preference
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
            index = SupportedEllipticCurvesExtension.DEFAULT.curveIds()[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
        String oid = SupportedEllipticCurvesExtension.getCurveOid(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
        ecdh = new ECDHCrypt(oid, sslContext.getSecureRandom());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
    private void setupStaticECDHKeys() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
        // don't need to check whether the curve is supported, already done
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
        // in setupPrivateKeyAndChain().
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
        ecdh = new ECDHCrypt(privateKey, certs[0].getPublicKey());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
     * Retrieve the server key and certificate for the specified algorithm
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
     * from the KeyManager and set the instance variables.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
     * @return true if successful, false if not available or invalid
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
    private boolean setupPrivateKeyAndChain(String algorithm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
        X509ExtendedKeyManager km = sslContext.getX509KeyManager();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
        String alias;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
        if (conn != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
            alias = km.chooseServerAlias(algorithm, null, conn);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
            alias = km.chooseEngineServerAlias(algorithm, null, engine);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
        if (alias == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
        PrivateKey tempPrivateKey = km.getPrivateKey(alias);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
        if (tempPrivateKey == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
        X509Certificate[] tempCerts = km.getCertificateChain(alias);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
        if ((tempCerts == null) || (tempCerts.length == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
        String keyAlgorithm = algorithm.split("_")[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
        PublicKey publicKey = tempCerts[0].getPublicKey();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
        if ((tempPrivateKey.getAlgorithm().equals(keyAlgorithm) == false)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
                || (publicKey.getAlgorithm().equals(keyAlgorithm) == false)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
        // For ECC certs, check whether we support the EC domain parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
        // If the client sent a SupportedEllipticCurves ClientHello extension,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
        // check against that too.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
        if (keyAlgorithm.equals("EC")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
            if (publicKey instanceof ECPublicKey == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
            ECParameterSpec params = ((ECPublicKey)publicKey).getParams();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
            int index = SupportedEllipticCurvesExtension.getCurveIndex(params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
            if (SupportedEllipticCurvesExtension.isSupported(index) == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
            if ((supportedCurves != null) && !supportedCurves.contains(index)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
        this.privateKey = tempPrivateKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
        this.certs = tempCerts;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
     * Retrieve the Kerberos key for the specified server principal
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
     * from the JAAS configuration file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
     * @return true if successful, false if not available or invalid
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
    private boolean setupKerberosKeys() {
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1445
        if (serviceCreds != null) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
            final AccessControlContext acc = getAccSE();
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1450
            serviceCreds = AccessController.doPrivileged(
4236
02f52c723b79 6894643: Separate out dependency on Kerberos
vinnie
parents: 2942
diff changeset
  1451
                // Eliminate dependency on KerberosKey
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1452
                new PrivilegedExceptionAction<Object>() {
14664
e71aa0962e70 8003950: Adds missing Override annotations and removes unnecessary imports in sun.security.ssl
xuelei
parents: 14194
diff changeset
  1453
                @Override
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1454
                public Object run() throws Exception {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
                    // get kerberos key for the default principal
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1456
                    return Krb5Helper.getServiceCreds(acc);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
                        }});
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
            // check permission to access and use the secret key of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
            // Kerberized "host" service
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1461
            if (serviceCreds != null) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
                if (debug != null && Debug.isOn("handshake")) {
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1463
                    System.out.println("Using Kerberos creds");
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1464
                }
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1465
                String serverPrincipal =
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1466
                        Krb5Helper.getServerPrincipalName(serviceCreds);
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1467
                if (serverPrincipal != null) {
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1468
                    // When service is bound, we check ASAP. Otherwise,
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1469
                    // will check after client request is received
28059
e576535359cc 8067377: My hobby: caning, then then canning, the the can-can
martin
parents: 25859
diff changeset
  1470
                    // in Kerberos ClientKeyExchange
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1471
                    SecurityManager sm = System.getSecurityManager();
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1472
                    try {
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1473
                        if (sm != null) {
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1474
                            // Eliminate dependency on ServicePermission
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1475
                            sm.checkPermission(Krb5Helper.getServicePermission(
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1476
                                    serverPrincipal, "accept"), acc);
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1477
                        }
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1478
                    } catch (SecurityException se) {
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1479
                        serviceCreds = null;
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1480
                        // Do not destroy keys. Will affect Subject
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1481
                        if (debug != null && Debug.isOn("handshake")) {
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1482
                            System.out.println("Permission to access Kerberos"
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1483
                                    + " secret key denied");
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1484
                        }
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1485
                        return false;
9499
f3115698a012 6894072: always refresh keytab
weijun
parents: 7804
diff changeset
  1486
                    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
            }
17189
9f2ae085280b 8005523: Unbound krb5 for TLS
weijun
parents: 16100
diff changeset
  1489
            return serviceCreds != null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
        } catch (PrivilegedActionException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
            // Likely exception here is LoginExceptin
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
            if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
                System.out.println("Attempt to obtain Kerberos key failed: "
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
                                + e.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
     * For Kerberos ciphers, the premaster secret is encrypted using
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
     * the session key. See RFC 2712.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
    private SecretKey clientKeyExchange(KerberosClientKeyExchange mesg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
        throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
        if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
            mesg.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
        // Record the principals involved in exchange
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
        session.setPeerPrincipal(mesg.getPeerPrincipal());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
        session.setLocalPrincipal(mesg.getLocalPrincipal());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
4236
02f52c723b79 6894643: Separate out dependency on Kerberos
vinnie
parents: 2942
diff changeset
  1515
        byte[] b = mesg.getUnencryptedPreMasterSecret();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
        return new SecretKeySpec(b, "TlsPremasterSecret");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
     * Diffie Hellman key exchange is used when the server presented
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
     * D-H parameters in its certificate (signed using RSA or DSS/DSA),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
     * or else the server presented no certificate but sent D-H params
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
     * in a ServerKeyExchange message.  Use of D-H is specified by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
     * cipher suite chosen.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
     * The message optionally contains the client's D-H public key (if
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
     * it wasn't not sent in a client certificate).  As always with D-H,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
     * if a client and a server have each other's D-H public keys and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
     * they use common algorithm parameters, they have a shared key
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
     * that's derived via the D-H calculation.  That key becomes the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
     * pre-master secret.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
    private SecretKey clientKeyExchange(DHClientKeyExchange mesg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
        if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
            mesg.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
        }
16080
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 16071
diff changeset
  1539
        return dh.getAgreedSecret(mesg.getClientPublicKey(), false);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
    private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
        if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
            mesg.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
        return ecdh.getAgreedSecret(mesg.getEncodedPoint());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1552
     * Client wrote a message to verify the certificate it sent earlier.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
     * Note that this certificate isn't involved in key exchange.  Client
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
     * authentication messages are included in the checksums used to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
     * validate the handshake (e.g. Finished messages).  Other than that,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
     * the _exact_ identity of the client is less fundamental to protocol
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
     * security than its role in selecting keys via the pre-master secret.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
    private void clientCertificateVerify(CertificateVerify mesg)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
        if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
            mesg.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1565
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1566
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1567
        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1568
            SignatureAndHashAlgorithm signAlg =
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1569
                mesg.getPreferableSignatureAlgorithm();
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1570
            if (signAlg == null) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1571
                throw new SSLHandshakeException(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1572
                        "Illegal CertificateVerify message");
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1573
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1574
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1575
            String hashAlg =
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1576
                SignatureAndHashAlgorithm.getHashAlgorithmName(signAlg);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1577
            if (hashAlg == null || hashAlg.length() == 0) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1578
                throw new SSLHandshakeException(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1579
                        "No supported hash algorithm");
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1580
            }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1581
        }
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1582
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1583
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1584
            PublicKey publicKey =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1585
                session.getPeerCertificates()[0].getPublicKey();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1586
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1587
            boolean valid = mesg.verify(protocolVersion, handshakeHash,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1588
                                        publicKey, session.getMasterSecret());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1589
            if (valid == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1590
                fatalSE(Alerts.alert_bad_certificate,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1591
                            "certificate verify message signature error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1592
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1593
        } catch (GeneralSecurityException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1594
            fatalSE(Alerts.alert_bad_certificate,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1595
                "certificate verify format error", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1596
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1597
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1598
        // reset the flag for clientCertificateVerify message
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1599
        needClientVerify = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1600
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1601
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1602
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1603
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1604
     * Client writes "finished" at the end of its handshake, after cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1605
     * spec is changed.   We verify it and then send ours.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1606
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1607
     * When we're resuming a session, we'll have already sent our own
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1608
     * Finished message so just the verification is needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1609
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1610
    private void clientFinished(Finished mesg) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1611
        if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1612
            mesg.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1613
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1614
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1615
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1616
         * Verify if client did send the certificate when client
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1617
         * authentication was required, otherwise server should not proceed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1618
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1619
        if (doClientAuth == SSLEngineImpl.clauth_required) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1620
           // get X500Principal of the end-entity certificate for X509-based
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1621
           // ciphersuites, or Kerberos principal for Kerberos ciphersuites
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1622
           session.getPeerPrincipal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1623
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1624
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1625
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
         * Verify if client did send clientCertificateVerify message following
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
         * the client Certificate, otherwise server should not proceed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1628
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1629
        if (needClientVerify) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
                fatalSE(Alerts.alert_handshake_failure,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
                        "client did not send certificate verify message");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1634
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1635
         * Verify the client's message with the "before" digest of messages,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1636
         * and forget about continuing to use that digest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1637
         */
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1638
        boolean verified = mesg.verify(handshakeHash, Finished.CLIENT,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1639
            session.getMasterSecret());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1640
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1641
        if (!verified) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1642
            fatalSE(Alerts.alert_handshake_failure,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1643
                        "client 'finished' message doesn't verify");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
            // NOTREACHED
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1647
        /*
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1648
         * save client verify data for secure renegotiation
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1649
         */
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1650
        if (secureRenegotiation) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1651
            clientVerifyData = mesg.getVerifyData();
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1652
        }
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1653
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1654
        /*
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1655
         * OK, it verified.  If we're doing the full handshake, add that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1656
         * "Finished" message to the hash of handshake messages, then send
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1657
         * the change_cipher_spec and Finished message.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1658
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1659
        if (!resumingSession) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1660
            input.digestNow();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
            sendChangeCipherAndFinish(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1662
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1663
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1664
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1665
         * Update the session cache only after the handshake completed, else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1666
         * we're open to an attack against a partially completed handshake.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1667
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1668
        session.setLastAccessedTime(System.currentTimeMillis());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1669
        if (!resumingSession && session.isRejoinable()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1670
            ((SSLSessionContextImpl)sslContext.engineGetServerSessionContext())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1671
                .put(session);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1672
            if (debug != null && Debug.isOn("session")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
                System.out.println(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1674
                    "%% Cached server session: " + session);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1675
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
        } else if (!resumingSession &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
                debug != null && Debug.isOn("session")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
            System.out.println(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
                "%% Didn't cache non-resumable server session: "
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1680
                + session);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1681
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1682
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1683
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1684
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1685
     * Compute finished message with the "server" digest (and then forget
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1686
     * about that digest, it can't be used again).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1687
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
    private void sendChangeCipherAndFinish(boolean finishedTag)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1689
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
        output.flush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1692
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
        Finished mesg = new Finished(protocolVersion, handshakeHash,
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1694
            Finished.SERVER, session.getMasterSecret(), cipherSuite);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1697
         * Send the change_cipher_spec record; then our Finished handshake
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1698
         * message will be the last handshake message.  Flush, and now we
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1699
         * are ready for application data!!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1700
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1701
        sendChangeCipherSpec(mesg, finishedTag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1702
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1703
        /*
6856
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1704
         * save server verify data for secure renegotiation
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1705
         */
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1706
        if (secureRenegotiation) {
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1707
            serverVerifyData = mesg.getVerifyData();
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1708
        }
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1709
533f4ad71f88 6914943: Implement final TLS renegotiation fix
xuelei
parents: 5506
diff changeset
  1710
        /*
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1711
         * Update state machine so client MUST send 'finished' next
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1712
         * The update should only take place if it is not in the fast
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1713
         * handshake mode since the server has to wait for a finished
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1714
         * message from the client.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1715
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1716
        if (finishedTag) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1717
            state = HandshakeMessage.ht_finished;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1718
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1719
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1720
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1721
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1722
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1723
     * Returns a HelloRequest message to kickstart renegotiations
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1724
     */
14664
e71aa0962e70 8003950: Adds missing Override annotations and removes unnecessary imports in sun.security.ssl
xuelei
parents: 14194
diff changeset
  1725
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1726
    HandshakeMessage getKickstartMessage() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1727
        return new HelloRequest();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1728
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1729
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1730
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1731
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1732
     * Fault detected during handshake.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1733
     */
14664
e71aa0962e70 8003950: Adds missing Override annotations and removes unnecessary imports in sun.security.ssl
xuelei
parents: 14194
diff changeset
  1734
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1735
    void handshakeAlert(byte description) throws SSLProtocolException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1736
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1737
        String message = Alerts.alertDescription(description);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1738
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1739
        if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1740
            System.out.println("SSL -- handshake alert:  "
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1741
                + message);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1742
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1743
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1744
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1745
         * It's ok to get a no_certificate alert from a client of which
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1746
         * we *requested* authentication information.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1747
         * However, if we *required* it, then this is not acceptable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1748
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1749
         * Anyone calling getPeerCertificates() on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1750
         * session will get an SSLPeerUnverifiedException.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1751
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1752
        if ((description == Alerts.alert_no_certificate) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1753
                (doClientAuth == SSLEngineImpl.clauth_requested)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1754
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1755
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1756
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1757
        throw new SSLProtocolException("handshake alert: " + message);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1758
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1759
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1760
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1761
     * RSA key exchange is normally used.  The client encrypts a "pre-master
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1762
     * secret" with the server's public key, from the Certificate (or else
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1763
     * ServerKeyExchange) message that was sent to it by the server.  That's
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1764
     * decrypted using the private key before we get here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1765
     */
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1766
    private SecretKey clientKeyExchange(RSAClientKeyExchange mesg)
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1767
            throws IOException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1768
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1769
        if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1770
            mesg.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1771
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1772
        return mesg.preMaster;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1773
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1774
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1775
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1776
     * Verify the certificate sent by the client. We'll only get one if we
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1777
     * sent a CertificateRequest to request client authentication. If we
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1778
     * are in TLS mode, the client may send a message with no certificates
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1779
     * to indicate it does not have an appropriate chain. (In SSLv3 mode,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1780
     * it would send a no certificate alert).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1781
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1782
    private void clientCertificate(CertificateMsg mesg) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1783
        if (debug != null && Debug.isOn("handshake")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1784
            mesg.print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1785
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1786
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1787
        X509Certificate[] peerCerts = mesg.getCertificateChain();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1788
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1789
        if (peerCerts.length == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1790
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1791
             * If the client authentication is only *REQUESTED* (e.g.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1792
             * not *REQUIRED*, this is an acceptable condition.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1793
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1794
            if (doClientAuth == SSLEngineImpl.clauth_requested) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1795
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1796
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1797
                fatalSE(Alerts.alert_bad_certificate,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1798
                    "null cert chain");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1799
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1800
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1801
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1802
        // ask the trust manager to verify the chain
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1803
        X509TrustManager tm = sslContext.getX509TrustManager();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1804
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1805
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1806
            // find out the types of client authentication used
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1807
            PublicKey key = peerCerts[0].getPublicKey();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1808
            String keyAlgorithm = key.getAlgorithm();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1809
            String authType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1810
            if (keyAlgorithm.equals("RSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1811
                authType = "RSA";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1812
            } else if (keyAlgorithm.equals("DSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1813
                authType = "DSA";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1814
            } else if (keyAlgorithm.equals("EC")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1815
                authType = "EC";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1816
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1817
                // unknown public key type
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1818
                authType = "UNKNOWN";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1819
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1820
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1821
            if (tm instanceof X509ExtendedTrustManager) {
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1822
                if (conn != null) {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1823
                    ((X509ExtendedTrustManager)tm).checkClientTrusted(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1824
                        peerCerts.clone(),
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1825
                        authType,
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1826
                        conn);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1827
                } else {
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1828
                    ((X509ExtendedTrustManager)tm).checkClientTrusted(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1829
                        peerCerts.clone(),
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1830
                        authType,
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1831
                        engine);
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1832
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1833
            } else {
7043
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1834
                // Unlikely to happen, because we have wrapped the old
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1835
                // X509TrustManager with the new X509ExtendedTrustManager.
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1836
                throw new CertificateException(
5e2d1edeb2c7 6916074: Add support for TLS 1.2
xuelei
parents: 7039
diff changeset
  1837
                    "Improper X509TrustManager implementation");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1838
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1839
        } catch (CertificateException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1840
            // This will throw an exception, so include the original error.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1841
            fatalSE(Alerts.alert_certificate_unknown, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1842
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1843
        // set the flag for clientCertificateVerify message
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1844
        needClientVerify = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1845
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1846
        session.setPeerCertificates(peerCerts);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1847
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1848
}