Produced by Araxis Merge on 9/25/2018 2:13:25 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.
# | Location | File | Last Modified |
---|---|---|---|
1 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\sun\security\ssl | ClientHandshaker.java | Mon Jan 22 14:46:54 2018 UTC |
2 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\sun\security\ssl | ClientHandshaker.java | Wed Sep 12 17:54:29 2018 UTC |
Description | Between Files 1 and 2 |
|
---|---|---|
Text Blocks | Lines | |
Unchanged | 18 | 3440 |
Changed | 17 | 36 |
Inserted | 0 | 0 |
Removed | 0 | 0 |
Whitespace | |
---|---|
Character case | Differences in character case are significant |
Line endings | Differences in line endings (CR and LF characters) are ignored |
CR/LF characters | Not shown in the comparison detail |
No regular expressions were active.
1 | /* | |
2 | * Copyrig ht (c) 199 6, 2015, O racle and/ or its aff iliates. A ll rights reserved. | |
3 | * DO NOT ALTER OR R EMOVE COPY RIGHT NOTI CES OR THI S FILE HEA DER. | |
4 | * | |
5 | * This co de is free software; you can r edistribut e it and/o r modify i t | |
6 | * under t he terms o f the GNU General Pu blic Licen se version 2 only, a s | |
7 | * publish ed by the Free Softw are Founda tion. Ora cle design ates this | |
8 | * particu lar file a s subject to the "Cl asspath" e xception a s provided | |
9 | * by Orac le in the LICENSE fi le that ac companied this code. | |
10 | * | |
11 | * This co de is dist ributed in the hope that it wi ll be usef ul, but WI THOUT | |
12 | * ANY WAR RANTY; wit hout even the implie d warranty of MERCHA NTABILITY or | |
13 | * FITNESS FOR A PAR TICULAR PU RPOSE. Se e the GNU General Pu blic Licen se | |
14 | * version 2 for mor e details (a copy is included in the LIC ENSE file that | |
15 | * accompa nied this code). | |
16 | * | |
17 | * You sho uld have r eceived a copy of th e GNU Gene ral Public License v ersion | |
18 | * 2 along with this work; if not, write to the Fr ee Softwar e Foundati on, | |
19 | * Inc., 5 1 Franklin St, Fifth Floor, Bo ston, MA 0 2110-1301 USA. | |
20 | * | |
21 | * Please contact Or acle, 500 Oracle Par kway, Redw ood Shores , CA 94065 USA | |
22 | * or visi t www.orac le.com if you need a dditional informatio n or have any | |
23 | * questio ns. | |
24 | */ | |
25 | ||
26 | package su n.security .ssl; | |
27 | ||
28 | import jav a.io.*; | |
29 | import jav a.math.Big Integer; | |
30 | import jav a.security .*; | |
31 | import jav a.util.*; | |
32 | ||
33 | import jav a.security .interface s.ECPublic Key; | |
34 | import jav a.security .interface s.RSAPubli cKey; | |
35 | import jav a.security .spec.ECPa rameterSpe c; | |
36 | ||
37 | import jav a.security .cert.X509 Certificat e; | |
38 | import jav a.security .cert.Cert ificateExc eption; | |
39 | import jav a.security .cert.Cert ificatePar singExcept ion; | |
40 | import jav ax.securit y.auth.x50 0.X500Prin cipal; | |
41 | ||
42 | import jav ax.crypto. SecretKey; | |
43 | import jav ax.crypto. spec.Secre tKeySpec; | |
44 | ||
45 | import jav ax.net.ssl .*; | |
46 | ||
47 | import jav ax.securit y.auth.Sub ject; | |
48 | ||
49 | import sun .security. ssl.Handsh akeMessage .*; | |
50 | import sta tic sun.se curity.ssl .CipherSui te.KeyExch ange.*; | |
51 | ||
52 | /** | |
53 | * ClientH andshaker does the p rotocol ha ndshaking from the p oint | |
54 | * of view of a clie nt. It is driven as ychronousl y by hands hake messa ges | |
55 | * as deli vered by t he parent Handshaker class, an d also use s | |
56 | * common functional ity (e.g. key genera tion) that is provid ed there. | |
57 | * | |
58 | * @author David Bro wnell | |
59 | */ | |
60 | final clas s ClientHa ndshaker e xtends Han dshaker { | |
61 | ||
62 | // con stants for subject a lt names o f type DNS and IP | |
63 | privat e final st atic int A LTNAME_DNS = 2; | |
64 | privat e final st atic int A LTNAME_IP = 7; | |
65 | ||
66 | // the server's public key from its certificat e. | |
67 | privat e PublicKe y serverKe y; | |
68 | ||
69 | // the server's ephemeral public key from the server key exchange message | |
70 | // for ECDHE/ECD H_anon and RSA_EXPOR T. | |
71 | privat e PublicKe y ephemera lServerKey ; | |
72 | ||
73 | // ser ver's ephe meral publ ic value f or DHE/DH_ anon key e xchanges | |
74 | privat e BigInteg er serverDH ; | |
75 | ||
76 | privat e DHCrypt dh; | |
77 | ||
78 | privat e ECDHCryp t ecdh; | |
79 | ||
80 | privat e Certific ateRequest certRequ est; | |
81 | ||
82 | privat e boolean serverKeyE xchangeRec eived; | |
83 | ||
84 | /* | |
85 | * The RSA PreMa sterSecret needs to know the v ersion of | |
86 | * Cli entHello t hat was us ed on this handshake . This re presents | |
87 | * the "max vers ion" this client is supporting . In the | |
88 | * cas e of an in itial hand shake, it' s the max version en abled, | |
89 | * but in the ca se of a re sumption a ttempt, it 's the ver sion | |
90 | * of the sessio n we're tr ying to re sume. | |
91 | */ | |
92 | privat e Protocol Version ma xProtocolV ersion; | |
93 | ||
94 | // To switch off the SNI e xtension. | |
95 | privat e final st atic boole an enableS NIExtensio n = | |
96 | Debug.ge tBooleanPr operty("js se.enableS NIExtensio n", true); | |
97 | ||
98 | /* | |
99 | * All ow unsafe server cer tificate c hange? | |
100 | * | |
101 | * Ser ver certif icate chan ge during SSL/TLS re negotiatio n may be c onsidered | |
102 | * uns afe, as de scribed in the Tripl e Handshak e attacks: | |
103 | * | |
104 | * https://s ecure-resu mption.com /tlsauth.p df | |
105 | * | |
106 | * End point iden tification (See | |
107 | * SSL Parameters .getEndpoi ntIdentifi cationAlgo rithm()) i s a pretty nice | |
108 | * gua rantee tha t the serv er certifi cate chang e in reneg otiation i s legal. | |
109 | * How ever, endp oing ident ification is only en abled for HTTPS and LDAP | |
110 | * ove r SSL/TLS by default . It is n ot enough to protect SSL/TLS | |
111 | * con nections o ther than HTTPS and LDAP. | |
112 | * | |
113 | * The renegotia tion indic ation exte nsion (See RFC 5764) is a pret ty | |
114 | * str ong guaran tee that t he endpoin ts on both client an d server s ides | |
115 | * are identical on the sa me connect ion. Howe ver, the T riple Hand shake | |
116 | * att acks can b ypass this guarantee if there is a sessi on-resumpt ion | |
117 | * han dshake bet ween the i nitial ful l handshak e and the renegotiat ion | |
118 | * ful l handshak e. | |
119 | * | |
120 | * Ser ver certif icate chan ge may be unsafe and should be restricte d if | |
121 | * end point iden tification is not en abled and the previo us handsha ke is | |
122 | * a s ession-res umption ab breviated initial ha ndshake, u nless the | |
123 | * ide ntities re presented by both ce rtificates can be re graded as the | |
124 | * sam e (See isI dentityEqu ivalent()) . | |
125 | * | |
126 | * Con sidering t he compati bility imp act and th e actual r equirement s to | |
127 | * sup port serve r certific ate change in practi ce, the sy stem prope rty, | |
128 | * jdk .tls.allow UnsafeServ erCertChan ge, is use d to defin e whether unsafe | |
129 | * ser ver certif icate chan ge in rene gotiation is allowed or not. The | |
130 | * def ault value of the sy stem prope rty is "fa lse". To mitigate t he | |
131 | * com pactibilit y impact, applicatio ns may wan t to set t he system | |
132 | * pro perty to " true" at t heir own r isk. | |
133 | * | |
134 | * If the value of the sys tem proper ty is "fal se", serve r certific ate | |
135 | * cha nge in ren egotiation after a s ession-res umption ab breviated initial | |
136 | * han dshake is restricted (See isId entityEqui valent()). | |
137 | * | |
138 | * If the system property is set to "true" exp licitly, t he restric tion on | |
139 | * ser ver certif icate chan ge in rene gotiation is disable d. | |
140 | */ | |
141 | privat e final st atic boole an allowUn safeServer CertChange = | |
142 | De bug.getBoo leanProper ty("jdk.tl s.allowUns afeServerC ertChange" , false); | |
143 | ||
144 | privat e List<SNI ServerName > requeste dServerNam es = | |
145 | Collecti ons.<SNISe rverName>e mptyList() ; | |
146 | ||
147 | privat e boolean serverName sAccepted = false; | |
148 | ||
149 | /* | |
150 | * the reserved server cer tificate c hain in pr evious han dshaking | |
151 | * | |
152 | * The server ce rtificate chain is o nly reserv ed if the previous | |
153 | * han dshake is a session- resumption abbreviat ed initial handshake . | |
154 | */ | |
155 | privat e X509Cert ificate[] reservedSe rverCerts = null; | |
156 | ||
157 | /* | |
158 | * Con structors | |
159 | */ | |
160 | Client Handshaker (SSLSocket Impl socke t, SSLCont extImpl co ntext, | |
161 | Protocol List enabl edProtocol s, | |
162 | Protocol Version ac tiveProtoc olVersion, | |
163 | boolean isInitialH andshake, boolean se cureRenego tiation, | |
164 | byte[] c lientVerif yData, byt e[] server VerifyData ) { | |
165 | ||
166 | su per(socket , context, enabledPr otocols, t rue, true, | |
167 | activePr otocolVers ion, isIni tialHandsh ake, secur eRenegotia tion, | |
168 | clientVe rifyData, serverVeri fyData); | |
169 | } | |
170 | ||
171 | Client Handshaker (SSLEngine Impl engin e, SSLCont extImpl co ntext, | |
172 | Protocol List enabl edProtocol s, | |
173 | Protocol Version ac tiveProtoc olVersion, | |
174 | boolean isInitialH andshake, boolean se cureRenego tiation, | |
175 | byte[] c lientVerif yData, byt e[] server VerifyData ) { | |
176 | ||
177 | su per(engine , context, enabledPr otocols, t rue, true, | |
178 | activePr otocolVers ion, isIni tialHandsh ake, secur eRenegotia tion, | |
179 | clientVe rifyData, serverVeri fyData); | |
180 | } | |
181 | ||
182 | /* | |
183 | * Thi s routine handles al l the clie nt side ha ndshake me ssages, on e at | |
184 | * a t ime. Give n the mess age type ( and in som e cases th e pending cipher | |
185 | * spe c) it pars es the typ e-specific message. Then it c alls a fun ction | |
186 | * tha t handles that speci fic messag e. | |
187 | * | |
188 | * It updates th e state ma chine (nee d to verif y it) as e ach messag e | |
189 | * is processed, and write s response s as neede d using th e connecti on | |
190 | * in the constr uctor. | |
191 | */ | |
192 | @Overr ide | |
193 | void p rocessMess age(byte t ype, int m essageLen) throws IO Exception { | |
194 | if (state >= type | |
195 | && ( type != Ha ndshakeMes sage.ht_he llo_reques t)) { | |
196 | throw ne w SSLProto colExcepti on( | |
197 | "Handshake message s equence vi olation, " + type); | |
198 | } | |
199 | ||
200 | sw itch (type ) { | |
201 | ca se Handsha keMessage. ht_hello_r equest: | |
202 | this.ser verHelloRe quest(new HelloReque st(input)) ; | |
203 | break; | |
204 | ||
205 | ca se Handsha keMessage. ht_server_ hello: | |
206 | this.ser verHello(n ew ServerH ello(input , messageL en)); | |
207 | break; | |
208 | ||
209 | ca se Handsha keMessage. ht_certifi cate: | |
210 | if (keyE xchange == K_DH_ANON || keyExc hange == K _ECDH_ANON | |
211 | || keyExch ange == K_ KRB5 || ke yExchange == K_KRB5_ EXPORT) { | |
212 | fata lSE(Alerts .alert_une xpected_me ssage, | |
213 | "unexpecte d server c ert chain" ); | |
214 | // N OTREACHED | |
215 | } | |
216 | this.ser verCertifi cate(new C ertificate Msg(input) ); | |
217 | serverKe y = | |
218 | sess ion.getPee rCertifica tes()[0].g etPublicKe y(); | |
219 | break; | |
220 | ||
221 | ca se Handsha keMessage. ht_server_ key_exchan ge: | |
222 | serverKe yExchangeR eceived = true; | |
223 | switch ( keyExchang e) { | |
224 | case K_R SA_EXPORT: | |
225 | /** | |
226 | * T he server key exchan ge message is sent b y the serv er only | |
227 | * w hen the se rver certi ficate mes sage does not contai n the | |
228 | * p roper amou nt of data to allow the client to exchan ge a | |
229 | * premaste r PW , such as when RSA_E XPORT is u sed and th e | |
230 | * p ublic key in the ser ver certif icate is l onger than 512 bits. | |
231 | */ | |
232 | if ( serverKey == null) { | |
233 | throw new SSLProtoco lException | |
234 | ("Serv er did not send cert ificate me ssage"); | |
235 | } | |
236 | ||
237 | if ( !(serverKe y instance of RSAPubl icKey)) { | |
238 | throw new SSLProtoco lException ("Protocol violation :" + | |
239 | " the certificat e type mus t be appro priate for the" + | |
240 | " sele cted ciphe r suite's key exchan ge algorit hm"); | |
241 | } | |
242 | ||
243 | if ( JsseJce.ge tRSAKeyLen gth(server Key) <= 51 2) { | |
244 | throw new SSLProtoco lException ("Protocol violation :" + | |
245 | " serv er sent a server key exchange message fo r" + | |
246 | " key exchange " + keyExch ange + | |
247 | " when the publi c key in t he server certificat e" + | |
248 | " is l ess than o r equal to 512 bits in length" ); | |
249 | } | |
250 | ||
251 | try { | |
252 | this.serve rKeyExchan ge(new RSA _ServerKey Exchange(i nput)); | |
253 | } ca tch (Gener alSecurity Exception e) { | |
254 | throwSSLEx ception("S erver key" , e); | |
255 | } | |
256 | brea k; | |
257 | case K_D H_ANON: | |
258 | try { | |
259 | this.serve rKeyExchan ge(new DH_ ServerKeyE xchange( | |
260 | in put, proto colVersion )); | |
261 | } ca tch (Gener alSecurity Exception e) { | |
262 | throwSSLEx ception("S erver key" , e); | |
263 | } | |
264 | brea k; | |
265 | case K_D HE_DSS: | |
266 | case K_D HE_RSA: | |
267 | try { | |
268 | this.serve rKeyExchan ge(new DH_ ServerKeyE xchange( | |
269 | input, serverKey , | |
270 | clnt_r andom.rand om_bytes, svr_random .random_by tes, | |
271 | messag eLen, | |
272 | getLoc alSupporte dSignAlgs( ), protoco lVersion)) ; | |
273 | } ca tch (Gener alSecurity Exception e) { | |
274 | throwSSLEx ception("S erver key" , e); | |
275 | } | |
276 | brea k; | |
277 | case K_E CDHE_ECDSA : | |
278 | case K_E CDHE_RSA: | |
279 | case K_E CDH_ANON: | |
280 | try { | |
281 | this.serve rKeyExchan ge(new ECD H_ServerKe yExchange | |
282 | (input , serverKe y, clnt_ra ndom.rando m_bytes, | |
283 | svr_ra ndom.rando m_bytes, | |
284 | getLoc alSupporte dSignAlgs( ), protoco lVersion)) ; | |
285 | } ca tch (Gener alSecurity Exception e) { | |
286 | throwSSLEx ception("S erver key" , e); | |
287 | } | |
288 | brea k; | |
289 | case K_R SA: | |
290 | case K_D H_RSA: | |
291 | case K_D H_DSS: | |
292 | case K_E CDH_ECDSA: | |
293 | case K_E CDH_RSA: | |
294 | thro w new SSLP rotocolExc eption( | |
295 | "Protocol violation: server se nt a serve r key exch ange" | |
296 | + " messag e for key exchange " + keyExch ange); | |
297 | case K_K RB5: | |
298 | case K_K RB5_EXPORT : | |
299 | thro w new SSLP rotocolExc eption( | |
300 | "unexpecte d receipt of server key exchan ge algorit hm"); | |
301 | default: | |
302 | thro w new SSLP rotocolExc eption( | |
303 | "unsupport ed key exc hange algo rithm = " | |
304 | + keyExcha nge); | |
305 | } | |
306 | break; | |
307 | ||
308 | ca se Handsha keMessage. ht_certifi cate_reque st: | |
309 | // save for later, it's hand led by ser verHelloDo ne | |
310 | if ((key Exchange = = K_DH_ANO N) || (key Exchange = = K_ECDH_A NON)) { | |
311 | thro w new SSLH andshakeEx ception( | |
312 | "Client au thenticati on request ed for "+ | |
313 | "anonymous cipher su ite."); | |
314 | } else i f (keyExch ange == K_ KRB5 || ke yExchange == K_KRB5_ EXPORT) { | |
315 | thro w new SSLH andshakeEx ception( | |
316 | "Client ce rtificate requested for "+ | |
317 | "kerberos cipher sui te."); | |
318 | } | |
319 | certRequ est = new Certificat eRequest(i nput, prot ocolVersio n); | |
320 | if (debu g != null && Debug.i sOn("hands hake")) { | |
321 | cert Request.pr int(System .out); | |
322 | } | |
323 | ||
324 | if (prot ocolVersio n.v >= Pro tocolVersi on.TLS12.v ) { | |
325 | Coll ection<Sig natureAndH ashAlgorit hm> peerSi gnAlgs = | |
326 | certReques t.getSignA lgorithms( ); | |
327 | if ( peerSignAl gs == null || peerSi gnAlgs.isE mpty()) { | |
328 | throw new SSLHandsha keExceptio n( | |
329 | "No pe er support ed signatu re algorit hms"); | |
330 | } | |
331 | ||
332 | Coll ection<Sig natureAndH ashAlgorit hm> suppor tedPeerSig nAlgs = | |
333 | SignatureA ndHashAlgo rithm.getS upportedAl gorithms( | |
334 | al gorithmCon straints, peerSignAl gs); | |
335 | if ( supportedP eerSignAlg s.isEmpty( )) { | |
336 | throw new SSLHandsha keExceptio n( | |
337 | "No su pported si gnature an d hash alg orithm in common"); | |
338 | } | |
339 | ||
340 | setP eerSupport edSignAlgs (supported PeerSignAl gs); | |
341 | sess ion.setPee rSupported SignatureA lgorithms( | |
342 | su pportedPee rSignAlgs) ; | |
343 | } | |
344 | ||
345 | break; | |
346 | ||
347 | ca se Handsha keMessage. ht_server_ hello_done : | |
348 | this.ser verHelloDo ne(new Ser verHelloDo ne(input)) ; | |
349 | break; | |
350 | ||
351 | ca se Handsha keMessage. ht_finishe d: | |
352 | // A Cha ngeCipherS pec record must have been rece ived prior to | |
353 | // recep tion of th e Finished message ( RFC 5246, 7.4.9). | |
354 | if (!rec eivedChang eCipherSpe c()) { | |
355 | fata lSE(Alerts .alert_han dshake_fai lure, | |
356 | "Recei ved Finish ed message before Ch angeCipher Spec"); | |
357 | } | |
358 | ||
359 | this.ser verFinishe d( | |
360 | new Finished(p rotocolVer sion, inpu t, cipherS uite)); | |
361 | break; | |
362 | ||
363 | de fault: | |
364 | throw ne w SSLProto colExcepti on( | |
365 | "Ill egal clien t handshak e msg, " + type); | |
366 | } | |
367 | ||
368 | // | |
369 | // Move stat e machine forward if the messa ge handlin g | |
370 | // code didn 't already do so | |
371 | // | |
372 | if (state < type) { | |
373 | state = type; | |
374 | } | |
375 | } | |
376 | ||
377 | /* | |
378 | * Use d by the s erver to k ickstart n egotiation s -- this requests a | |
379 | * "cl ient hello " to reneg otiate cur rent ciphe r specs (e .g. maybe lots | |
380 | * of data has b een encryp ted with t he same ke ys, or the server ne eds | |
381 | * the client to present a certifica te). | |
382 | */ | |
383 | privat e void ser verHelloRe quest(Hell oRequest m esg) throw s IOExcept ion { | |
384 | if (debug != null && D ebug.isOn( "handshake ")) { | |
385 | mesg.pri nt(System. out); | |
386 | } | |
387 | ||
388 | // | |
389 | // Could be (e.g. at c onnection setup) tha t we alrea dy | |
390 | // sent the "client he llo" but t he server' s not seen it. | |
391 | // | |
392 | if (state < HandshakeM essage.ht_ client_hel lo) { | |
393 | if (!sec ureRenegot iation && !allowUnsa feRenegoti ation) { | |
394 | // r enegotiati on is not allowed. | |
395 | if ( activeProt ocolVersio n.v >= Pro tocolVersi on.TLS10.v ) { | |
396 | // respons e with a n o_renegoti ation warn ing, | |
397 | warningSE( Alerts.ale rt_no_rene gotiation) ; | |
398 | ||
399 | // invalid ate the ha ndshake so that the caller can | |
400 | // dispose this obje ct. | |
401 | invalidate d = true; | |
402 | ||
403 | // If ther e is still unread bl ock in the handshake | |
404 | // input s tream, it would be t runcated w ith the di sposal | |
405 | // and the next hand shake mess age will b ecome inco mplete. | |
406 | // | |
407 | // However , accordin g to SSL/T LS specifi cations, n o more | |
408 | // handsha ke message should im mediately follow Cli entHello | |
409 | // or Hell oRequest. So just le t it be. | |
410 | } el se { | |
411 | // For SSL v3, send t he handsha ke_failure fatal err or. | |
412 | // Note th at SSLv3 d oes not de fine a no_ renegotiat ion | |
413 | // alert l ike TLSv1. However w e cannot i gnore the message | |
414 | // simply, otherwise the other side was waiting fo r a | |
415 | // respons e that wou ld never c ome. | |
416 | fatalSE(Al erts.alert _handshake _failure, | |
417 | "Reneg otiation i s not allo wed"); | |
418 | } | |
419 | } else { | |
420 | if ( !secureRen egotiation ) { | |
421 | if (debug != null && Debug.isO n("handsha ke")) { | |
422 | System .out.print ln( | |
423 | "W arning: co ntinue wit h insecure renegotia tion"); | |
424 | } | |
425 | } | |
426 | kick start(); | |
427 | } | |
428 | } | |
429 | } | |
430 | ||
431 | ||
432 | /* | |
433 | * Ser ver choose s session parameters given opt ions creat ed by the | |
434 | * cli ent -- bas ically, ci pher optio ns, sessio n id, and someday a | |
435 | * set of compre ssion opti ons. | |
436 | * | |
437 | * The re are two branches of the sta te machine , decided by the | |
438 | * det ails of th is message . One is the "fast" handshake , where we | |
439 | * can resume th e pre-exis ting sessi on we aske d resume. The other | |
440 | * is a more exp ensive "fu ll" handsh ake, with key exchan ge and | |
441 | * pro bably auth entication getting d one. | |
442 | */ | |
443 | privat e void ser verHello(S erverHello mesg) thr ows IOExce ption { | |
444 | se rverKeyExc hangeRecei ved = fals e; | |
445 | if (debug != null && D ebug.isOn( "handshake ")) { | |
446 | mesg.pri nt(System. out); | |
447 | } | |
448 | ||
449 | // check if the server selected protocol v ersion is OK for us | |
450 | Pr otocolVers ion mesgVe rsion = me sg.protoco lVersion; | |
451 | if (!isNegot iable(mesg Version)) { | |
452 | throw ne w SSLHands hakeExcept ion( | |
453 | "Ser ver chose " + mesgVe rsion + | |
454 | ", b ut that pr otocol ver sion is no t enabled or not sup ported " + | |
455 | "by the client ."); | |
456 | } | |
457 | ||
458 | ha ndshakeHas h.protocol Determined (mesgVersi on); | |
459 | ||
460 | // Set proto colVersion and propa gate to SS LSocket an d the | |
461 | // Handshake streams | |
462 | se tVersion(m esgVersion ); | |
463 | ||
464 | // check the "renegoti ation_info " extensio n | |
465 | Re negotiatio nInfoExten sion serve rHelloRI = (Renegoti ationInfoE xtension) | |
466 | mesg.exten sions.get( ExtensionT ype.EXT_RE NEGOTIATIO N_INFO); | |
467 | if (serverHe lloRI != n ull) { | |
468 | if (isIn itialHands hake) { | |
469 | // v erify the length of the "reneg otiated_co nnection" field | |
470 | if ( !serverHel loRI.isEmp ty()) { | |
471 | // abort t he handsha ke with a fatal hand shake_fail ure alert | |
472 | fatalSE(Al erts.alert _handshake _failure, | |
473 | "The r enegotiati on_info fi eld is not empty"); | |
474 | } | |
475 | ||
476 | secu reRenegoti ation = tr ue; | |
477 | } else { | |
478 | // F or a legac y renegoti ation, the client MU ST verify that | |
479 | // i t does not contain t he "renego tiation_in fo" extens ion. | |
480 | if ( !secureRen egotiation ) { | |
481 | fatalSE(Al erts.alert _handshake _failure, | |
482 | "Unexp ected rene gotiation indication extension "); | |
483 | } | |
484 | ||
485 | // v erify the client_ver ify_data a nd server_ verify_dat a values | |
486 | byte [] verifyD ata = | |
487 | new byte[c lientVerif yData.leng th + serve rVerifyDat a.length]; | |
488 | Syst em.arrayco py(clientV erifyData, 0, verify Data, | |
489 | 0, cli entVerifyD ata.length ); | |
490 | Syst em.arrayco py(serverV erifyData, 0, verify Data, | |
491 | client VerifyData .length, s erverVerif yData.leng th); | |
492 | if ( !MessageDi gest.isEqu al(verifyD ata, | |
493 | serverHe lloRI.getR enegotiate dConnectio n())) { | |
494 | fatalSE(Al erts.alert _handshake _failure, | |
495 | "Incor rect verif y data in ServerHell o " + | |
496 | "reneg otiation_i nfo messag e"); | |
497 | } | |
498 | } | |
499 | } else { | |
500 | // no re negotiatio n indicati on extensi on | |
501 | if (isIn itialHands hake) { | |
502 | if ( !allowLega cyHelloMes sages) { | |
503 | // abort t he handsha ke with a fatal hand shake_fail ure alert | |
504 | fatalSE(Al erts.alert _handshake _failure, | |
505 | "Faile d to negot iate the u se of secu re renegot iation"); | |
506 | } | |
507 | ||
508 | secu reRenegoti ation = fa lse; | |
509 | if ( debug != n ull && Deb ug.isOn("h andshake") ) { | |
510 | System.out .println(" Warning: N o renegoti ation " + | |
511 | "ind ication ex tension in ServerHel lo"); | |
512 | } | |
513 | } else { | |
514 | // F or a secur e renegoti ation, the client mu st abort t he | |
515 | // h andshake i f no "rene gotiation_ info" exte nsion is p resent. | |
516 | if ( secureRene gotiation) { | |
517 | fatalSE(Al erts.alert _handshake _failure, | |
518 | "No re negotiatio n indicati on extensi on"); | |
519 | } | |
520 | ||
521 | // w e have alr eady allow ed unsafe renegotati on before request | |
522 | // t he renegot iation. | |
523 | } | |
524 | } | |
525 | ||
526 | // | |
527 | // Save serv er nonce, we always use it to compute co nnection | |
528 | // keys an d it's als o used to create the master PW if we're | |
529 | // creating a new sess ion (i.e. in the ful l handshak e). | |
530 | // | |
531 | sv r_random = mesg.svr_ random; | |
532 | ||
533 | if (isNegoti able(mesg. cipherSuit e) == fals e) { | |
534 | fatalSE( Alerts.ale rt_illegal _parameter , | |
535 | "Ser ver select ed imprope r ciphersu ite " + me sg.cipherS uite); | |
536 | } | |
537 | ||
538 | se tCipherSui te(mesg.ci pherSuite) ; | |
539 | if (protocol Version.v >= Protoco lVersion.T LS12.v) { | |
540 | handshak eHash.setF inishedAlg (cipherSui te.prfAlg. getPRFHash Alg()); | |
541 | } | |
542 | ||
543 | if (mesg.com pression_m ethod != 0 ) { | |
544 | fatalSE( Alerts.ale rt_illegal _parameter , | |
545 | "com pression t ype not su pported, " | |
546 | + me sg.compres sion_metho d); | |
547 | // NOTRE ACHED | |
548 | } | |
549 | ||
550 | // so far so good, let 's look at the sessi on | |
551 | if (session != null) { | |
552 | // we tr ied to res ume, let's see what the server decided | |
553 | if (sess ion.getSes sionId().e quals(mesg .sessionId )) { | |
554 | // s erver resu med the se ssion, let 's make su re everyth ing | |
555 | // c hecks out | |
556 | ||
557 | // V erify that the sessi on ciphers are uncha nged. | |
558 | Ciph erSuite se ssionSuite = session .getSuite( ); | |
559 | if ( cipherSuit e != sessi onSuite) { | |
560 | throw new SSLProtoco lException | |
561 | ("Serv er returne d wrong ci pher suite for sessi on"); | |
562 | } | |
563 | ||
564 | // v erify prot ocol versi on match | |
565 | Prot ocolVersio n sessionV ersion = s ession.get ProtocolVe rsion(); | |
566 | if ( protocolVe rsion != s essionVers ion) { | |
567 | throw new SSLProtoco lException | |
568 | ("Serv er resumed session w ith wrong protocol v ersion"); | |
569 | } | |
570 | ||
571 | // v alidate su bject iden tity | |
572 | if ( sessionSui te.keyExch ange == K_ KRB5 || | |
573 | sessionSui te.keyExch ange == K_ KRB5_EXPOR T) { | |
574 | Principal localPrinc ipal = ses sion.getLo calPrincip al(); | |
575 | ||
576 | Subject su bject = nu ll; | |
577 | try { | |
578 | subjec t = Access Controller .doPrivile ged( | |
579 | ne w Privileg edExceptio nAction<Su bject>() { | |
580 | @O verride | |
581 | pu blic Subje ct run() t hrows Exce ption { | |
582 | return K rb5Helper. getClientS ubject(get AccSE()); | |
583 | }} ); | |
584 | } catch (P rivilegedA ctionExcep tion e) { | |
585 | subjec t = null; | |
586 | if (de bug != nul l && Debug .isOn("ses sion")) { | |
587 | Sy stem.out.p rintln("At tempt to o btain" + | |
588 | " subject failed!"); | |
589 | } | |
590 | } | |
591 | ||
592 | if (subjec t != null) { | |
593 | // Eli minate dep endency on KerberosP rincipal | |
594 | Set<Pr incipal> p rincipals = | |
595 | su bject.getP rincipals( Principal. class); | |
596 | if (!p rincipals. contains(l ocalPrinci pal)) { | |
597 | th row new SS LProtocolE xception(" Server res umed" + | |
598 | " sessio n with wro ng subject identity" ); | |
599 | } else { | |
600 | if (debug != null && D ebug.isOn( "session") ) | |
601 | System.o ut.println ("Subject identity i s same"); | |
602 | } | |
603 | } else { | |
604 | if (de bug != nul l && Debug .isOn("ses sion")) | |
605 | Sy stem.out.p rintln("Ke rberos cre dentials a re not" + | |
606 | " presen t in the c urrent Sub ject; chec k if " + | |
607 | " javax. security.a uth.useSub jectAsCred s" + | |
608 | " system property has been s et to fals e"); | |
609 | throw new SSLPro tocolExcep tion | |
610 | (" Server res umed sessi on with no subject") ; | |
611 | } | |
612 | } | |
613 | ||
614 | // l ooks fine; resume it , and upda te the sta te machine . | |
615 | resu mingSessio n = true; | |
616 | stat e = Handsh akeMessage .ht_finish ed - 1; | |
617 | calc ulateConne ctionKeys( session.ge tMasterSec ret()); | |
618 | if ( debug != n ull && Deb ug.isOn("s ession")) { | |
619 | System.out .println(" %% Server resumed " + session) ; | |
620 | } | |
621 | } else { | |
622 | // w e wanted t o resume, but the se rver refus ed | |
623 | // | |
624 | // I nvalidate the sessio n for init ial handsh ake in cas e | |
625 | // o f reusing next time. | |
626 | if ( isInitialH andshake) { | |
627 | session.in validate() ; | |
628 | } | |
629 | sess ion = null ; | |
630 | if ( !enableNew Session) { | |
631 | throw new SSLExcepti on("New se ssion crea tion is di sabled"); | |
632 | } | |
633 | } | |
634 | } | |
635 | ||
636 | // check t he "extend ed_master_ PW " extensio n | |
637 | Ex tendedMast erSecretEx tension ex tendedMast erSecretEx t = | |
638 | (Ext endedMaste rSecretExt ension)mes g.extensio ns.get( | |
639 | Extens ionType.EX T_EXTENDED _MASTER_SE CRET); | |
640 | if (extended MasterSecr etExt != n ull) { | |
641 | // Is it the expec ted server extension ? | |
642 | if (!use ExtendedMa sterSecret || | |
643 | !(mesgVers ion.v >= P rotocolVer sion.TLS10 .v) || !re questedToU seEMS) { | |
644 | fata lSE(Alerts .alert_uns upported_e xtension, | |
645 | "Server se nt the ext ended_mast er_ PW " + | |
646 | "exten sion impro perly"); | |
647 | } | |
648 | ||
649 | // For a bbreviated handshake , if the o riginal se ssion did not use | |
650 | // the "ex tended_mas ter_ PW " extensio n but the new Server Hello | |
651 | // conta ins the ex tension, t he client MUST abort the hands hake. | |
652 | if (resu mingSessio n && (sess ion != nul l) && | |
653 | !session.g etUseExten dedMasterS ecret()) { | |
654 | fata lSE(Alerts .alert_uns upported_e xtension, | |
655 | "Server se nt an unex pected ext ended_mast er_ PW " + | |
656 | "exten sion on se ssion resu mption"); | |
657 | } | |
658 | } else { | |
659 | if (useE xtendedMas terSecret && !allowL egacyMaste rSecret) { | |
660 | // F or full ha ndshake, i f a client receives a ServerHe llo | |
661 | // w ithout the extension , it SHOUL D abort th e handshak e if | |
662 | // i t does not wish to i nteroperat e with leg acy server s. | |
663 | fata lSE(Alerts .alert_han dshake_fai lure, | |
664 | "Extended Master Sec ret extens ion is req uired"); | |
665 | } | |
666 | ||
667 | if (resu mingSessio n && (sess ion != nul l)) { | |
668 | if ( session.ge tUseExtend edMasterSe cret()) { | |
669 | // For abb reviated h andshake, if the ori ginal sess ion used | |
670 | // the "ex tended_mas ter_ PW " extensio n but the new | |
671 | // ServerH ello does not contai n the exte nsion, the client | |
672 | // MUST ab ort the ha ndshake. | |
673 | fatalSE(Al erts.alert _handshake _failure, | |
674 | "M issing Ext ended Mast er Secret extension " + | |
675 | "o n session resumption "); | |
676 | } el se if (use ExtendedMa sterSecret && !allow LegacyResu mption) { | |
677 | // Unlikel y, abbrevi ated hands hake shoul d be disca rded. | |
678 | fatalSE(Al erts.alert _handshake _failure, | |
679 | "Exten ded Master Secret ex tension is required" ); | |
680 | } | |
681 | } | |
682 | } | |
683 | ||
684 | if (resuming Session && session ! = null) { | |
685 | setHands hakeSessio nSE(sessio n); | |
686 | // Reser ve the han dshake sta te if this is a sess ion-resump tion | |
687 | // abbre viated ini tial hands hake. | |
688 | if (isIn itialHands hake) { | |
689 | sess ion.setAsS essionResu mption(tru e); | |
690 | } | |
691 | ||
692 | return; | |
693 | } | |
694 | ||
695 | // check ext ensions | |
696 | fo r (HelloEx tension ex t : mesg.e xtensions. list()) { | |
697 | Extensio nType type = ext.typ e; | |
698 | if (type == Extens ionType.EX T_SERVER_N AME) { | |
699 | serv erNamesAcc epted = tr ue; | |
700 | } else i f ((type ! = Extensio nType.EXT_ ELLIPTIC_C URVES) | |
701 | && (type ! = Extensio nType.EXT_ EC_POINT_F ORMATS) | |
702 | && (type ! = Extensio nType.EXT_ SERVER_NAM E) | |
703 | && (type ! = Extensio nType.EXT_ RENEGOTIAT ION_INFO) | |
704 | && (type ! = Extensio nType.EXT_ EXTENDED_M ASTER_SECR ET)){ | |
705 | fata lSE(Alerts .alert_uns upported_e xtension, | |
706 | "Server se nt an unsu pported ex tension: " + type); | |
707 | } | |
708 | } | |
709 | ||
710 | // Create a new sessio n, we need to do the full hand shake | |
711 | se ssion = ne w SSLSessi onImpl(pro tocolVersi on, cipher Suite, | |
712 | ge tLocalSupp ortedSignA lgs(), | |
713 | me sg.session Id, getHos tSE(), get PortSE(), | |
714 | (e xtendedMas terSecretE xt != null )); | |
715 | se ssion.setR equestedSe rverNames( requestedS erverNames ); | |
716 | se tHandshake SessionSE( session); | |
717 | if (debug != null && D ebug.isOn( "handshake ")) { | |
718 | System.o ut.println ("** " + c ipherSuite ); | |
719 | } | |
720 | } | |
721 | ||
722 | /* | |
723 | * Ser ver's own key was ei ther a sig ning-only key, or wa s too | |
724 | * lar ge for exp ort rules ... this m essage hol ds an ephe meral | |
725 | * RSA key to us e for key exchange. | |
726 | */ | |
727 | privat e void ser verKeyExch ange(RSA_S erverKeyEx change mes g) | |
728 | throws I OException , GeneralS ecurityExc eption { | |
729 | if (debug != null && D ebug.isOn( "handshake ")) { | |
730 | mesg.pri nt(System. out); | |
731 | } | |
732 | if (!mesg.ve rify(serve rKey, clnt _random, s vr_random) ) { | |
733 | fatalSE( Alerts.ale rt_handsha ke_failure , | |
734 | "ser ver key ex change inv alid"); | |
735 | // NOTRE ACHED | |
736 | } | |
737 | ep hemeralSer verKey = m esg.getPub licKey(); | |
738 | ||
739 | // check con straints o f RSA Publ icKey | |
740 | if (!algorit hmConstrai nts.permit s( | |
741 | EnumSet. of(CryptoP rimitive.K EY_AGREEME NT), ephem eralServer Key)) { | |
742 | ||
743 | throw ne w SSLHands hakeExcept ion("RSA S erverKeyEx change " + | |
744 | "does not comply to algorithm constraint s"); | |
745 | } | |
746 | } | |
747 | ||
748 | ||
749 | /* | |
750 | * Dif fie-Hellma n key exch ange. We save the s erver publ ic key and | |
751 | * our own D-H a lgorithm o bject so w e can defe r key calc ulations | |
752 | * unt il after w e've sent the client key excha nge messag e (which | |
753 | * giv es client and server some usef ul paralle lism). | |
754 | */ | |
755 | privat e void ser verKeyExch ange(DH_Se rverKeyExc hange mesg ) | |
756 | throws I OException { | |
757 | if (debug != null && D ebug.isOn( "handshake ")) { | |
758 | mesg.pri nt(System. out); | |
759 | } | |
760 | dh = new DHC rypt(mesg. getModulus (), mesg.g etBase(), | |
761 | sslCon text.getSe cureRandom ()); | |
762 | se rverDH = m esg.getSer verPublicK ey(); | |
763 | ||
764 | // check alg orithm con straints | |
765 | dh .checkCons traints(al gorithmCon straints, serverDH); | |
766 | } | |
767 | ||
768 | privat e void ser verKeyExch ange(ECDH_ ServerKeyE xchange me sg) | |
769 | throws I OException { | |
770 | if (debug != null && D ebug.isOn( "handshake ")) { | |
771 | mesg.pri nt(System. out); | |
772 | } | |
773 | EC PublicKey key = mesg .getPublic Key(); | |
774 | ec dh = new E CDHCrypt(k ey.getPara ms(), sslC ontext.get SecureRand om()); | |
775 | ep hemeralSer verKey = k ey; | |
776 | ||
777 | // check con straints o f EC Publi cKey | |
778 | if (!algorit hmConstrai nts.permit s( | |
779 | EnumSet. of(CryptoP rimitive.K EY_AGREEME NT), ephem eralServer Key)) { | |
780 | ||
781 | throw ne w SSLHands hakeExcept ion("ECDH ServerKeyE xchange " + | |
782 | "does not comply to algorithm constraint s"); | |
783 | } | |
784 | } | |
785 | ||
786 | /* | |
787 | * The server's "Hello Don e" message is the cl ient's sig n that | |
788 | * it' s time to do all the hard work . | |
789 | */ | |
790 | privat e void ser verHelloDo ne(ServerH elloDone m esg) throw s IOExcept ion { | |
791 | if (debug != null && D ebug.isOn( "handshake ")) { | |
792 | mesg.pri nt(System. out); | |
793 | } | |
794 | /* | |
795 | * Always ma ke sure th e input ha s been dig ested befo re we | |
796 | * start emi tting data , to ensur e the hash es are cor rectly | |
797 | * computed for the Fi nished and Certifica teVerify m essages | |
798 | * which we send (here ). | |
799 | * / | |
800 | in put.digest Now(); | |
801 | ||
802 | /* | |
803 | * FIRST ... if reques ted, send an appropr iate Certi ficate cha in | |
804 | * to authen ticate the client, a nd remembe r the asso ciated pri vate | |
805 | * key to si gn the Cer tificateVe rify messa ge. | |
806 | * / | |
807 | Pr ivateKey s igningKey = null; | |
808 | ||
809 | if (certRequ est != nul l) { | |
810 | X509Exte ndedKeyMan ager km = sslContext .getX509Ke yManager() ; | |
811 | ||
812 | ArrayLis t<String> keytypesTm p = new Ar rayList<>( 4); | |
813 | ||
814 | for (int i = 0; i < certRequ est.types. length; i+ +) { | |
815 | Stri ng typeNam e; | |
816 | ||
817 | swit ch (certRe quest.type s[i]) { | |
818 | case Certi ficateRequ est.cct_rs a_sign: | |
819 | typeNa me = "RSA" ; | |
820 | break; | |
821 | ||
822 | case Certi ficateRequ est.cct_ds s_sign: | |
823 | typeNa me = "DSA" ; | |
824 | br eak; | |
825 | ||
826 | case Certi ficateRequ est.cct_ec dsa_sign: | |
827 | // ign ore if we do not hav e EC crypt o availabl e | |
828 | typeNa me = JsseJ ce.isEcAva ilable() ? "EC" : nu ll; | |
829 | break; | |
830 | ||
831 | // Fixed D H/ECDH cli ent authen tication n ot support ed | |
832 | // | |
833 | // case Ce rtificateR equest.cct _rsa_fixed _dh: | |
834 | // case Ce rtificateR equest.cct _dss_fixed _dh: | |
835 | // case Ce rtificateR equest.cct _rsa_fixed _ecdh: | |
836 | // case Ce rtificateR equest.cct _ecdsa_fix ed_ecdh: | |
837 | // | |
838 | // Any oth er values (currently not used in TLS) | |
839 | // | |
840 | // case Ce rtificateR equest.cct _rsa_ephem eral_dh: | |
841 | // case Ce rtificateR equest.cct _dss_ephem eral_dh: | |
842 | default: | |
843 | typeNa me = null; | |
844 | break; | |
845 | } | |
846 | ||
847 | if ( (typeName != null) & & (!keytyp esTmp.cont ains(typeN ame))) { | |
848 | keytypesTm p.add(type Name); | |
849 | } | |
850 | } | |
851 | ||
852 | String a lias = nul l; | |
853 | int keyt ypesTmpSiz e = keytyp esTmp.size (); | |
854 | if (keyt ypesTmpSiz e != 0) { | |
855 | Stri ng keytype s[] = | |
856 | keytyp esTmp.toAr ray(new St ring[keyty pesTmpSize ]); | |
857 | ||
858 | if ( conn != nu ll) { | |
859 | alias = km .chooseCli entAlias(k eytypes, | |
860 | certRe quest.getA uthorities (), conn); | |
861 | } el se { | |
862 | alias = km .chooseEng ineClientA lias(keyty pes, | |
863 | certRe quest.getA uthorities (), engine ); | |
864 | } | |
865 | } | |
866 | ||
867 | Certific ateMsg m1 = null; | |
868 | if (alia s != null) { | |
869 | X509 Certificat e[] certs = km.getCe rtificateC hain(alias ); | |
870 | if ( (certs != null) && ( certs.leng th != 0)) { | |
871 | PublicKey publicKey = certs[0] .getPublic Key(); | |
872 | if (public Key != nul l) { | |
873 | m1 = n ew Certifi cateMsg(ce rts); | |
874 | signin gKey = km. getPrivate Key(alias) ; | |
875 | sessio n.setLocal PrivateKey (signingKe y); | |
876 | sessio n.setLocal Certificat es(certs); | |
877 | } | |
878 | } | |
879 | } | |
880 | if (m1 = = null) { | |
881 | // | |
882 | // N o appropri ate cert w as found . .. report this to th e | |
883 | // s erver. Fo r SSLv3, s end the no _certifica te alert; | |
884 | // T LS uses an empty cer t chain in stead. | |
885 | // | |
886 | if ( protocolVe rsion.v >= ProtocolV ersion.TLS 10.v) { | |
887 | m1 = new C ertificate Msg(new X5 09Certific ate [0]); | |
888 | } el se { | |
889 | warningSE( Alerts.ale rt_no_cert ificate); | |
890 | } | |
891 | if ( debug != n ull && Deb ug.isOn("h andshake") ) { | |
892 | System.out .println( | |
893 | "Warni ng: no sui table cert ificate fo und - " + | |
894 | "conti nuing with out client authentic ation"); | |
895 | } | |
896 | } | |
897 | ||
898 | // | |
899 | // At la st ... sen d any clie nt certifi cate chain . | |
900 | // | |
901 | if (m1 ! = null) { | |
902 | if ( debug != n ull && Deb ug.isOn("h andshake") ) { | |
903 | m1.print(S ystem.out) ; | |
904 | } | |
905 | m1.w rite(outpu t); | |
906 | } | |
907 | } | |
908 | ||
909 | /* | |
910 | * SECOND .. . send the client ke y exchange message. The | |
911 | * procedure used is a function of the cip her suite selected; | |
912 | * one is al ways neede d. | |
913 | * / | |
914 | Ha ndshakeMes sage m2; | |
915 | ||
916 | sw itch (keyE xchange) { | |
917 | ||
918 | ca se K_RSA: | |
919 | ca se K_RSA_E XPORT: | |
920 | if (serv erKey == n ull) { | |
921 | thro w new SSLP rotocolExc eption | |
922 | ("Serv er did not send cert ificate me ssage"); | |
923 | } | |
924 | ||
925 | if (!(se rverKey in stanceof R SAPublicKe y)) { | |
926 | thro w new SSLP rotocolExc eption | |
927 | ("Serv er certifi cate does not includ e an RSA k ey"); | |
928 | } | |
929 | ||
930 | /* | |
931 | * For R SA key exc hange, we randomly g enerate a new | |
932 | * pre-mast er PW and encryp t it with the server 's | |
933 | * public k ey. Then we sa ve that pr e-master PW | |
934 | * so th at we can calculate the keying data late r; | |
935 | * it's a performa nce speedu p not to d o that unt il | |
936 | * the c lient's wa iting for the server response, but | |
937 | * more of a speed up for the D-H case. | |
938 | * | |
939 | * If th e RSA_EXPO RT scheme is active, when the public | |
940 | * key i n the serv er certifi cate is le ss than or equal | |
941 | * to 51 2 bits in length, us e the cert 's public key, | |
942 | * other wise, the ephemeral one. | |
943 | */ | |
944 | PublicKe y key; | |
945 | if (keyE xchange == K_RSA) { | |
946 | key = serverKe y; | |
947 | } else { // K_R SA_EXPORT | |
948 | if ( JsseJce.ge tRSAKeyLen gth(server Key) <= 51 2) { | |
949 | // extrane ous epheme ralServerK ey check d one | |
950 | // above i n processM essage() | |
951 | key = serv erKey; | |
952 | } el se { | |
953 | if (epheme ralServerK ey == null ) { | |
954 | throw new SSLPro tocolExcep tion("Serv er did not send" + | |
955 | " a RSA_EXPO RT Server Key Exchan ge message "); | |
956 | } | |
957 | key = ephe meralServe rKey; | |
958 | } | |
959 | } | |
960 | ||
961 | m2 = new RSAClient KeyExchang e(protocol Version, m axProtocol Version, | |
962 | sslConte xt.getSecu reRandom() , key); | |
963 | break; | |
964 | ca se K_DH_RS A: | |
965 | ca se K_DH_DS S: | |
966 | /* | |
967 | * For D H Key exch ange, we o nly need t o make sur e the serv er | |
968 | * knows our publi c key, so we calcula te the sam e pre-mast er | |
969 | * PW . | |
970 | * | |
971 | * For c erts that had DH key s in them, we send a n empty | |
972 | * hands hake messa ge (no key ) ... we f lag this c ase by | |
973 | * passi ng a null "dhPublic" value. | |
974 | * | |
975 | * Other wise we se nd ephemer al DH keys , unsigned . | |
976 | */ | |
977 | // if (u seDH_RSA | | useDH_DS S) | |
978 | m2 = new DHClientK eyExchange (); | |
979 | break; | |
980 | ca se K_DHE_R SA: | |
981 | ca se K_DHE_D SS: | |
982 | ca se K_DH_AN ON: | |
983 | if (dh = = null) { | |
984 | thro w new SSLP rotocolExc eption | |
985 | ("Server d id not sen d a DH Ser ver Key Ex change mes sage"); | |
986 | } | |
987 | m2 = new DHClientK eyExchange (dh.getPub licKey()); | |
988 | break; | |
989 | ca se K_ECDHE _RSA: | |
990 | ca se K_ECDHE _ECDSA: | |
991 | ca se K_ECDH_ ANON: | |
992 | if (ecdh == null) { | |
993 | thro w new SSLP rotocolExc eption | |
994 | ("Server d id not sen d a ECDH S erver Key Exchange m essage"); | |
995 | } | |
996 | m2 = new ECDHClien tKeyExchan ge(ecdh.ge tPublicKey ()); | |
997 | break; | |
998 | ca se K_ECDH_ RSA: | |
999 | ca se K_ECDH_ ECDSA: | |
1000 | if (serv erKey == n ull) { | |
1001 | thro w new SSLP rotocolExc eption | |
1002 | ("Serv er did not send cert ificate me ssage"); | |
1003 | } | |
1004 | if (serv erKey inst anceof ECP ublicKey = = false) { | |
1005 | thro w new SSLP rotocolExc eption | |
1006 | ("Serv er certifi cate does not includ e an EC ke y"); | |
1007 | } | |
1008 | ECParame terSpec pa rams = ((E CPublicKey )serverKey ).getParam s(); | |
1009 | ecdh = n ew ECDHCry pt(params, sslContex t.getSecur eRandom()) ; | |
1010 | m2 = new ECDHClien tKeyExchan ge(ecdh.ge tPublicKey ()); | |
1011 | break; | |
1012 | ca se K_KRB5: | |
1013 | ca se K_KRB5_ EXPORT: | |
1014 | String s niHostname = null; | |
1015 | for (SNI ServerName serverNam e : reques tedServerN ames) { | |
1016 | if ( serverName instanceo f SNIHostN ame) { | |
1017 | sniHostnam e = ((SNIH ostName) s erverName) .getAsciiN ame(); | |
1018 | break; | |
1019 | } | |
1020 | } | |
1021 | ||
1022 | Kerberos ClientKeyE xchange ke rberosMsg = null; | |
1023 | if (sniH ostname != null) { | |
1024 | // u se first r equested S NI hostnam e | |
1025 | try { | |
1026 | kerberosMs g = new Ke rberosClie ntKeyExcha nge( | |
1027 | sniHos tname, get AccSE(), p rotocolVer sion, | |
1028 | sslCon text.getSe cureRandom ()); | |
1029 | } ca tch(IOExce ption e) { | |
1030 | if (server NamesAccep ted) { | |
1031 | // ser ver accept ed request ed SNI hos tname, | |
1032 | // so it must be used | |
1033 | throw e; | |
1034 | } | |
1035 | // fallbac k to using hostname | |
1036 | if (debug != null && Debug.isO n("handsha ke")) { | |
1037 | System .out.print ln( | |
1038 | "W arning, ca nnot use S erver Name Indicatio n: " | |
1039 | + e.getM essage()); | |
1040 | } | |
1041 | } | |
1042 | } | |
1043 | ||
1044 | if (kerb erosMsg == null) { | |
1045 | Stri ng hostnam e = getHos tSE(); | |
1046 | if ( hostname = = null) { | |
1047 | throw new IOExceptio n("Hostnam e is requi red" + | |
1048 | " to u se Kerbero s cipher s uites"); | |
1049 | } | |
1050 | kerb erosMsg = new Kerber osClientKe yExchange( | |
1051 | hostname, getAccSE( ), protoco lVersion, | |
1052 | sslContex t.getSecur eRandom()) ; | |
1053 | } | |
1054 | ||
1055 | // Recor d the prin cipals inv olved in e xchange | |
1056 | session. setPeerPri ncipal(ker berosMsg.g etPeerPrin cipal()); | |
1057 | session. setLocalPr incipal(ke rberosMsg. getLocalPr incipal()) ; | |
1058 | m2 = ker berosMsg; | |
1059 | break; | |
1060 | de fault: | |
1061 | // somet hings very wrong | |
1062 | throw ne w RuntimeE xception | |
1063 | ("Unsupp orted key exchange: " + keyExc hange); | |
1064 | } | |
1065 | if (debug != null && D ebug.isOn( "handshake ")) { | |
1066 | m2.print (System.ou t); | |
1067 | } | |
1068 | m2 .write(out put); | |
1069 | ||
1070 | ||
1071 | /* | |
1072 | * THIRD, se nd a "chan ge_cipher_ spec" reco rd followe d by the | |
1073 | * "Finished " message. We flush the messa ges we've queued up, to | |
1074 | * get concu rrency bet ween clien t and serv er. The c oncurrency is | |
1075 | * useful a s we calcu late the m aster PW , which is needed bo th | |
1076 | * to comput e the "Fin ished" mes sage, and to compute the keys used | |
1077 | * to protec t all reco rds follow ing the ch ange_ciphe r_spec. | |
1078 | * / | |
1079 | ||
1080 | ou tput.doHas hes(); | |
1081 | ou tput.flush (); | |
1082 | ||
1083 | /* | |
1084 | * We defer red calcul ating the master PW and this c onnection' s | |
1085 | * keying da ta; we do it now. D eferring t his calcul ation is g ood | |
1086 | * from a pe rformance point of v iew, since it lets u s do it du ring | |
1087 | * some time that netw ork delays and the s erver's ow n calculat ions | |
1088 | * would oth erwise cau se to be " dead" in t he critica l path. | |
1089 | * / | |
1090 | Se cretKey pr eMasterSec ret; | |
1091 | sw itch (keyE xchange) { | |
1092 | ca se K_RSA: | |
1093 | ca se K_RSA_E XPORT: | |
1094 | preMaste rSecret = ((RSAClien tKeyExchan ge)m2).pre Master; | |
1095 | break; | |
1096 | ca se K_KRB5: | |
1097 | ca se K_KRB5_ EXPORT: | |
1098 | byte[] PW Bytes = | |
1099 | ((Ke rberosClie ntKeyExcha nge)m2).ge tUnencrypt edPreMaste rSecret(); | |
1100 | preMasterS ecret = ne w SecretKe ySpec( PW Bytes, | |
1101 | "Tls PremasterS ecret"); | |
1102 | break; | |
1103 | ca se K_DHE_R SA: | |
1104 | ca se K_DHE_D SS: | |
1105 | ca se K_DH_AN ON: | |
1106 | preMaste rSecret = dh.getAgre edSecret(s erverDH, t rue); | |
1107 | break; | |
1108 | ca se K_ECDHE _RSA: | |
1109 | ca se K_ECDHE _ECDSA: | |
1110 | ca se K_ECDH_ ANON: | |
1111 | preMaste rSecret = ecdh.getAg reedSecret (ephemeral ServerKey) ; | |
1112 | break; | |
1113 | ca se K_ECDH_ RSA: | |
1114 | ca se K_ECDH_ ECDSA: | |
1115 | preMaste rSecret = ecdh.getAg reedSecret (serverKey ); | |
1116 | break; | |
1117 | de fault: | |
1118 | throw ne w IOExcept ion("Inter nal error: unknown k ey exchang e " | |
1119 | + ke yExchange) ; | |
1120 | } | |
1121 | ||
1122 | ca lculateKey s(preMaste rSecret, n ull); | |
1123 | ||
1124 | /* | |
1125 | * FOURTH, i f we sent a Certific ate, we ne ed to send a signed | |
1126 | * Certifica teVerify ( unless the key in th e client's certifica te | |
1127 | * was a Dif fie-Hellma n key).). | |
1128 | * | |
1129 | * This uses a hash of the previ ous handsh ake messag es ... eit her | |
1130 | * a nonfina l one (if the partic ular imple mentation supports i t) | |
1131 | * or else u sing the t hird eleme nt in the arrays of hashes bei ng | |
1132 | * computed. | |
1133 | * / | |
1134 | if (signingK ey != null ) { | |
1135 | Certific ateVerify m3; | |
1136 | try { | |
1137 | Sign atureAndHa shAlgorith m preferab leSignatur eAlgorithm = null; | |
1138 | if ( protocolVe rsion.v >= ProtocolV ersion.TLS 12.v) { | |
1139 | preferable SignatureA lgorithm = | |
1140 | Signat ureAndHash Algorithm. getPrefera bleAlgorit hm( | |
1141 | ge tPeerSuppo rtedSignAl gs(), | |
1142 | si gningKey.g etAlgorith m(), signi ngKey); | |
1143 | ||
1144 | if (prefer ableSignat ureAlgorit hm == null ) { | |
1145 | throw new SSLHan dshakeExce ption( | |
1146 | "N o supporte d signatur e algorith m"); | |
1147 | } | |
1148 | ||
1149 | String has hAlg = | |
1150 | Signat ureAndHash Algorithm. getHashAlg orithmName ( | |
1151 | preferab leSignatur eAlgorithm ); | |
1152 | if (hashAl g == null || hashAlg .length() == 0) { | |
1153 | throw new SSLHan dshakeExce ption( | |
1154 | "No supp orted hash algorithm "); | |
1155 | } | |
1156 | } | |
1157 | ||
1158 | m3 = new Certi ficateVeri fy(protoco lVersion, handshakeH ash, | |
1159 | signingKey , session. getMasterS ecret(), | |
1160 | sslContext .getSecure Random(), | |
1161 | preferable SignatureA lgorithm); | |
1162 | } catch (GeneralSe curityExce ption e) { | |
1163 | fata lSE(Alerts .alert_han dshake_fai lure, | |
1164 | "Error sig ning certi ficate ver ify", e); | |
1165 | // N OTREACHED, make comp iler happy | |
1166 | m3 = null; | |
1167 | } | |
1168 | if (debu g != null && Debug.i sOn("hands hake")) { | |
1169 | m3.p rint(Syste m.out); | |
1170 | } | |
1171 | m3.write (output); | |
1172 | output.d oHashes(); | |
1173 | } | |
1174 | ||
1175 | /* | |
1176 | * OK, that' s that! | |
1177 | * / | |
1178 | se ndChangeCi pherAndFin ish(false) ; | |
1179 | } | |
1180 | ||
1181 | ||
1182 | /* | |
1183 | * "Fi nished" is the last handshake message se nt. If we got this | |
1184 | * far , the MAC has been v alidated p ost-decryp tion. We validate | |
1185 | * the two hashe s here as an additio nal sanity check, pr otecting | |
1186 | * the handshake against v arious act ive attack s. | |
1187 | */ | |
1188 | privat e void ser verFinishe d(Finished mesg) thr ows IOExce ption { | |
1189 | if (debug != null && D ebug.isOn( "handshake ")) { | |
1190 | mesg.pri nt(System. out); | |
1191 | } | |
1192 | ||
1193 | bo olean veri fied = mes g.verify(h andshakeHa sh, Finish ed.SERVER, | |
1194 | session. getMasterS ecret()); | |
1195 | ||
1196 | if (!verifie d) { | |
1197 | fatalSE( Alerts.ale rt_illegal _parameter , | |
1198 | "server 'finished ' message doesn't ve rify"); | |
1199 | // NOTRE ACHED | |
1200 | } | |
1201 | ||
1202 | /* | |
1203 | * save serv er verify data for s ecure rene gotiation | |
1204 | * / | |
1205 | if (secureRe negotiatio n) { | |
1206 | serverVe rifyData = mesg.getV erifyData( ); | |
1207 | } | |
1208 | ||
1209 | /* | |
1210 | * Reset the handshake state if this is no t an initi al handsha ke. | |
1211 | * / | |
1212 | if (!isIniti alHandshak e) { | |
1213 | session. setAsSessi onResumpti on(false); | |
1214 | } | |
1215 | ||
1216 | /* | |
1217 | * OK, it ve rified. I f we're do ing the fa st handsha ke, add th at | |
1218 | * "Finished " message to the has h of hands hake messa ges, then send | |
1219 | * our own c hange_ciph er_spec an d Finished message f or the ser ver | |
1220 | * to verify in turn. These are the last handshake messages. | |
1221 | * | |
1222 | * In any ca se, update the sessi on cache. We're don e handshak ing, | |
1223 | * so there are no thr eats any m ore associ ated with partially | |
1224 | * completed handshake s. | |
1225 | * / | |
1226 | if (resuming Session) { | |
1227 | input.di gestNow(); | |
1228 | sendChan geCipherAn dFinish(tr ue); | |
1229 | } | |
1230 | se ssion.setL astAccesse dTime(Syst em.current TimeMillis ()); | |
1231 | ||
1232 | if (!resumin gSession) { | |
1233 | if (sess ion.isRejo inable()) { | |
1234 | ((SS LSessionCo ntextImpl) sslContex t | |
1235 | .engin eGetClient SessionCon text()) | |
1236 | .put(s ession); | |
1237 | if ( debug != n ull && Deb ug.isOn("s ession")) { | |
1238 | System.out .println(" %% Cached client ses sion: " + session); | |
1239 | } | |
1240 | } else i f (debug ! = null && Debug.isOn ("session" )) { | |
1241 | Syst em.out.pri ntln( | |
1242 | "%% Didn't cache non -resumable client se ssion: " | |
1243 | + session) ; | |
1244 | } | |
1245 | } | |
1246 | } | |
1247 | ||
1248 | ||
1249 | /* | |
1250 | * Sen d my chang e-cipher-s pec and Fi nished mes sage ... d one as the | |
1251 | * las t handshak e act in e ither the short or l ong sequen ces. In | |
1252 | * the short one , we've al ready seen the serve r's Finish ed; in the | |
1253 | * lon g one, we wait for i t now. | |
1254 | */ | |
1255 | privat e void sen dChangeCip herAndFini sh(boolean finishedT ag) | |
1256 | throws I OException { | |
1257 | Fi nished mes g = new Fi nished(pro tocolVersi on, handsh akeHash, | |
1258 | Finished .CLIENT, s ession.get MasterSecr et(), ciph erSuite); | |
1259 | ||
1260 | /* | |
1261 | * Send the change_cip her_spec m essage, th en the Fin ished mess age | |
1262 | * which we just calcu lated (and protected using the keys we j ust | |
1263 | * calculate d). Serve r responds with its Finished m essage, ex cept | |
1264 | * in the "f ast handsh ake" (resu me session ) case. | |
1265 | * / | |
1266 | se ndChangeCi pherSpec(m esg, finis hedTag); | |
1267 | ||
1268 | /* | |
1269 | * save clie nt verify data for s ecure rene gotiation | |
1270 | * / | |
1271 | if (secureRe negotiatio n) { | |
1272 | clientVe rifyData = mesg.getV erifyData( ); | |
1273 | } | |
1274 | ||
1275 | /* | |
1276 | * Update st ate machin e so serve r MUST sen d 'finishe d' next. | |
1277 | * (In "long " handshak e case; in short cas e, we're r esponding | |
1278 | * to its me ssage.) | |
1279 | * / | |
1280 | st ate = Hand shakeMessa ge.ht_fini shed - 1; | |
1281 | } | |
1282 | ||
1283 | ||
1284 | /* | |
1285 | * Ret urns a Cli entHello m essage to kickstart renegotiat ions | |
1286 | */ | |
1287 | @Overr ide | |
1288 | Handsh akeMessage getKickst artMessage () throws SSLExcepti on { | |
1289 | // session I D of the C lientHello message | |
1290 | Se ssionId se ssionId = SSLSession Impl.nullS ession.get SessionId( ); | |
1291 | ||
1292 | // a list of cipher su ites sent by the cli ent | |
1293 | Ci pherSuiteL ist cipher Suites = g etActiveCi pherSuites (); | |
1294 | ||
1295 | // set the m ax protoco l version this clien t is suppo rting. | |
1296 | ma xProtocolV ersion = p rotocolVer sion; | |
1297 | ||
1298 | // | |
1299 | // Try to re sume an ex isting ses sion. Thi s might be mandatory , | |
1300 | // given cer tain API o ptions. | |
1301 | // | |
1302 | se ssion = (( SSLSession ContextImp l)sslConte xt | |
1303 | .engin eGetClient SessionCon text()) | |
1304 | .get(g etHostSE() , getPortS E()); | |
1305 | if (debug != null && D ebug.isOn( "session") ) { | |
1306 | if (sess ion != nul l) { | |
1307 | Syst em.out.pri ntln("%% C lient cach ed " | |
1308 | + session | |
1309 | + (session .isRejoina ble() ? "" : " (not rejoinable )")); | |
1310 | } else { | |
1311 | Syst em.out.pri ntln("%% N o cached c lient sess ion"); | |
1312 | } | |
1313 | } | |
1314 | if (session != null) { | |
1315 | // If un safe serve r certific ate change is not al lowed, res erve | |
1316 | // curre nt server certificat es if the previous h andshake i s a | |
1317 | // sessi on-resumpt ion abbrev iated init ial handsh ake. | |
1318 | if (!all owUnsafeSe rverCertCh ange && se ssion.isSe ssionResum ption()) { | |
1319 | try { | |
1320 | // If exis ting, peer certifica te chain c annot be n ull. | |
1321 | reservedSe rverCerts = | |
1322 | (X509C ertificate [])session .getPeerCe rtificates (); | |
1323 | } ca tch (SSLPe erUnverifi edExceptio n puve) { | |
1324 | // Maybe n ot certifi cate-based , ignore t he excepti on. | |
1325 | } | |
1326 | } | |
1327 | ||
1328 | if (!ses sion.isRej oinable()) { | |
1329 | sess ion = null ; | |
1330 | } | |
1331 | } | |
1332 | ||
1333 | if (session != null) { | |
1334 | CipherSu ite sessio nSuite = s ession.get Suite(); | |
1335 | Protocol Version se ssionVersi on = sessi on.getProt ocolVersio n(); | |
1336 | if (isNe gotiable(s essionSuit e) == fals e) { | |
1337 | if ( debug != n ull && Deb ug.isOn("s ession")) { | |
1338 | System.out .println(" %% can't r esume, una vailable c ipher"); | |
1339 | } | |
1340 | sess ion = null ; | |
1341 | } | |
1342 | ||
1343 | if ((ses sion != nu ll) && !is Negotiable (sessionVe rsion)) { | |
1344 | if ( debug != n ull && Deb ug.isOn("s ession")) { | |
1345 | System.out .println(" %% can't r esume, pro tocol disa bled"); | |
1346 | } | |
1347 | sess ion = null ; | |
1348 | } | |
1349 | ||
1350 | if ((ses sion != nu ll) && use ExtendedMa sterSecret ) { | |
1351 | bool ean isTLS1 0Plus = se ssionVersi on.v >= Pr otocolVers ion.TLS10. v; | |
1352 | if ( isTLS10Plu s && !sess ion.getUse ExtendedMa sterSecret ()) { | |
1353 | if (!allow LegacyResu mption) { | |
1354 | // per form full handshake instead | |
1355 | // | |
1356 | // The client SH OULD NOT o ffer an ab breviated handshake | |
1357 | // to resume a s ession tha t does not use an ex tended | |
1358 | // master PW . Instead, i t SHOULD o ffer a ful l | |
1359 | // han dshake. | |
1360 | sessio n = null; | |
1361 | } | |
1362 | } | |
1363 | ||
1364 | if ( (session ! = null) && !allowUns afeServerC ertChange) { | |
1365 | // It is f ine to mov e on with abbreviate handshake if | |
1366 | // endpoin t identifi cation is enabled. | |
1367 | String ide ntityAlg = getEndpoi ntIdentifi cationAlgo rithmSE(); | |
1368 | if ((ident ityAlg == null || id entityAlg. length() = = 0)) { | |
1369 | if (is TLS10Plus) { | |
1370 | if (!session .getUseExt endedMaste rSecret()) { | |
1371 | // perfo rm full ha ndshake in stead | |
1372 | session = null; | |
1373 | } // Otherwi se, use ex tended mas ter PW . | |
1374 | } else { | |
1375 | // The ext ended mast er PW extension does not | |
1376 | // apply to SSL 3.0. Perform a full hands hake | |
1377 | // instead. | |
1378 | // | |
1379 | // Note that the useEx tendedMast erSecret i s | |
1380 | // extended to protect SSL 3.0 c onnections , | |
1381 | // by discar ding abbre viate hand shake. | |
1382 | se ssion = nu ll; | |
1383 | } | |
1384 | } | |
1385 | } | |
1386 | } | |
1387 | ||
1388 | if (sess ion != nul l) { | |
1389 | if ( debug != n ull) { | |
1390 | if (Debug. isOn("hand shake") || Debug.isO n("session ")) { | |
1391 | System .out.print ln("%% Try resuming " + sessio n | |
1392 | + " from por t " + getL ocalPortSE ()); | |
1393 | } | |
1394 | } | |
1395 | ||
1396 | sess ionId = se ssion.getS essionId() ; | |
1397 | maxP rotocolVer sion = ses sionVersio n; | |
1398 | ||
1399 | // U pdate SSL version nu mber in un derlying S SL socket and | |
1400 | // h andshake o utput stre am, so tha t the outp ut records (at the | |
1401 | // r ecord laye r) have th e correct version | |
1402 | setV ersion(ses sionVersio n); | |
1403 | } | |
1404 | ||
1405 | /* | |
1406 | * Force use of th e previous session c iphersuite , and | |
1407 | * add t he SCSV if enabled. | |
1408 | */ | |
1409 | if (!ena bleNewSess ion) { | |
1410 | if ( session == null) { | |
1411 | throw new SSLHandsha keExceptio n( | |
1412 | "Can't reuse exi sting SSL client ses sion"); | |
1413 | } | |
1414 | ||
1415 | Coll ection<Cip herSuite> cipherList = new Arr ayList<>(2 ); | |
1416 | ciph erList.add (sessionSu ite); | |
1417 | if ( !secureRen egotiation && | |
1418 | cipher Suites.con tains(Ciph erSuite.C_ SCSV)) { | |
1419 | cipherList .add(Ciphe rSuite.C_S CSV); | |
1420 | } // otherwi se, renego tiation_in fo extensi on will be used | |
1421 | ||
1422 | ciph erSuites = new Ciphe rSuiteList (cipherLis t); | |
1423 | } | |
1424 | } | |
1425 | ||
1426 | if (session == null && !enableNe wSession) { | |
1427 | throw ne w SSLHands hakeExcept ion("No ex isting ses sion to re sume"); | |
1428 | } | |
1429 | ||
1430 | // exclude S CSV for se cure reneg otiation | |
1431 | if (secureRe negotiatio n && ciphe rSuites.co ntains(Cip herSuite.C _SCSV)) { | |
1432 | Collecti on<CipherS uite> ciph erList = | |
1433 | new Ar rayList<>( cipherSuit es.size() - 1); | |
1434 | for (Cip herSuite s uite : cip herSuites. collection ()) { | |
1435 | if ( suite != C ipherSuite .C_SCSV) { | |
1436 | cipherList .add(suite ); | |
1437 | } | |
1438 | } | |
1439 | ||
1440 | cipherSu ites = new CipherSui teList(cip herList); | |
1441 | } | |
1442 | ||
1443 | // make sure there is a negotiab le cipher suite. | |
1444 | bo olean nego tiable = f alse; | |
1445 | fo r (CipherS uite suite : cipherS uites.coll ection()) { | |
1446 | if (isNe gotiable(s uite)) { | |
1447 | nego tiable = t rue; | |
1448 | brea k; | |
1449 | } | |
1450 | } | |
1451 | ||
1452 | if (!negotia ble) { | |
1453 | throw ne w SSLHands hakeExcept ion("No ne gotiable c ipher suit e"); | |
1454 | } | |
1455 | ||
1456 | // Not a TLS 1.2+ hands hake | |
1457 | // For SSLv2 Hello, Han dshakeHash .reset() w ill be cal led, so we | |
1458 | // cannot ca ll Handsha keHash.pro tocolDeter mined() he re. As it does | |
1459 | // not follo w the spec that Hand shakeHash. reset() ca n be only be | |
1460 | // called be fore proto colDetermi ned. | |
1461 | // if (maxPr otocolVers ion.v < Pr otocolVers ion.TLS12. v) { | |
1462 | // hands hakeHash.p rotocolDet ermined(ma xProtocolV ersion); | |
1463 | // } | |
1464 | ||
1465 | // create th e ClientHe llo messag e | |
1466 | Cl ientHello clientHell oMessage = new Clien tHello( | |
1467 | sslC ontext.get SecureRand om(), maxP rotocolVer sion, | |
1468 | sess ionId, cip herSuites) ; | |
1469 | ||
1470 | // add ellip tic curves and point format ex tensions | |
1471 | if (cipherSu ites.conta insEC()) { | |
1472 | Elliptic CurvesExte nsion ece = | |
1473 | Elli pticCurves Extension. createExte nsion(algo rithmConst raints); | |
1474 | if (ece != null) { | |
1475 | clie ntHelloMes sage.exten sions.add( ece); | |
1476 | clie ntHelloMes sage.exten sions.add( | |
1477 | E llipticPoi ntFormatsE xtension.D EFAULT); | |
1478 | } | |
1479 | } | |
1480 | ||
1481 | // add signa ture_algor ithm exten sion | |
1482 | if (maxProto colVersion .v >= Prot ocolVersio n.TLS12.v) { | |
1483 | // we wi ll always send the s ignature_a lgorithm e xtension | |
1484 | Collecti on<Signatu reAndHashA lgorithm> localSignA lgs = | |
1485 | ge tLocalSupp ortedSignA lgs(); | |
1486 | if (loca lSignAlgs. isEmpty()) { | |
1487 | thro w new SSLH andshakeEx ception( | |
1488 | "N o supporte d signatur e algorith m"); | |
1489 | } | |
1490 | ||
1491 | clientHe lloMessage .addSignat ureAlgorit hmsExtensi on(localSi gnAlgs); | |
1492 | } | |
1493 | ||
1494 | // add Exten ded Master Secret ex tension | |
1495 | if (useExten dedMasterS ecret && ( maxProtoco lVersion.v >= Protoc olVersion. TLS10.v)) { | |
1496 | if ((ses sion == nu ll) || ses sion.getUs eExtendedM asterSecre t()) { | |
1497 | clie ntHelloMes sage.addEx tendedMast erSecretEx tension(); | |
1498 | requ estedToUse EMS = true ; | |
1499 | } | |
1500 | } | |
1501 | ||
1502 | // add serve r_name ext ension | |
1503 | if (enableSN IExtension ) { | |
1504 | if (sess ion != nul l) { | |
1505 | requ estedServe rNames = s ession.get RequestedS erverNames (); | |
1506 | } else { | |
1507 | requ estedServe rNames = s erverNames ; | |
1508 | } | |
1509 | ||
1510 | if (!req uestedServ erNames.is Empty()) { | |
1511 | clie ntHelloMes sage.addSN IExtension (requested ServerName s); | |
1512 | } | |
1513 | } | |
1514 | ||
1515 | // reset the client ra ndom cooki e | |
1516 | cl nt_random = clientHe lloMessage .clnt_rand om; | |
1517 | ||
1518 | /* | |
1519 | * need to s et the ren egotiation _info exte nsion for: | |
1520 | * 1: secure renegotia tion | |
1521 | * 2: initia l handshak e and no S CSV in the ClientHel lo | |
1522 | * 3: insecu re renegot iation and no SCSV i n the Clie ntHello | |
1523 | * / | |
1524 | if (secureRe negotiatio n || | |
1525 | !cip herSuites. contains(C ipherSuite .C_SCSV)) { | |
1526 | clientHe lloMessage .addRenego tiationInf oExtension (clientVer ifyData); | |
1527 | } | |
1528 | ||
1529 | re turn clien tHelloMess age; | |
1530 | } | |
1531 | ||
1532 | /* | |
1533 | * Fau lt detecte d during h andshake. | |
1534 | */ | |
1535 | @Overr ide | |
1536 | void h andshakeAl ert(byte d escription ) throws S SLProtocol Exception { | |
1537 | St ring messa ge = Alert s.alertDes cription(d escription ); | |
1538 | ||
1539 | if (debug != null && D ebug.isOn( "handshake ")) { | |
1540 | System.o ut.println ("SSL - ha ndshake al ert: " + m essage); | |
1541 | } | |
1542 | th row new SS LProtocolE xception(" handshake alert: " + message) ; | |
1543 | } | |
1544 | ||
1545 | /* | |
1546 | * Unl ess we are using an anonymous ciphersuit e, the ser ver always | |
1547 | * sen ds a certi ficate mes sage (for the Cipher Suites we currently | |
1548 | * sup port). The trust man ager verif ies the ch ain for us . | |
1549 | */ | |
1550 | privat e void ser verCertifi cate(Certi ficateMsg mesg) thro ws IOExcep tion { | |
1551 | if (debug != null && D ebug.isOn( "handshake ")) { | |
1552 | mesg.pri nt(System. out); | |
1553 | } | |
1554 | X5 09Certific ate[] peer Certs = me sg.getCert ificateCha in(); | |
1555 | if (peerCert s.length = = 0) { | |
1556 | fatalSE( Alerts.ale rt_bad_cer tificate, "empty cer tificate c hain"); | |
1557 | } | |
1558 | ||
1559 | // Allow ser ver certif icate chan ge in clie nt side du ring reneg otiation | |
1560 | // after a s ession-res umption ab breviated initial ha ndshake? | |
1561 | // | |
1562 | // DO NOT ne ed to chec k allowUns afeServerC ertChange here. We only | |
1563 | // reserve s erver cert ificates w hen allowU nsafeServe rCertChang e is | |
1564 | // flase. | |
1565 | // | |
1566 | // Allow ser ver certif icate chan ge if it i s negotiat ed to use the | |
1567 | // extende d master PW . | |
1568 | if ((reserve dServerCer ts != null ) && | |
1569 | !ses sion.getUs eExtendedM asterSecre t()) { | |
1570 | // It is not neces sary to ch eck the ce rtificate update if endpoint | |
1571 | // ident ification is enabled . | |
1572 | String i dentityAlg = getEndp ointIdenti ficationAl gorithmSE( ); | |
1573 | if ((ide ntityAlg = = null || identityAl g.length() == 0) && | |
1574 | !isI dentityEqu ivalent(pe erCerts[0] , reserved ServerCert s[0])) { | |
1575 | ||
1576 | fata lSE(Alerts .alert_bad _certifica te, | |
1577 | "serve r certific ate change is restri cted " + | |
1578 | "durin g renegoti ation"); | |
1579 | } | |
1580 | } | |
1581 | ||
1582 | // ask the t rust manag er to veri fy the cha in | |
1583 | X5 09TrustMan ager tm = sslContext .getX509Tr ustManager (); | |
1584 | tr y { | |
1585 | // find out the ke y exchange algorithm used | |
1586 | // use " RSA" for n on-ephemer al "RSA_EX PORT" | |
1587 | String k eyExchange String; | |
1588 | if (keyE xchange == K_RSA_EXP ORT && !se rverKeyExc hangeRecei ved) { | |
1589 | keyE xchangeStr ing = K_RS A.name; | |
1590 | } else { | |
1591 | keyE xchangeStr ing = keyE xchange.na me; | |
1592 | } | |
1593 | ||
1594 | if (tm i nstanceof X509Extend edTrustMan ager) { | |
1595 | if ( conn != nu ll) { | |
1596 | ((X509Exte ndedTrustM anager)tm) .checkServ erTrusted( | |
1597 | peerCe rts.clone( ), | |
1598 | keyExc hangeStrin g, | |
1599 | conn); | |
1600 | } el se { | |
1601 | ((X509Exte ndedTrustM anager)tm) .checkServ erTrusted( | |
1602 | peerCe rts.clone( ), | |
1603 | keyExc hangeStrin g, | |
1604 | engine ); | |
1605 | } | |
1606 | } else { | |
1607 | // U nlikely to happen, b ecause we have wrapp ed the old | |
1608 | // X 509TrustMa nager with the new X 509Extende dTrustMana ger. | |
1609 | thro w new Cert ificateExc eption( | |
1610 | "Improper X509TrustM anager imp lementatio n"); | |
1611 | } | |
1612 | } catch (Cer tificateEx ception e) { | |
1613 | // This will throw an except ion, so in clude the original e rror. | |
1614 | fatalSE( Alerts.ale rt_certifi cate_unkno wn, e); | |
1615 | } | |
1616 | se ssion.setP eerCertifi cates(peer Certs); | |
1617 | } | |
1618 | ||
1619 | /* | |
1620 | * Whe ther the c ertificate s can repr esent the same ident ity? | |
1621 | * | |
1622 | * The certifica tes can be used to r epresent t he same id entity: | |
1623 | * 1. If the subject a lternative names of IP address are prese nt in | |
1624 | * both c ertificate s, they sh ould be id entical; o therwise, | |
1625 | * 2. if the subject a lternative names of DNS name a re present in | |
1626 | * both c ertificate s, they sh ould be id entical; o therwise, | |
1627 | * 3. if the subject f ields are present in both cert ificates, the | |
1628 | * certif icate subj ects and i ssuers sho uld be ide ntical. | |
1629 | */ | |
1630 | privat e static b oolean isI dentityEqu ivalent(X5 09Certific ate thisCe rt, | |
1631 | X509Cert ificate pr evCert) { | |
1632 | if (thisCert .equals(pr evCert)) { | |
1633 | return t rue; | |
1634 | } | |
1635 | ||
1636 | // check sub ject alter native nam es | |
1637 | Co llection<L ist<?>> th isSubjectA ltNames = null; | |
1638 | tr y { | |
1639 | thisSubj ectAltName s = thisCe rt.getSubj ectAlterna tiveNames( ); | |
1640 | } catch (Cer tificatePa rsingExcep tion cpe) { | |
1641 | if (debu g != null && Debug.i sOn("hands hake")) { | |
1642 | Syst em.out.pri ntln( | |
1643 | "Attem pt to obta in subject AltNames e xtension f ailed!"); | |
1644 | } | |
1645 | } | |
1646 | ||
1647 | Co llection<L ist<?>> pr evSubjectA ltNames = null; | |
1648 | tr y { | |
1649 | prevSubj ectAltName s = prevCe rt.getSubj ectAlterna tiveNames( ); | |
1650 | } catch (Cer tificatePa rsingExcep tion cpe) { | |
1651 | if (debu g != null && Debug.i sOn("hands hake")) { | |
1652 | Syst em.out.pri ntln( | |
1653 | "Attem pt to obta in subject AltNames e xtension f ailed!"); | |
1654 | } | |
1655 | } | |
1656 | ||
1657 | if ((thisSub jectAltNam es != null ) && (prev SubjectAlt Names != n ull)) { | |
1658 | // check the iPAdd ress field in subjec tAltName e xtension | |
1659 | Collecti on<String> thisSubAl tIPAddrs = | |
1660 | getSub jectAltNam es(thisSub jectAltNam es, ALTNAM E_IP); | |
1661 | Collecti on<String> prevSubAl tIPAddrs = | |
1662 | getSub jectAltNam es(prevSub jectAltNam es, ALTNAM E_IP); | |
1663 | if ((thi sSubAltIPA ddrs != nu ll) && (pr evSubAltIP Addrs != n ull) && | |
1664 | (isE quivalent( thisSubAlt IPAddrs, p revSubAltI PAddrs))) { | |
1665 | ||
1666 | retu rn true; | |
1667 | } | |
1668 | ||
1669 | // check the dNSNa me field i n subjectA ltName ext ension | |
1670 | Collecti on<String> thisSubAl tDnsNames = | |
1671 | getSub jectAltNam es(thisSub jectAltNam es, ALTNAM E_DNS); | |
1672 | Collecti on<String> prevSubAl tDnsNames = | |
1673 | getSub jectAltNam es(prevSub jectAltNam es, ALTNAM E_DNS); | |
1674 | if ((thi sSubAltDns Names != n ull) && (p revSubAltD nsNames != null) && | |
1675 | (isE quivalent( thisSubAlt DnsNames, prevSubAlt DnsNames)) ) { | |
1676 | ||
1677 | retu rn true; | |
1678 | } | |
1679 | } | |
1680 | ||
1681 | // check the certifica te subject and issue r | |
1682 | X5 00Principa l thisSubj ect = this Cert.getSu bjectX500P rincipal() ; | |
1683 | X5 00Principa l prevSubj ect = prev Cert.getSu bjectX500P rincipal() ; | |
1684 | X5 00Principa l thisIssu er = thisC ert.getIss uerX500Pri ncipal(); | |
1685 | X5 00Principa l prevIssu er = prevC ert.getIss uerX500Pri ncipal(); | |
1686 | if (!thisSub ject.getNa me().isEmp ty() && | |
1687 | !pre vSubject.g etName().i sEmpty() & & | |
1688 | this Subject.eq uals(prevS ubject) && | |
1689 | this Issuer.equ als(prevIs suer)) { | |
1690 | return t rue; | |
1691 | } | |
1692 | ||
1693 | re turn false ; | |
1694 | } | |
1695 | ||
1696 | /* | |
1697 | * Ret urns the s ubject alt ernative n ame of the specified type in t he | |
1698 | * sub jectAltNam es extensi on of a ce rtificate. | |
1699 | * | |
1700 | * Not e that onl y those su bjectAltNa me types t hat use St ring data | |
1701 | * sho uld be pas sed into t his functi on. | |
1702 | */ | |
1703 | privat e static C ollection< String> ge tSubjectAl tNames( | |
1704 | Collecti on<List<?> > subjectA ltNames, i nt type) { | |
1705 | ||
1706 | Ha shSet<Stri ng> subAlt DnsNames = null; | |
1707 | fo r (List<?> subjectAl tName : su bjectAltNa mes) { | |
1708 | int subj ectAltName Type = (In teger)subj ectAltName .get(0); | |
1709 | if (subj ectAltName Type == ty pe) { | |
1710 | Stri ng subAltD nsName = ( String)sub jectAltNam e.get(1); | |
1711 | if ( (subAltDns Name != nu ll) && !su bAltDnsNam e.isEmpty( )) { | |
1712 | if (subAlt DnsNames = = null) { | |
1713 | subAlt DnsNames = | |
1714 | new Hash Set<>(subj ectAltName s.size()); | |
1715 | } | |
1716 | subAltDnsN ames.add(s ubAltDnsNa me); | |
1717 | } | |
1718 | } | |
1719 | } | |
1720 | ||
1721 | re turn subAl tDnsNames; | |
1722 | } | |
1723 | ||
1724 | privat e static b oolean isE quivalent( Collection <String> t hisSubAltN ames, | |
1725 | Collecti on<String> prevSubAl tNames) { | |
1726 | ||
1727 | fo r (String thisSubAlt Name : thi sSubAltNam es) { | |
1728 | for (Str ing prevSu bAltName : prevSubAl tNames) { | |
1729 | // O nly allow the exactl y match. Check no w ildcard ch aracter. | |
1730 | if ( thisSubAlt Name.equal sIgnoreCas e(prevSubA ltName)) { | |
1731 | return tru e; | |
1732 | } | |
1733 | } | |
1734 | } | |
1735 | ||
1736 | re turn false ; | |
1737 | } | |
1738 | } |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.