jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java

Print this page
rev 5680 : 7192393: Better Checking of order of TLS Messages
Summary: Also reviewed by Andrew Gross<Andrew.Gross@Oracle.COM>
Reviewed-by: weijun


 111             ProtocolVersion activeProtocolVersion,
 112             boolean isInitialHandshake, boolean secureRenegotiation,
 113             byte[] clientVerifyData, byte[] serverVerifyData) {
 114 
 115         super(engine, context, enabledProtocols, true, true,
 116             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 117             clientVerifyData, serverVerifyData);
 118     }
 119 
 120     /*
 121      * This routine handles all the client side handshake messages, one at
 122      * a time.  Given the message type (and in some cases the pending cipher
 123      * spec) it parses the type-specific message.  Then it calls a function
 124      * that handles that specific message.
 125      *
 126      * It updates the state machine (need to verify it) as each message
 127      * is processed, and writes responses as needed using the connection
 128      * in the constructor.
 129      */
 130     void processMessage(byte type, int messageLen) throws IOException {
 131         if (state > type
 132                 && (type != HandshakeMessage.ht_hello_request
 133                     && state != HandshakeMessage.ht_client_hello)) {
 134             throw new SSLProtocolException(
 135                     "Handshake message sequence violation, " + type);
 136         }
 137 
 138         switch (type) {
 139         case HandshakeMessage.ht_hello_request:
 140             this.serverHelloRequest(new HelloRequest(input));
 141             break;
 142 
 143         case HandshakeMessage.ht_server_hello:
 144             this.serverHello(new ServerHello(input, messageLen));
 145             break;
 146 
 147         case HandshakeMessage.ht_certificate:
 148             if (keyExchange == K_DH_ANON || keyExchange == K_ECDH_ANON
 149                     || keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
 150                 fatalSE(Alerts.alert_unexpected_message,
 151                     "unexpected server cert chain");
 152                 // NOTREACHED
 153             }


 176                     throw new SSLProtocolException("Protocol violation:" +
 177                         " the certificate type must be appropriate for the" +
 178                         " selected cipher suite's key exchange algorithm");
 179                 }
 180 
 181                 if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
 182                     throw new SSLProtocolException("Protocol violation:" +
 183                         " server sent a server key exchange message for" +
 184                         " key exchange " + keyExchange +
 185                         " when the public key in the server certificate" +
 186                         " is less than or equal to 512 bits in length");
 187                 }
 188 
 189                 try {
 190                     this.serverKeyExchange(new RSA_ServerKeyExchange(input));
 191                 } catch (GeneralSecurityException e) {
 192                     throwSSLException("Server key", e);
 193                 }
 194                 break;
 195             case K_DH_ANON:

 196                 this.serverKeyExchange(new DH_ServerKeyExchange(
 197                                                 input, protocolVersion));



 198                 break;
 199             case K_DHE_DSS:
 200             case K_DHE_RSA:
 201                 try {
 202                     this.serverKeyExchange(new DH_ServerKeyExchange(
 203                         input, serverKey,
 204                         clnt_random.random_bytes, svr_random.random_bytes,
 205                         messageLen,
 206                         localSupportedSignAlgs, protocolVersion));
 207                 } catch (GeneralSecurityException e) {
 208                     throwSSLException("Server key", e);
 209                 }
 210                 break;
 211             case K_ECDHE_ECDSA:
 212             case K_ECDHE_RSA:
 213             case K_ECDH_ANON:
 214                 try {
 215                     this.serverKeyExchange(new ECDH_ServerKeyExchange
 216                         (input, serverKey, clnt_random.random_bytes,
 217                         svr_random.random_bytes,


 905          * from a performance point of view, since it lets us do it during
 906          * some time that network delays and the server's own calculations
 907          * would otherwise cause to be "dead" in the critical path.
 908          */
 909         SecretKey preMasterSecret;
 910         switch (keyExchange) {
 911         case K_RSA:
 912         case K_RSA_EXPORT:
 913             preMasterSecret = ((RSAClientKeyExchange)m2).preMaster;
 914             break;
 915         case K_KRB5:
 916         case K_KRB5_EXPORT:
 917             byte[] secretBytes =
 918                 ((KerberosClientKeyExchange)m2).getUnencryptedPreMasterSecret();
 919             preMasterSecret = new SecretKeySpec(secretBytes,
 920                 "TlsPremasterSecret");
 921             break;
 922         case K_DHE_RSA:
 923         case K_DHE_DSS:
 924         case K_DH_ANON:
 925             preMasterSecret = dh.getAgreedSecret(serverDH);
 926             break;
 927         case K_ECDHE_RSA:
 928         case K_ECDHE_ECDSA:
 929         case K_ECDH_ANON:
 930             preMasterSecret = ecdh.getAgreedSecret(ephemeralServerKey);
 931             break;
 932         case K_ECDH_RSA:
 933         case K_ECDH_ECDSA:
 934             preMasterSecret = ecdh.getAgreedSecret(serverKey);
 935             break;
 936         default:
 937             throw new IOException("Internal error: unknown key exchange "
 938                 + keyExchange);
 939         }
 940 
 941         calculateKeys(preMasterSecret, null);
 942 
 943         /*
 944          * FOURTH, if we sent a Certificate, we need to send a signed
 945          * CertificateVerify (unless the key in the client's certificate




 111             ProtocolVersion activeProtocolVersion,
 112             boolean isInitialHandshake, boolean secureRenegotiation,
 113             byte[] clientVerifyData, byte[] serverVerifyData) {
 114 
 115         super(engine, context, enabledProtocols, true, true,
 116             activeProtocolVersion, isInitialHandshake, secureRenegotiation,
 117             clientVerifyData, serverVerifyData);
 118     }
 119 
 120     /*
 121      * This routine handles all the client side handshake messages, one at
 122      * a time.  Given the message type (and in some cases the pending cipher
 123      * spec) it parses the type-specific message.  Then it calls a function
 124      * that handles that specific message.
 125      *
 126      * It updates the state machine (need to verify it) as each message
 127      * is processed, and writes responses as needed using the connection
 128      * in the constructor.
 129      */
 130     void processMessage(byte type, int messageLen) throws IOException {
 131         if (state >= type
 132                 && (type != HandshakeMessage.ht_hello_request)) {

 133             throw new SSLProtocolException(
 134                     "Handshake message sequence violation, " + type);
 135         }
 136 
 137         switch (type) {
 138         case HandshakeMessage.ht_hello_request:
 139             this.serverHelloRequest(new HelloRequest(input));
 140             break;
 141 
 142         case HandshakeMessage.ht_server_hello:
 143             this.serverHello(new ServerHello(input, messageLen));
 144             break;
 145 
 146         case HandshakeMessage.ht_certificate:
 147             if (keyExchange == K_DH_ANON || keyExchange == K_ECDH_ANON
 148                     || keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
 149                 fatalSE(Alerts.alert_unexpected_message,
 150                     "unexpected server cert chain");
 151                 // NOTREACHED
 152             }


 175                     throw new SSLProtocolException("Protocol violation:" +
 176                         " the certificate type must be appropriate for the" +
 177                         " selected cipher suite's key exchange algorithm");
 178                 }
 179 
 180                 if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
 181                     throw new SSLProtocolException("Protocol violation:" +
 182                         " server sent a server key exchange message for" +
 183                         " key exchange " + keyExchange +
 184                         " when the public key in the server certificate" +
 185                         " is less than or equal to 512 bits in length");
 186                 }
 187 
 188                 try {
 189                     this.serverKeyExchange(new RSA_ServerKeyExchange(input));
 190                 } catch (GeneralSecurityException e) {
 191                     throwSSLException("Server key", e);
 192                 }
 193                 break;
 194             case K_DH_ANON:
 195                 try {
 196                     this.serverKeyExchange(new DH_ServerKeyExchange(
 197                                                 input, protocolVersion));
 198                 } catch (GeneralSecurityException e) {
 199                     throwSSLException("Server key", e);
 200                 }
 201                 break;
 202             case K_DHE_DSS:
 203             case K_DHE_RSA:
 204                 try {
 205                     this.serverKeyExchange(new DH_ServerKeyExchange(
 206                         input, serverKey,
 207                         clnt_random.random_bytes, svr_random.random_bytes,
 208                         messageLen,
 209                         localSupportedSignAlgs, protocolVersion));
 210                 } catch (GeneralSecurityException e) {
 211                     throwSSLException("Server key", e);
 212                 }
 213                 break;
 214             case K_ECDHE_ECDSA:
 215             case K_ECDHE_RSA:
 216             case K_ECDH_ANON:
 217                 try {
 218                     this.serverKeyExchange(new ECDH_ServerKeyExchange
 219                         (input, serverKey, clnt_random.random_bytes,
 220                         svr_random.random_bytes,


 908          * from a performance point of view, since it lets us do it during
 909          * some time that network delays and the server's own calculations
 910          * would otherwise cause to be "dead" in the critical path.
 911          */
 912         SecretKey preMasterSecret;
 913         switch (keyExchange) {
 914         case K_RSA:
 915         case K_RSA_EXPORT:
 916             preMasterSecret = ((RSAClientKeyExchange)m2).preMaster;
 917             break;
 918         case K_KRB5:
 919         case K_KRB5_EXPORT:
 920             byte[] secretBytes =
 921                 ((KerberosClientKeyExchange)m2).getUnencryptedPreMasterSecret();
 922             preMasterSecret = new SecretKeySpec(secretBytes,
 923                 "TlsPremasterSecret");
 924             break;
 925         case K_DHE_RSA:
 926         case K_DHE_DSS:
 927         case K_DH_ANON:
 928             preMasterSecret = dh.getAgreedSecret(serverDH, true);
 929             break;
 930         case K_ECDHE_RSA:
 931         case K_ECDHE_ECDSA:
 932         case K_ECDH_ANON:
 933             preMasterSecret = ecdh.getAgreedSecret(ephemeralServerKey);
 934             break;
 935         case K_ECDH_RSA:
 936         case K_ECDH_ECDSA:
 937             preMasterSecret = ecdh.getAgreedSecret(serverKey);
 938             break;
 939         default:
 940             throw new IOException("Internal error: unknown key exchange "
 941                 + keyExchange);
 942         }
 943 
 944         calculateKeys(preMasterSecret, null);
 945 
 946         /*
 947          * FOURTH, if we sent a Certificate, we need to send a signed
 948          * CertificateVerify (unless the key in the client's certificate