History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/ssl/ServerHandshaker.java (1 of 18352 files). Show all

Unified · Split

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