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