Produced by Araxis Merge on 9/25/2018 2:13:26 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 | SSLSocketImpl.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 | SSLSocketImpl.java | Wed Sep 12 17:54:54 2018 UTC |
Description | Between Files 1 and 2 |
|
---|---|---|
Text Blocks | Lines | |
Unchanged | 2 | 5454 |
Changed | 1 | 2 |
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, 2016, 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 | ||
27 | package su n.security .ssl; | |
28 | ||
29 | import jav a.io.*; | |
30 | import jav a.net.*; | |
31 | import jav a.security .GeneralSe curityExce ption; | |
32 | import jav a.security .AccessCon troller; | |
33 | import jav a.security .AccessCon trolContex t; | |
34 | import jav a.security .Privilege dAction; | |
35 | import jav a.security .Algorithm Constraint s; | |
36 | import jav a.util.*; | |
37 | import jav a.util.con current.Ti meUnit; | |
38 | import jav a.util.con current.lo cks.Reentr antLock; | |
39 | ||
40 | import jav ax.crypto. BadPadding Exception; | |
41 | import jav ax.net.ssl .*; | |
42 | ||
43 | import sun .misc.Java NetAccess; | |
44 | import sun .misc.Shar edSecrets; | |
45 | ||
46 | /** | |
47 | * Impleme ntation of an SSL so cket. Thi s is a nor mal connec tion type | |
48 | * socket, implement ing SSL ov er some lo wer level socket, su ch as TCP. | |
49 | * Because it is lay ered over some lower level soc ket, it MU ST overrid e | |
50 | * all def ault socke t methods. | |
51 | * | |
52 | * <P> Thi s API offe rs a non-t raditional option fo r establis hing SSL | |
53 | * connect ions. You may first establish the conne ction dire ctly, then pass | |
54 | * that co nnection t o the SSL socket con structor w ith a flag saying wh ich | |
55 | * role sh ould be ta ken in the handshake protocol. (The two ends of t he | |
56 | * connect ion must n ot choose the same r ole!) Thi s allows s etup of SS L | |
57 | * proxyin g or tunne ling, and also allow s the kind of "role reversal" | |
58 | * that is required for most F TP data tr ansfers. | |
59 | * | |
60 | * @see ja vax.net.ss l.SSLSocke t | |
61 | * @see SS LServerSoc ket | |
62 | * | |
63 | * @author David Bro wnell | |
64 | */ | |
65 | final publ ic class S SLSocketIm pl extends BaseSSLSo cketImpl { | |
66 | ||
67 | /* | |
68 | * ERR OR HANDLIN G GUIDELIN ES | |
69 | * (wh ich except ions to th row and ca tch and wh ich not to throw and catch) | |
70 | * | |
71 | * . i f there is an IOExce ption (Soc ketExcepti on) when a ccessing t he | |
72 | * u nderlying Socket, pa ss it thro ugh | |
73 | * | |
74 | * . d o not thro w IOExcept ions, thro w SSLExcep tions (or a subclass ) | |
75 | * | |
76 | * . f or interna l errors ( things tha t indicate a bug in JSSE or a | |
77 | * g rossly mis configured J2RE), th row either an SSLExc eption or | |
78 | * a RuntimeEx ception at your conv enience. | |
79 | * | |
80 | * . h andshaking code (Han dshaker or Handshake Message) s hould gene rally | |
81 | * p ass throug h exceptio ns, but ca n handle t hem if the y know wha t to | |
82 | * d o. | |
83 | * | |
84 | * . e xception c haining sh ould be us ed for all new code. If you ha ppen | |
85 | * t o touch ol d code tha t does not use chain ing, you s hould chan ge it. | |
86 | * | |
87 | * . t here is a top level exception handler th at sits at all entry | |
88 | * p oints from applicati on code to SSLSocket read/writ e code. It | |
89 | * m akes sure that all e rrors are handled (s ee handleE xception() ). | |
90 | * | |
91 | * . J SSE intern al code sh ould gener ally not c all close( ), call | |
92 | * c loseIntern al(). | |
93 | */ | |
94 | ||
95 | /* | |
96 | * The re's a sta te machine associate d with eac h connecti on, which | |
97 | * amo ng other r oles serve s to negot iate sessi on changes . | |
98 | * | |
99 | * - S TART with constructo r, until t he TCP con nection's around. | |
100 | * - H ANDSHAKE p icks sessi on paramet ers before allowing traffic. | |
101 | * Ther e are many substates due to se quencing r equirement s | |
102 | * for handshake messages. | |
103 | * - D ATA may be transmitt ed. | |
104 | * - R ENEGOTIATE state all ows concur rent data and handsh aking | |
105 | * traf fic ("same " substate s as HANDS HAKE), and terminate s | |
106 | * in s election o f new sess ion (and c onnection) parameter s | |
107 | * - E RROR state immediate ly precede s abortive disconnec t. | |
108 | * - S ENT_CLOSE sent a clo se_notify to the pee r. For lay ered, | |
109 | * non- autoclose socket, mu st now rea d close_no tify | |
110 | * from peer befo re closing the conne ction. For nonlayere d or | |
111 | * non- autoclose socket, cl ose connec tion and g o onto | |
112 | * cs_C LOSED stat e. | |
113 | * - C LOSED afte r sending close_noti fy alert, & socket i s closed. | |
114 | * SSL connection objects a re not reu sed. | |
115 | * - A PP_CLOSED once the a pplication calls clo se(). Then it behave s like | |
116 | * a cl osed socke t, e.g.. g etInputStr eam() thro ws an Exce ption. | |
117 | * | |
118 | * Sta te affects what SSL record typ es may leg ally be se nt: | |
119 | * | |
120 | * - H andshake . .. only in HANDSHAKE and RENEG OTIATE sta tes | |
121 | * - A pp Data .. . only in DATA and R ENEGOTIATE states | |
122 | * - A lert ... i n HANDSHAK E, DATA, R ENEGOTIATE | |
123 | * | |
124 | * Re what may b e received : same as what may be sent, e xcept that | |
125 | * Han dshakeRequ est handsh aking mess ages can c ome from s ervers eve n | |
126 | * in the applic ation data state, to request e ntry to RE NEGOTIATE. | |
127 | * | |
128 | * The state mac hine withi n HANDSHAK E and RENE GOTIATE st ates contr ols | |
129 | * the pending s ession, no t the conn ection sta te, until the change | |
130 | * cip her spec a nd "Finish ed" handsh ake messag es are pro cessed and | |
131 | * mak e the "new " session become the current o ne. | |
132 | * | |
133 | * NOT E: details of the SM s always n eed to be nailed dow n better. | |
134 | * The text abov e illustra tes the co re ideas. | |
135 | * | |
136 | * +---->-- -----+---- -->------- -->------- + | |
137 | * | | | | |
138 | * <-----< ^ ^ <- ----< v | |
139 | *STAR T>----->HA NDSHAKE>-- --->DATA>- ---->RENEG OTIATE SE NT_CLOSE | |
140 | * v v v | | | |
141 | * | | | | v | |
142 | * +------- -----+---- ---------- -+ v ERROR | |
143 | * | | | | |
144 | * v | | | |
145 | * ERROR>--- --->-----> CLOSED<--- -----<---- +-- + | |
146 | * | | |
147 | * v | |
148 | * A PP_CLOSED | |
149 | * | |
150 | * ALS O, note th at the the purpose o f handshak ing (reneg otiation i s | |
151 | * inc luded) is to assign a differen t, and per haps new, session to | |
152 | * the connectio n. The SS Lv3 spec i s a bit co nfusing on that new | |
153 | * pro tocol feat ure. | |
154 | */ | |
155 | privat e static f inal int cs_START = 0; | |
156 | privat e static f inal int cs_HANDS HAKE = 1; | |
157 | privat e static f inal int cs_DATA = 2; | |
158 | privat e static f inal int cs_RENEG OTIATE = 3 ; | |
159 | privat e static f inal int cs_ERROR = 4; | |
160 | privat e static f inal int cs_SENT_C LOSE = 5; | |
161 | privat e static f inal int cs_CLOSE D = 6; | |
162 | privat e static f inal int cs_APP_C LOSED = 7; | |
163 | ||
164 | ||
165 | /* | |
166 | * Cli ent authen tication b e off, req uested, or required. | |
167 | * | |
168 | * Mig rated to S SLEngineIm pl: | |
169 | * clauth_non e/cl_auth_ requested/ clauth_req uired | |
170 | */ | |
171 | ||
172 | /* | |
173 | * Dri ves the pr otocol sta te machine . | |
174 | */ | |
175 | privat e volatile int connecti onState; | |
176 | ||
177 | /* | |
178 | * Fla g indicati ng that th e engine's handshake r has done the neces sary | |
179 | * ste ps so the engine may process a ChangeCip herSpec me ssage. | |
180 | */ | |
181 | privat e boolean received CCS; | |
182 | ||
183 | /* | |
184 | * Fla g indicati ng if the next recor d we recei ve MUST be a Finishe d | |
185 | * mes sage. Temp orarily se t during t he handsha ke to ensu re that | |
186 | * a c hange ciph er spec me ssage is f ollowed by a finishe d message. | |
187 | */ | |
188 | privat e boolean expectin gFinished; | |
189 | ||
190 | /* | |
191 | * For improved diagnostic s, we deta il connect ion closur e | |
192 | * If the socket is closed (connecti onState >= cs_ERROR) , | |
193 | * clo seReason ! = null ind icates if the socket was close d | |
194 | * bec ause of an error or because or normal sh utdown. | |
195 | */ | |
196 | privat e SSLExcep tion closeRea son; | |
197 | ||
198 | /* | |
199 | * Per -connectio n private state that doesn't c hange when the | |
200 | * ses sion is ch anged. | |
201 | */ | |
202 | privat e byte doClient Auth; | |
203 | privat e boolean roleIsSe rver; | |
204 | privat e boolean enableSe ssionCreat ion = true ; | |
205 | privat e String host; | |
206 | privat e boolean autoClos e = true; | |
207 | privat e AccessCo ntrolConte xt acc; | |
208 | ||
209 | // The cipher su ites enabl ed for use on this c onnection. | |
210 | privat e CipherSu iteList enabledC ipherSuite s; | |
211 | ||
212 | // The endpoint identifica tion proto col | |
213 | privat e String identifi cationProt ocol = nul l; | |
214 | ||
215 | // The cryptogra phic algor ithm const raints | |
216 | privat e Algorith mConstrain ts algo rithmConst raints = n ull; | |
217 | ||
218 | // The server na me indicat ion and ma tchers | |
219 | List<S NIServerNa me> serverNa mes = | |
220 | Coll ections.<S NIServerNa me>emptyLi st(); | |
221 | Collec tion<SNIMa tcher> sniMatch ers = | |
222 | Coll ections.<S NIMatcher> emptyList( ); | |
223 | // Is the server Names set to empty w ith SSLPar ameters.se tServerNam es()? | |
224 | privat e boolean noSniExt ension = f alse; | |
225 | ||
226 | // Is the sniMat chers set to empty w ith SSLPar ameters.se tSNIMatche rs()? | |
227 | privat e boolean noSniMat cher = fal se; | |
228 | ||
229 | /* | |
230 | * REA D ME * REA D ME * REA D ME * REA D ME * REA D ME * REA D ME * | |
231 | * IMP ORTANT STU FF TO UNDE RSTANDING THE SYNCHR ONIZATION ISSUES. | |
232 | * REA D ME * REA D ME * REA D ME * REA D ME * REA D ME * REA D ME * | |
233 | * | |
234 | * The re are sev eral locks here. | |
235 | * | |
236 | * The primary l ock is the per-insta nce lock u sed by | |
237 | * syn chronized( this) and the synchr onized met hods. It controls a ll | |
238 | * acc ess to thi ngs such a s the conn ection sta te and var iables whi ch | |
239 | * aff ect handsh aking. If we are in side a syn chronized method, we | |
240 | * can access th e state di rectly, ot herwise, w e must use the | |
241 | * syn chronized equivalent s. | |
242 | * | |
243 | * The handshake Lock is us ed to ensu re that on ly one thr ead perfor ms | |
244 | * the *complete initial* handshake. If someo ne is hand shaking, a ny | |
245 | * str ay applica tion or st artHandsha ke() reque sts who fi nd the | |
246 | * con nection st ate is cs_ HANDSHAKE will stall on handsh akeLock | |
247 | * unt il handsha king is do ne. Once the handsh ake is don e, we eith er | |
248 | * suc ceeded or failed, bu t we can n ever go ba ck to the cs_HANDSHA KE | |
249 | * or cs_START s tate again . | |
250 | * | |
251 | * Not e that the read/writ e() calls here in SS LSocketImp l are not | |
252 | * obv iously syn chronized. In fact, it's very nonintuit ive, and | |
253 | * req uires care ful examin ation of c ode paths. Grab som e coffee, | |
254 | * and be carefu l with any code chan ges. | |
255 | * | |
256 | * The re can be only three threads a ctive at a time in t he I/O | |
257 | * sub section of this clas s. | |
258 | * 1. startH andshake | |
259 | * 2. AppInp utStream | |
260 | * 3. AppOut putStream | |
261 | * One thread co uld call s tartHandsh ake(). | |
262 | * App InputStrea m/AppOutpu tStream re ad() and w rite() cal ls are eac h | |
263 | * syn chronized on 'this' in their r espective classes, s o only one | |
264 | * app . thread w ill be doi ng a SSLSo cketImpl.r ead() or . write()'s at | |
265 | * a t ime. | |
266 | * | |
267 | * If handshakin g is requi red (state cs_HANDSH AKE), and | |
268 | * get Connection State() fo r some/all threads r eturns cs_ HANDSHAKE, | |
269 | * onl y one can grab the h andshakeLo ck, and th e rest wil l stall | |
270 | * eit her on get Connection State(), o r on the h andshakeLo ck if they | |
271 | * hap pen to suc cessfully race throu gh the get Connection State(). | |
272 | * | |
273 | * If a writer i s doing th e initial handshakin g, it must create a | |
274 | * tem porary rea der to rea d the resp onses from the other side. As a | |
275 | * sid e-effect, the writer 's reader will have priority o ver any | |
276 | * oth er reader. However, the write r's reader is not al lowed to | |
277 | * con sume any a pplication data. Wh en handsha keLock is finally | |
278 | * rel eased, we either hav e a cs_DAT A connecti on, or a | |
279 | * cs_ CLOSED/cs_ ERROR sock et. | |
280 | * | |
281 | * The writeLock is held w hile writi ng on a so cket conne ction and | |
282 | * als o to prote ct the MAC and ciphe r for thei r directio n. The | |
283 | * wri teLock is package pr ivate for Handshaker which hol ds it whil e | |
284 | * wri ting the C hangeCiphe rSpec mess age. | |
285 | * | |
286 | * To avoid the problem of a thread trying to change ope rational | |
287 | * mod es on a so cket while handshaki ng is goin g on, we s ynchronize | |
288 | * on 'this'. I f handshak ing has no t started yet, we te ll the | |
289 | * han dshaker to change it s mode. I f handshak ing has st arted, | |
290 | * we simply sto re that re quest unti l the next pending s ession | |
291 | * is created, a t which ti me the new handshake r's state is set. | |
292 | * | |
293 | * The readLock is held du ring readR ecord(), w hich is re sponsible | |
294 | * for reading a n InputRec ord, decry pting it, and proces sing it. | |
295 | * The readLock ensures th at these t hree steps are done atomically | |
296 | * and that once started, no other t hread can block on I nputRecord .read. | |
297 | * Thi s is neces sary so th at process ing of clo se_notify alerts | |
298 | * fro m the peer are handl ed properl y. | |
299 | */ | |
300 | final private Ob ject handshak eLock = ne w Object() ; | |
301 | final ReentrantL ock writeLoc k = new Re entrantLoc k(); | |
302 | final private Ob ject readLock = new Obj ect(); | |
303 | ||
304 | privat e InputRec ord inrec; | |
305 | ||
306 | /* | |
307 | * Cry pto state that's rei nitialized when the session ch anges. | |
308 | */ | |
309 | privat e Authenti cator readAuth enticator, writeAuth enticator; | |
310 | privat e CipherBo x readCiph er, writeC ipher; | |
311 | // NOT E: compres sion state would be saved here | |
312 | ||
313 | /* | |
314 | * sec urity para meters for secure re negotiatio n. | |
315 | */ | |
316 | privat e boolean secureRe negotiatio n; | |
317 | privat e byte[] clientVe rifyData; | |
318 | privat e byte[] serverVe rifyData; | |
319 | ||
320 | /* | |
321 | * The authentic ation cont ext holds all inform ation used to establ ish | |
322 | * who this end of the con nection is (certific ate chains , private keys, | |
323 | * etc ) and who is trusted (e.g. as CAs or web sites). | |
324 | */ | |
325 | privat e SSLConte xtImpl sslConte xt; | |
326 | ||
327 | ||
328 | /* | |
329 | * Thi s connecti on is one of (potent ially) man y associat ed with | |
330 | * any given ses sion. The output of the hands hake proto col is a | |
331 | * new session . .. althoug h all the protocol d escription talks | |
332 | * abo ut changin g the ciph er spec (a nd it does change), in fact | |
333 | * tha t's incide ntal since it's done by changi ng everyth ing that | |
334 | * is associated with a se ssion at t he same ti me. (TLS/ IETF may | |
335 | * cha nge that t o add clie nt authent ication w/ o new key exchg.) | |
336 | */ | |
337 | privat e Handshak er handshaker ; | |
338 | privat e SSLSessi onImpl sess; | |
339 | privat e volatile SSLSessio nImpl handshakeS ession; | |
340 | ||
341 | ||
342 | /* | |
343 | * If anyone wan ts to get notified a bout hands hake compl etions, | |
344 | * the y'll show up on this list. | |
345 | */ | |
346 | privat e HashMap< HandshakeC ompletedLi stener, Ac cessContro lContext> | |
347 | hand shakeListe ners; | |
348 | ||
349 | /* | |
350 | * Reu se the sam e internal input/out put stream s. | |
351 | */ | |
352 | privat e InputStr eam sockInpu t; | |
353 | privat e OutputSt ream sockOutp ut; | |
354 | ||
355 | ||
356 | /* | |
357 | * The se input a nd output streams bl ock their data in SS L records, | |
358 | * and usually a rrange int egrity and privacy p rotection for those | |
359 | * rec ords. The guts of t he SSL pro tocol are wrapped up in these | |
360 | * str eams, and in the han dshaking t hat establ ishes the details of | |
361 | * tha t integrit y and priv acy protec tion. | |
362 | */ | |
363 | privat e AppInput Stream input; | |
364 | privat e AppOutpu tStream output; | |
365 | ||
366 | /* | |
367 | * The protocol versions e nabled for use on th is connect ion. | |
368 | * | |
369 | * Not e: we supp ort a pseu do protoco l called S SLv2Hello which when | |
370 | * set will resu lt in an S SL v2 Hell o being se nt with SS L (version 3.0) | |
371 | * or TLS (versi on 3.1, 3. 2, etc.) v ersion inf o. | |
372 | */ | |
373 | privat e Protocol List enabl edProtocol s; | |
374 | ||
375 | /* | |
376 | * The SSL versi on associa ted with t his connec tion. | |
377 | */ | |
378 | privat e Protocol Version protocol Version = ProtocolVe rsion.DEFA ULT; | |
379 | ||
380 | /* Cla ss and sub class dyna mic debugg ing suppor t */ | |
381 | privat e static f inal Debug debug = D ebug.getIn stance("ss l"); | |
382 | ||
383 | /* | |
384 | * Is it the fir st applica tion recor d to write ? | |
385 | */ | |
386 | privat e boolean isFirstApp OutputReco rd = true; | |
387 | ||
388 | /* | |
389 | * If AppOutputS tream need s to delay writes of small pac kets, we | |
390 | * wil l use this to store the data u ntil we ac tually do the write. | |
391 | */ | |
392 | privat e ByteArra yOutputStr eam heldRe cordBuffer = null; | |
393 | ||
394 | /* | |
395 | * Whe ther local cipher su ites prefe rence in s erver side should be | |
396 | * hon ored durin g handshak ing? | |
397 | */ | |
398 | privat e boolean preferLoca lCipherSui tes = fals e; | |
399 | ||
400 | /* | |
401 | * Is the local name servi ce trustwo rthy? | |
402 | * | |
403 | * If the local name servi ce is not trustworth y, reverse host name | |
404 | * res olution sh ould not b e performe d for endp oint ident ification. | |
405 | */ | |
406 | static final boo lean trust NameServic e = | |
407 | Debug.ge tBooleanPr operty("jd k.tls.trus tNameServi ce", false ); | |
408 | ||
409 | // | |
410 | // CON STRUCTORS AND INITIA LIZATION C ODE | |
411 | // | |
412 | ||
413 | /** | |
414 | * Con structs an SSL conne ction to a named hos t at a spe cified por t, | |
415 | * usi ng the aut henticatio n context provided. This endp oint acts as | |
416 | * the client, a nd may rej oin an exi sting SSL session if appropria te. | |
417 | * | |
418 | * @pa ram contex t authenti cation con text to us e | |
419 | * @pa ram host n ame of the host with which to connect | |
420 | * @pa ram port n umber of t he server' s port | |
421 | */ | |
422 | SSLSoc ketImpl(SS LContextIm pl context , String h ost, int p ort) | |
423 | throws I OException , UnknownH ostExcepti on { | |
424 | su per(); | |
425 | th is.host = host; | |
426 | th is.serverN ames = | |
427 | Utilitie s.addToSNI ServerName List(this. serverName s, this.ho st); | |
428 | in it(context , false); | |
429 | So cketAddres s socketAd dress = | |
430 | host != null ? new InetSo cketAddres s(host, po rt) : | |
431 | new I netSocketA ddress(Ine tAddress.g etByName(n ull), port ); | |
432 | co nnect(sock etAddress, 0); | |
433 | } | |
434 | ||
435 | ||
436 | /** | |
437 | * Con structs an SSL conne ction to a server at a specifi ed address . | |
438 | * and TCP port, using the authentic ation cont ext provid ed. This | |
439 | * end point acts as the cl ient, and may rejoin an existi ng SSL ses sion | |
440 | * if appropriat e. | |
441 | * | |
442 | * @pa ram contex t authenti cation con text to us e | |
443 | * @pa ram addres s the serv er's host | |
444 | * @pa ram port i ts port | |
445 | */ | |
446 | SSLSoc ketImpl(SS LContextIm pl context , InetAddr ess host, int port) | |
447 | throws I OException { | |
448 | su per(); | |
449 | in it(context , false); | |
450 | So cketAddres s socketAd dress = ne w InetSock etAddress( host, port ); | |
451 | co nnect(sock etAddress, 0); | |
452 | } | |
453 | ||
454 | /** | |
455 | * Con structs an SSL conne ction to a named hos t at a spe cified por t, | |
456 | * usi ng the aut henticatio n context provided. This endp oint acts as | |
457 | * the client, a nd may rej oin an exi sting SSL session if appropria te. | |
458 | * | |
459 | * @pa ram contex t authenti cation con text to us e | |
460 | * @pa ram host n ame of the host with which to connect | |
461 | * @pa ram port n umber of t he server' s port | |
462 | * @pa ram localA ddr the lo cal addres s the sock et is boun d to | |
463 | * @pa ram localP ort the lo cal port t he socket is bound t o | |
464 | */ | |
465 | SSLSoc ketImpl(SS LContextIm pl context , String h ost, int p ort, | |
466 | InetAddr ess localA ddr, int l ocalPort) | |
467 | throws I OException , UnknownH ostExcepti on { | |
468 | su per(); | |
469 | th is.host = host; | |
470 | th is.serverN ames = | |
471 | Utilitie s.addToSNI ServerName List(this. serverName s, this.ho st); | |
472 | in it(context , false); | |
473 | bi nd(new Ine tSocketAdd ress(local Addr, loca lPort)); | |
474 | So cketAddres s socketAd dress = | |
475 | host != null ? new InetSo cketAddres s(host, po rt) : | |
476 | new I netSocketA ddress(Ine tAddress.g etByName(n ull), port ); | |
477 | co nnect(sock etAddress, 0); | |
478 | } | |
479 | ||
480 | ||
481 | /** | |
482 | * Con structs an SSL conne ction to a server at a specifi ed address . | |
483 | * and TCP port, using the authentic ation cont ext provid ed. This | |
484 | * end point acts as the cl ient, and may rejoin an existi ng SSL ses sion | |
485 | * if appropriat e. | |
486 | * | |
487 | * @pa ram contex t authenti cation con text to us e | |
488 | * @pa ram addres s the serv er's host | |
489 | * @pa ram port i ts port | |
490 | * @pa ram localA ddr the lo cal addres s the sock et is boun d to | |
491 | * @pa ram localP ort the lo cal port t he socket is bound t o | |
492 | */ | |
493 | SSLSoc ketImpl(SS LContextIm pl context , InetAddr ess host, int port, | |
494 | InetAddr ess localA ddr, int l ocalPort) | |
495 | throws I OException { | |
496 | su per(); | |
497 | in it(context , false); | |
498 | bi nd(new Ine tSocketAdd ress(local Addr, loca lPort)); | |
499 | So cketAddres s socketAd dress = ne w InetSock etAddress( host, port ); | |
500 | co nnect(sock etAddress, 0); | |
501 | } | |
502 | ||
503 | /* | |
504 | * Pac kage-priva te constru ctor used ONLY by SS LServerSoc ket. The | |
505 | * jav a.net pack age accept s the TCP connection after thi s call is | |
506 | * mad e. This j ust initia lizes hand shake stat e to use " server mod e", | |
507 | * giv ing contro l over the use of SS L client a uthenticat ion. | |
508 | */ | |
509 | SSLSoc ketImpl(SS LContextIm pl context , boolean serverMode , | |
510 | CipherSu iteList su ites, byte clientAut h, | |
511 | boolean sessionCre ation, Pro tocolList protocols, | |
512 | String i dentificat ionProtoco l, | |
513 | Algorith mConstrain ts algorit hmConstrai nts, | |
514 | Collecti on<SNIMatc her> sniMa tchers, | |
515 | boolean preferLoca lCipherSui tes) throw s IOExcept ion { | |
516 | ||
517 | su per(); | |
518 | do ClientAuth = clientA uth; | |
519 | en ableSessio nCreation = sessionC reation; | |
520 | th is.identif icationPro tocol = id entificati onProtocol ; | |
521 | th is.algorit hmConstrai nts = algo rithmConst raints; | |
522 | th is.sniMatc hers = sni Matchers; | |
523 | th is.preferL ocalCipher Suites = p referLocal CipherSuit es; | |
524 | in it(context , serverMo de); | |
525 | ||
526 | /* | |
527 | * Override what was p icked out for us. | |
528 | * / | |
529 | en abledCiphe rSuites = suites; | |
530 | en abledProto cols = pro tocols; | |
531 | } | |
532 | ||
533 | ||
534 | /** | |
535 | * Pac kage-priva te constru ctor used to instant iate an un connected | |
536 | * soc ket. The j ava.net pa ckage will connect i t, either when the | |
537 | * con nect() cal l is made by the app lication. This inst ance is | |
538 | * mea nt to set handshake state to u se "client mode". | |
539 | */ | |
540 | SSLSoc ketImpl(SS LContextIm pl context ) { | |
541 | su per(); | |
542 | in it(context , false); | |
543 | } | |
544 | ||
545 | ||
546 | /** | |
547 | * Lay er SSL tra ffic over an existin g connecti on, rather than crea ting | |
548 | * a n ew connect ion. The existing c onnection may be use d only for SSL | |
549 | * tra ffic (usin g this SSL Socket) un til the SS LSocket.cl ose() call | |
550 | * ret urns. Howe ver, if a protocol e rror is de tected, th at existin g | |
551 | * con nection is automatic ally close d. | |
552 | * | |
553 | * <P> This part icular con structor a lways uses the socke t in the | |
554 | * rol e of an SS L client. It may be useful in cases whic h start | |
555 | * usi ng SSL aft er some in itial data transfers , for exam ple in som e | |
556 | * SSL tunneling applicati ons or as part of so me kinds o f applicat ion | |
557 | * pro tocols whi ch negotia te use of a SSL base d security . | |
558 | * | |
559 | * @pa ram sock t he existin g connecti on | |
560 | * @pa ram contex t the auth entication context t o use | |
561 | */ | |
562 | SSLSoc ketImpl(SS LContextIm pl context , Socket s ock, Strin g host, | |
563 | int port , boolean autoClose) throws IO Exception { | |
564 | su per(sock); | |
565 | // We always layer ove r a connec ted socket | |
566 | if (!sock.is Connected( )) { | |
567 | throw ne w SocketEx ception("U nderlying socket is not connec ted"); | |
568 | } | |
569 | th is.host = host; | |
570 | th is.serverN ames = | |
571 | Utilitie s.addToSNI ServerName List(this. serverName s, this.ho st); | |
572 | in it(context , false); | |
573 | th is.autoClo se = autoC lose; | |
574 | do neConnect( ); | |
575 | } | |
576 | ||
577 | /** | |
578 | * Cre ates a ser ver mode { @link Sock et} layere d over an | |
579 | * exi sting conn ected sock et, and is able to r ead data w hich has | |
580 | * alr eady been consumed/r emoved fro m the {@li nk Socket} 's | |
581 | * und erlying {@ link Input Stream}. | |
582 | */ | |
583 | SSLSoc ketImpl(SS LContextIm pl context , Socket s ock, | |
584 | InputStr eam consum ed, boolea n autoClos e) throws IOExceptio n { | |
585 | su per(sock, consumed); | |
586 | // We always layer ove r a connec ted socket | |
587 | if (!sock.is Connected( )) { | |
588 | throw ne w SocketEx ception("U nderlying socket is not connec ted"); | |
589 | } | |
590 | ||
591 | // In server mode, it is not nec essary to set host a nd serverN ames. | |
592 | // Otherwise , would re quire a re verse DNS lookup to get the ho stname. | |
593 | ||
594 | in it(context , true); | |
595 | th is.autoClo se = autoC lose; | |
596 | do neConnect( ); | |
597 | } | |
598 | ||
599 | /** | |
600 | * Ini tializes t he client socket. | |
601 | */ | |
602 | privat e void ini t(SSLConte xtImpl con text, bool ean isServ er) { | |
603 | ss lContext = context; | |
604 | se ss = SSLSe ssionImpl. nullSessio n; | |
605 | ha ndshakeSes sion = nul l; | |
606 | ||
607 | /* | |
608 | * role is a s specifie d, state i s START un til after | |
609 | * the low l evel conne ction's es tablished. | |
610 | * / | |
611 | ro leIsServer = isServe r; | |
612 | co nnectionSt ate = cs_S TART; | |
613 | re ceivedCCS = false; | |
614 | ||
615 | /* | |
616 | * default r ead and wr ite side c ipher and MAC suppor t | |
617 | * | |
618 | * Note: co mpression support wo uld go her e too | |
619 | * / | |
620 | re adCipher = CipherBox .NULL; | |
621 | re adAuthenti cator = MA C.NULL; | |
622 | wr iteCipher = CipherBo x.NULL; | |
623 | wr iteAuthent icator = M AC.NULL; | |
624 | ||
625 | // initial s ecurity pa rameters f or secure renegotiat ion | |
626 | se cureRenego tiation = false; | |
627 | cl ientVerify Data = new byte[0]; | |
628 | se rverVerify Data = new byte[0]; | |
629 | ||
630 | en abledCiphe rSuites = | |
631 | sslC ontext.get DefaultCip herSuiteLi st(roleIsS erver); | |
632 | en abledProto cols = | |
633 | sslC ontext.get DefaultPro tocolList( roleIsServ er); | |
634 | ||
635 | in rec = null ; | |
636 | ||
637 | // save the acc | |
638 | ac c = Access Controller .getContex t(); | |
639 | ||
640 | in put = new AppInputSt ream(this) ; | |
641 | ou tput = new AppOutput Stream(thi s); | |
642 | } | |
643 | ||
644 | /** | |
645 | * Con nects this socket to the serve r with a s pecified t imeout | |
646 | * val ue. | |
647 | * | |
648 | * Thi s method i s either c alled on a n unconnec ted SSLSoc ketImpl by the | |
649 | * app lication, or it is c alled in t he constru ctor of a regular | |
650 | * SSL SocketImpl . If we ar e layering on top on another s ocket, the n | |
651 | * thi s method s hould not be called, because w e assume t hat the | |
652 | * und erlying so cket is al ready conn ected by t he time it is passed to | |
653 | * us. | |
654 | * | |
655 | * @pa ram endp oint the < code>Socke tAddress</ code> | |
656 | * @pa ram time out the t imeout val ue to be u sed, 0 is no timeout | |
657 | * @th rows IOEx ception if an error occurs dur ing the co nnection | |
658 | * @th rows Sock etTimeoutE xception i f timeout expires be fore conne cting | |
659 | */ | |
660 | @Overr ide | |
661 | public void conn ect(Socket Address en dpoint, in t timeout) | |
662 | throws I OException { | |
663 | ||
664 | if (isLayere d()) { | |
665 | throw ne w SocketEx ception("A lready con nected"); | |
666 | } | |
667 | ||
668 | if (!(endpoi nt instanc eof InetSo cketAddres s)) { | |
669 | throw ne w SocketEx ception( | |
670 | "Canno t handle n on-Inet so cket addre sses."); | |
671 | } | |
672 | ||
673 | su per.connec t(endpoint , timeout) ; | |
674 | ||
675 | if (host == null || ho st.length( ) == 0) { | |
676 | useImpli citHost(fa lse); | |
677 | } | |
678 | ||
679 | do neConnect( ); | |
680 | } | |
681 | ||
682 | /** | |
683 | * Ini tialize th e handshak er and soc ket stream s. | |
684 | * | |
685 | * Cal led by con nect, the layered co nstructor, and SSLSe rverSocket . | |
686 | */ | |
687 | void d oneConnect () throws IOExceptio n { | |
688 | /* | |
689 | * Save the input and output str eams. May be done o nly after | |
690 | * java.net actually c onnects us ing the so cket "self ", else | |
691 | * we get so me pretty bizarre fa ilure mode s. | |
692 | * / | |
693 | so ckInput = super.getI nputStream (); | |
694 | so ckOutput = super.get OutputStre am(); | |
695 | ||
696 | /* | |
697 | * Move to h andshaking state, wi th pending session i nitialized | |
698 | * to defaul ts and the appropria te kind of handshake r set up. | |
699 | * / | |
700 | in itHandshak er(); | |
701 | } | |
702 | ||
703 | synchr onized pri vate int g etConnecti onState() { | |
704 | re turn conne ctionState ; | |
705 | } | |
706 | ||
707 | synchr onized pri vate void setConnect ionState(i nt state) { | |
708 | co nnectionSt ate = stat e; | |
709 | } | |
710 | ||
711 | Access ControlCon text getAc c() { | |
712 | re turn acc; | |
713 | } | |
714 | ||
715 | // | |
716 | // REA DING AND W RITING REC ORDS | |
717 | // | |
718 | ||
719 | /* | |
720 | * App OutputStre am calls m ay need to buffer mu ltiple out bound | |
721 | * app lication p ackets. | |
722 | * | |
723 | * All other wri teRecord() calls wil l not buff er, so do not hold | |
724 | * the se records . | |
725 | */ | |
726 | void w riteRecord (OutputRec ord r) thr ows IOExce ption { | |
727 | wr iteRecord( r, false); | |
728 | } | |
729 | ||
730 | /* | |
731 | * Rec ord Output . Applicat ion data c an't be se nt until t he first | |
732 | * han dshake est ablishes a session. | |
733 | * | |
734 | * NOT E: we let empty rec ords be wr itten as a hook to f orce some | |
735 | * TCP -level act ivity, not ably hands haking, to occur. | |
736 | */ | |
737 | void w riteRecord (OutputRec ord r, boo lean holdR ecord) thr ows IOExce ption { | |
738 | /* | |
739 | * The loop is in case of HANDSH AKE --> ER ROR transi tions, etc | |
740 | * / | |
741 | loop: | |
742 | wh ile (r.con tentType() == Record .ct_applic ation_data ) { | |
743 | /* | |
744 | * Not a ll states support pa ssing appl ication da ta. We | |
745 | * synch ronize acc ess to the connectio n state, s o that | |
746 | * synch ronous han dshakes ca n complete cleanly. | |
747 | */ | |
748 | switch ( getConnect ionState() ) { | |
749 | ||
750 | /* | |
751 | * We've deferred the initia l handshak ing till j ust now, | |
752 | * when presumably a thread' s decided it's OK to block for | |
753 | * longi sh periods of time f or I/O pur poses (as well as | |
754 | * confi gured the cipher sui tes it wan ts to use) . | |
755 | */ | |
756 | case cs_ HANDSHAKE: | |
757 | perf ormInitial Handshake( ); | |
758 | brea k; | |
759 | ||
760 | case cs_ DATA: | |
761 | case cs_ RENEGOTIAT E: | |
762 | brea k loop; | |
763 | ||
764 | case cs_ ERROR: | |
765 | fata l(Alerts.a lert_close _notify, | |
766 | "error whi le writing to socket "); | |
767 | brea k; // dumm y | |
768 | ||
769 | case cs_ SENT_CLOSE : | |
770 | case cs_ CLOSED: | |
771 | case cs_ APP_CLOSED : | |
772 | // w e should n ever get h ere (check in AppOut putStream) | |
773 | // t his is jus t a fallba ck | |
774 | if ( closeReaso n != null) { | |
775 | throw clos eReason; | |
776 | } el se { | |
777 | throw new SocketExce ption("Soc ket closed "); | |
778 | } | |
779 | ||
780 | /* | |
781 | * Else something' s goofy in this stat e machine' s use. | |
782 | */ | |
783 | default: | |
784 | thro w new SSLP rotocolExc eption("St ate error, send app data"); | |
785 | } | |
786 | } | |
787 | ||
788 | // | |
789 | // Don't bot her to rea lly write empty reco rds. We w ent this | |
790 | // far to dr ive the ha ndshake ma chinery, f or correct ness; not | |
791 | // writing e mpty recor ds improve s performa nce by cut ting CPU | |
792 | // time and network re source usa ge. Howev er, some p rotocol | |
793 | // implement ations are fragile a nd don't l ike to see empty | |
794 | // records, so this al so increas es robustn ess. | |
795 | // | |
796 | if (!r.isEmp ty()) { | |
797 | ||
798 | // If th e record i s a close notify ale rt, we nee d to honor | |
799 | // socke t option S O_LINGER. Note that we will tr y to send | |
800 | // the c lose notif y even if the SO_LIN GER set to zero. | |
801 | if (r.is Alert(Aler ts.alert_c lose_notif y) && getS oLinger() >= 0) { | |
802 | ||
803 | // k eep and cl ear the cu rrent thre ad interru ption stat us. | |
804 | bool ean interr upted = Th read.inter rupted(); | |
805 | try { | |
806 | if (writeL ock.tryLoc k(getSoLin ger(), Tim eUnit.SECO NDS)) { | |
807 | try { | |
808 | wr iteRecordI nternal(r, holdRecor d); | |
809 | } fina lly { | |
810 | wr iteLock.un lock(); | |
811 | } | |
812 | } else { | |
813 | SSLExc eption ssl e = new SS LException ( | |
814 | "SO_LING ER timeout ," + | |
815 | " close_ notify mes sage canno t be sent. "); | |
816 | ||
817 | ||
818 | // For layered, non-autocl ose socket s, we are not | |
819 | // abl e to bring them into a usable state, so we | |
820 | // tre at it as f atal error . | |
821 | if (is Layered() && !autoCl ose) { | |
822 | // Note that the alert descripti on is | |
823 | // specified as -1, so no messag e will be send | |
824 | // to peer a nymore. | |
825 | fa tal((byte) (-1), ssle ); | |
826 | } else if ((debu g != null) && Debug. isOn("ssl" )) { | |
827 | Sy stem.out.p rintln( | |
828 | Thread.c urrentThre ad().getNa me() + | |
829 | ", recei ved Except ion: " + s sle); | |
830 | } | |
831 | ||
832 | // RFC 2246 requi res that t he session becomes | |
833 | // unr esumable i f any conn ection is terminated | |
834 | // wit hout prope r close_no tify messa ges with | |
835 | // lev el equal t o warning. | |
836 | // | |
837 | // RFC 4346 no lo nger requi res that a session n ot be | |
838 | // res umed if fa ilure to p roperly cl ose a conn ection. | |
839 | // | |
840 | // We choose to make the s ession unr esumable i f | |
841 | // fai led to sen d the clos e_notify m essage. | |
842 | // | |
843 | sess.i nvalidate( ); | |
844 | } | |
845 | } ca tch (Inter ruptedExce ption ie) { | |
846 | // keep in terrupted status | |
847 | interrupte d = true; | |
848 | } | |
849 | ||
850 | // r estore the interrupt ed status | |
851 | if ( interrupte d) { | |
852 | Thread.cur rentThread ().interru pt(); | |
853 | } | |
854 | } else { | |
855 | writ eLock.lock (); | |
856 | try { | |
857 | writeRecor dInternal( r, holdRec ord); | |
858 | } fi nally { | |
859 | writeLock. unlock(); | |
860 | } | |
861 | } | |
862 | } | |
863 | } | |
864 | ||
865 | privat e void wri teRecordIn ternal(Out putRecord r, | |
866 | boolean holdRecord ) throws I OException { | |
867 | ||
868 | // r.compres s(c); | |
869 | r. encrypt(wr iteAuthent icator, wr iteCipher) ; | |
870 | ||
871 | if (holdReco rd) { | |
872 | // If we were requ ested to d elay the r ecord due to possibi lity | |
873 | // of Na gle's bein g active w hen finall y got to w riting, an d | |
874 | // it's actually n ot, we don 't really need to de lay it. | |
875 | if (getT cpNoDelay( )) { | |
876 | hold Record = f alse; | |
877 | } else { | |
878 | // W e need to hold the r ecord, so let's prov ide | |
879 | // a per-socke t place to do it. | |
880 | if ( heldRecord Buffer == null) { | |
881 | // Likely only need 37 bytes. | |
882 | heldRecord Buffer = n ew ByteArr ayOutputSt ream(40); | |
883 | } | |
884 | } | |
885 | } | |
886 | r. write(sock Output, ho ldRecord, heldRecord Buffer); | |
887 | ||
888 | /* | |
889 | * Check the sequence number sta te | |
890 | * | |
891 | * Note that in order to maintai n the conn ection I/O | |
892 | * properly, we check the sequen ce number after the last | |
893 | * record wr iting proc ess. As we request r enegotiati on | |
894 | * or close the connec tion for w rapped seq uence numb er | |
895 | * when ther e is enoug h sequence number sp ace left t o | |
896 | * handle a few more r ecords, so the seque nce number | |
897 | * of the la st record cannot be wrapped. | |
898 | * / | |
899 | if (connecti onState < cs_ERROR) { | |
900 | checkSeq uenceNumbe r(writeAut henticator , r.conten tType()); | |
901 | } | |
902 | ||
903 | // turn off the flag o f the firs t applicat ion record | |
904 | if (isFirstA ppOutputRe cord && | |
905 | r.co ntentType( ) == Recor d.ct_appli cation_dat a) { | |
906 | isFirstA ppOutputRe cord = fal se; | |
907 | } | |
908 | } | |
909 | ||
910 | /* | |
911 | * Nee d to split the paylo ad except the follow ing cases: | |
912 | * | |
913 | * 1. protocol v ersion is TLS 1.1 or later; | |
914 | * 2. bulk ciphe r does not use CBC m ode, inclu ding null bulk ciphe r suites. | |
915 | * 3. the payloa d is the f irst appli cation rec ord of a f reshly | |
916 | * negotiated TLS sessi on. | |
917 | * 4. the CBC pr otection i s disabled ; | |
918 | * | |
919 | * Mor e details, please re fer to App OutputStre am.write(b yte[], int , int). | |
920 | */ | |
921 | boolea n needToSp litPayload () { | |
922 | wr iteLock.lo ck(); | |
923 | tr y { | |
924 | return ( protocolVe rsion.v <= ProtocolV ersion.TLS 10.v) && | |
925 | writeCiphe r.isCBCMod e() && !is FirstAppOu tputRecord && | |
926 | Record.ena bleCBCProt ection; | |
927 | } finally { | |
928 | writeLoc k.unlock() ; | |
929 | } | |
930 | } | |
931 | ||
932 | /* | |
933 | * Rea d an appli cation dat a record. Alerts an d handshak e | |
934 | * mes sages are handled di rectly. | |
935 | */ | |
936 | void r eadDataRec ord(InputR ecord r) t hrows IOEx ception { | |
937 | if (getConne ctionState () == cs_H ANDSHAKE) { | |
938 | performI nitialHand shake(); | |
939 | } | |
940 | re adRecord(r , true); | |
941 | } | |
942 | ||
943 | ||
944 | /* | |
945 | * Cle ar the pip eline of r ecords fro m the peer , optional ly returni ng | |
946 | * app lication d ata. Cal ler is res ponsible f or knowing that it's | |
947 | * pos sible to d o this kin d of clear ing, if th ey don't w ant app | |
948 | * dat a -- e.g. since it's the initi al SSL han dshake. | |
949 | * | |
950 | * Don 't synchro nize (this ) during a blocking read() sin ce it | |
951 | * pro tects data which is accessed o n the writ e side as well. | |
952 | */ | |
953 | privat e void rea dRecord(In putRecord r, boolean needAppDa ta) | |
954 | throws I OException { | |
955 | in t state; | |
956 | ||
957 | // readLock protects r eading and processin g of an In putRecord. | |
958 | // It keeps the readin g from soc kInput and processin g of the r ecord | |
959 | // atomic so that no t wo threads can be bl ocked on t he | |
960 | // read from the same input stre am at the same time. | |
961 | // This is r equired fo r example when a rea der thread is | |
962 | // blocked o n the read and anoth er thread is trying to | |
963 | // close the socket. F or a non-a utoclose, layered so cket, | |
964 | // the threa d performi ng the clo se needs t o read the close_not ify. | |
965 | // | |
966 | // Use readL ock instea d of 'this ' for lock ing becaus e | |
967 | // 'this' al so protect s data acc essed duri ng writing . | |
968 | sync hronized ( readLock) { | |
969 | /* | |
970 | * Read and handle rec ords ... r eturn appl ication da ta | |
971 | * ONLY if i t's needed . | |
972 | * / | |
973 | ||
974 | wh ile (((sta te = getCo nnectionSt ate()) != cs_CLOSED) && | |
975 | (sta te != cs_E RROR) && ( state != c s_APP_CLOS ED)) { | |
976 | /* | |
977 | * Read a record . .. maybe e mitting an alert if we get a | |
978 | * compr ehensible but unsupp orted "hel lo" messag e during | |
979 | * forma t checking (e.g. V2) . | |
980 | */ | |
981 | try { | |
982 | r.se tAppDataVa lid(false) ; | |
983 | r.re ad(sockInp ut, sockOu tput); | |
984 | } catch (SSLProtoc olExceptio n e) { | |
985 | try { | |
986 | fatal(Aler ts.alert_u nexpected_ message, e ); | |
987 | } ca tch (IOExc eption x) { | |
988 | // discard this exce ption | |
989 | } | |
990 | thro w e; | |
991 | } catch (EOFExcept ion eof) { | |
992 | bool ean handsh aking = (g etConnecti onState() <= cs_HAND SHAKE); | |
993 | bool ean rethro w = requir eCloseNoti fy || hand shaking; | |
994 | if ( (debug != null) && D ebug.isOn( "ssl")) { | |
995 | System.out .println(T hread.curr entThread( ).getName( ) + | |
996 | ", rec eived EOFE xception: " | |
997 | + (ret hrow ? "er ror" : "ig nored")); | |
998 | } | |
999 | if ( rethrow) { | |
1000 | SSLExcepti on e; | |
1001 | if (handsh aking) { | |
1002 | e = ne w SSLHands hakeExcept ion | |
1003 | (" Remote hos t closed c onnection during han dshake"); | |
1004 | } else { | |
1005 | e = ne w SSLProto colExcepti on | |
1006 | (" Remote hos t closed c onnection incorrectl y"); | |
1007 | } | |
1008 | e.initCaus e(eof); | |
1009 | throw e; | |
1010 | } el se { | |
1011 | // treat a s if we ha d received a close_n otify | |
1012 | closeInter nal(false) ; | |
1013 | continue; | |
1014 | } | |
1015 | } | |
1016 | ||
1017 | ||
1018 | /* | |
1019 | * The b asic SSLv3 record pr otection i nvolves (o ptional) | |
1020 | * encry ption for privacy, a nd an inte grity chec k ensuring | |
1021 | * data origin aut henticatio n. We do them both here, and | |
1022 | * throw a fatal a lert if th e integrit y check fa ils. | |
1023 | */ | |
1024 | try { | |
1025 | r.de crypt(read Authentica tor, readC ipher); | |
1026 | } catch (BadPaddin gException e) { | |
1027 | byte alertType = (r.cont entType() == Record. ct_handsha ke) | |
1028 | ? Alerts.a lert_hands hake_failu re | |
1029 | : Alerts.a lert_bad_r ecord_mac; | |
1030 | fata l(alertTyp e, e.getMe ssage(), e ); | |
1031 | } | |
1032 | ||
1033 | // if (! r.decompre ss(c)) | |
1034 | // f atal(Alert s.alert_de compressio n_failure, | |
1035 | // "decomp ression fa ilure"); | |
1036 | ||
1037 | /* | |
1038 | * Proce ss the rec ord. | |
1039 | */ | |
1040 | synchron ized (this ) { | |
1041 | switch (r.conten tType()) { | |
1042 | case Record.ct _handshake : | |
1043 | /* | |
1044 | * Handsha ke message s always g o to a pen ding sessi on | |
1045 | * handsha ker ... if there isn 't one, cr eate one. This | |
1046 | * must wo rk asynchr onously, f or renegot iation. | |
1047 | * | |
1048 | * NOTE th at handsha king will either res ume a sess ion | |
1049 | * which w as in the cache (and which mig ht have ot her | |
1050 | * connect ions in it already), or else w ill start a new | |
1051 | * session (new keys exchanged ) with jus t this con nection | |
1052 | * in it. | |
1053 | */ | |
1054 | initHandsh aker(); | |
1055 | if (!hands haker.acti vated()) { | |
1056 | // pri or to hand shaking, a ctivate th e handshak e | |
1057 | if (co nnectionSt ate == cs_ RENEGOTIAT E) { | |
1058 | // don't use SSLv2Hell o when ren egotiating | |
1059 | ha ndshaker.a ctivate(pr otocolVers ion); | |
1060 | } else { | |
1061 | ha ndshaker.a ctivate(nu ll); | |
1062 | } | |
1063 | } | |
1064 | ||
1065 | /* | |
1066 | * process the hands hake recor d ... may contain ju st | |
1067 | * a parti al handsha ke message or multip le message s. | |
1068 | * | |
1069 | * The han dshaker st ate machin e will ens ure that i t's | |
1070 | * a finis hed messag e. | |
1071 | */ | |
1072 | handshaker .process_r ecord(r, e xpectingFi nished); | |
1073 | expectingF inished = false; | |
1074 | ||
1075 | if (handsh aker.inval idated) { | |
1076 | handsh aker = nul l; | |
1077 | receiv edCCS = fa lse; | |
1078 | // if state is c s_RENEGOTI ATE, rever t it to cs _DATA | |
1079 | if (co nnectionSt ate == cs_ RENEGOTIAT E) { | |
1080 | co nnectionSt ate = cs_D ATA; | |
1081 | } | |
1082 | } else if (handshake r.isDone() ) { | |
1083 | // res et the par ameters fo r secure r enegotiati on. | |
1084 | secure Renegotiat ion = | |
1085 | handshaker .isSecureR enegotiati on(); | |
1086 | client VerifyData = handsha ker.getCli entVerifyD ata(); | |
1087 | server VerifyData = handsha ker.getSer verVerifyD ata(); | |
1088 | ||
1089 | sess = handshake r.getSessi on(); | |
1090 | handsh akeSession = null; | |
1091 | handsh aker = nul l; | |
1092 | connec tionState = cs_DATA; | |
1093 | receiv edCCS = fa lse; | |
1094 | ||
1095 | // | |
1096 | // Tel l folk abo ut handsha ke complet ion, but d o | |
1097 | // it in a separ ate thread . | |
1098 | // | |
1099 | if (ha ndshakeLis teners != null) { | |
1100 | Ha ndshakeCom pletedEven t event = | |
1101 | new Hand shakeCompl etedEvent( this, sess ); | |
1102 | ||
1103 | Th read t = n ew NotifyH andshakeTh read( | |
1104 | handshak eListeners .entrySet( ), event); | |
1105 | t. start(); | |
1106 | } | |
1107 | } | |
1108 | ||
1109 | if (needAp pData || c onnectionS tate != cs _DATA) { | |
1110 | contin ue; | |
1111 | } | |
1112 | break; | |
1113 | ||
1114 | case Record.ct _applicati on_data: | |
1115 | // Pass th is right b ack up to the applic ation. | |
1116 | if (connec tionState != cs_DATA | |
1117 | && connectio nState != cs_RENEGOT IATE | |
1118 | && connectio nState != cs_SENT_CL OSE) { | |
1119 | throw new SSLPro tocolExcep tion( | |
1120 | "D ata receiv ed in non- data state : " + | |
1121 | co nnectionSt ate); | |
1122 | } | |
1123 | if (expect ingFinishe d) { | |
1124 | throw new SSLPro tocolExcep tion | |
1125 | ("Expect ing finish ed message , received data"); | |
1126 | } | |
1127 | if (!needA ppData) { | |
1128 | throw new SSLExc eption("Di scarding a pp data"); | |
1129 | } | |
1130 | ||
1131 | r.setAppDa taValid(tr ue); | |
1132 | break; | |
1133 | ||
1134 | case Record.ct _alert: | |
1135 | recvAlert( r); | |
1136 | continue; | |
1137 | ||
1138 | case Record.ct _change_ci pher_spec: | |
1139 | if ((conne ctionState != cs_HAN DSHAKE | |
1140 | && conne ctionState != cs_REN EGOTIATE) | |
1141 | || !handshak er.session KeysCalcul ated() | |
1142 | || receivedC CS) { | |
1143 | // For the CCS m essage arr iving in t he wrong s tate | |
1144 | fatal( Alerts.ale rt_unexpec ted_messag e, | |
1145 | "illegal change ci pher spec msg, conn state = " | |
1146 | + connec tionState + ", hands hake state = " | |
1147 | + handsh aker.state ); | |
1148 | } else if (r.availab le() != 1 || r.read( ) != 1) { | |
1149 | // For structura l/content issues wit h the CCS | |
1150 | fatal( Alerts.ale rt_unexpec ted_messag e, | |
1151 | "Malform ed change cipher spe c msg"); | |
1152 | } | |
1153 | ||
1154 | // Once we 've receiv ed CCS, up date the f lag. | |
1155 | // If the remote end point send s it again in this h andshake | |
1156 | // we won' t process it. | |
1157 | receivedCC S = true; | |
1158 | ||
1159 | // | |
1160 | // The fir st message after a c hange_ciph er_spec | |
1161 | // record MUST be a "Finished" handshake record, | |
1162 | // else it 's a proto col violat ion. We f orce this | |
1163 | // to be c hecked by a minor tw eak to the state | |
1164 | // machine . | |
1165 | // | |
1166 | changeRead Ciphers(); | |
1167 | // next me ssage MUST be a fini shed messa ge | |
1168 | expectingF inished = true; | |
1169 | continue; | |
1170 | ||
1171 | defa ult: | |
1172 | // | |
1173 | // TLS req uires that unrecogni zed record s be ignor ed. | |
1174 | // | |
1175 | if (debug != null && Debug.isO n("ssl")) { | |
1176 | System .out.print ln(Thread. currentThr ead().getN ame() + | |
1177 | ", Received record typ e: " | |
1178 | + r.contentT ype()); | |
1179 | } | |
1180 | continue; | |
1181 | } // s witch | |
1182 | ||
1183 | /* | |
1184 | * Che ck the seq uence numb er state | |
1185 | * | |
1186 | * Not e that in order to m aintain th e connecti on I/O | |
1187 | * pro perly, we check the sequence n umber afte r the last | |
1188 | * rec ord readin g process. As we req uest reneg otiation | |
1189 | * or close the connection for wrapp ed sequenc e number | |
1190 | * whe n there is enough se quence num ber space left to | |
1191 | * han dle a few more recor ds, so the sequence number | |
1192 | * of the last r ecord cann ot be wrap ped. | |
1193 | */ | |
1194 | if (co nnectionSt ate < cs_E RROR) { | |
1195 | ch eckSequenc eNumber(re adAuthenti cator, r.c ontentType ()); | |
1196 | } | |
1197 | ||
1198 | return ; | |
1199 | } // syn chronized (this) | |
1200 | } | |
1201 | ||
1202 | // | |
1203 | // couldn't read, due to some ki nd of erro r | |
1204 | // | |
1205 | r. close(); | |
1206 | re turn; | |
1207 | } / / synchron ized (read Lock) | |
1208 | } | |
1209 | ||
1210 | /** | |
1211 | * Che ck the seq uence numb er state | |
1212 | * | |
1213 | * RFC 4346 stat es that, " Sequence n umbers are of type u int64 and | |
1214 | * may not excee d 2^64-1. Sequence numbers do not wrap. If a TLS | |
1215 | * imp lementatio n would ne ed to wrap a sequenc e number, it must | |
1216 | * ren egotiate i nstead." | |
1217 | */ | |
1218 | privat e void che ckSequence Number(Aut henticator authentic ator, byte type) | |
1219 | throws I OException { | |
1220 | ||
1221 | /* | |
1222 | * Don't bot her to che ck the seq uence numb er for err or or | |
1223 | * closed co nnections, or NULL M AC. | |
1224 | * / | |
1225 | if (connecti onState >= cs_ERROR || authent icator == MAC.NULL) { | |
1226 | return; | |
1227 | } | |
1228 | ||
1229 | /* | |
1230 | * Conservat ively, clo se the con nection im mediately when the | |
1231 | * sequence number is close to o verflow | |
1232 | * / | |
1233 | if (authenti cator.seqN umOverflow ()) { | |
1234 | /* | |
1235 | * TLS p rotocols d o not defi ne a error alert for sequence | |
1236 | * numbe r overflow . We use h andshake_f ailure err or alert | |
1237 | * for h andshaking and bad_r ecord_mac for other records. | |
1238 | */ | |
1239 | if (debu g != null && Debug.i sOn("ssl") ) { | |
1240 | Syst em.out.pri ntln(Threa d.currentT hread().ge tName() + | |
1241 | ", sequenc e number e xtremely c lose to ov erflow " + | |
1242 | "(2^64-1 p ackets). C losing con nection.") ; | |
1243 | ||
1244 | } | |
1245 | ||
1246 | fatal(Al erts.alert _handshake _failure, "sequence number ove rflow"); | |
1247 | } | |
1248 | ||
1249 | /* | |
1250 | * Ask for r enegotiati on when ne ed to rene w sequence number. | |
1251 | * | |
1252 | * Don't bot her to kic kstart the renegotia tion when the local is | |
1253 | * asking fo r it. | |
1254 | * / | |
1255 | if ((type != Record.ct _handshake ) && authe nticator.s eqNumIsHug e()) { | |
1256 | if (debu g != null && Debug.i sOn("ssl") ) { | |
1257 | Syst em.out.pri ntln(Threa d.currentT hread().ge tName() + | |
1258 | ", req uest reneg otiation " + | |
1259 | "to av oid sequen ce number overflow") ; | |
1260 | } | |
1261 | ||
1262 | startHan dshake(); | |
1263 | } | |
1264 | } | |
1265 | ||
1266 | // | |
1267 | // HAN DSHAKE REL ATED CODE | |
1268 | // | |
1269 | ||
1270 | /** | |
1271 | * Ret urn the Ap pInputStre am. For us e by Hands haker only . | |
1272 | */ | |
1273 | AppInp utStream g etAppInput Stream() { | |
1274 | re turn input ; | |
1275 | } | |
1276 | ||
1277 | /** | |
1278 | * Ret urn the Ap pOutputStr eam. For u se by Hand shaker onl y. | |
1279 | */ | |
1280 | AppOut putStream getAppOutp utStream() { | |
1281 | re turn outpu t; | |
1282 | } | |
1283 | ||
1284 | /** | |
1285 | * Ini tialize th e handshak er object. This mean s: | |
1286 | * | |
1287 | * . if a hands hake is al ready in p rogress (s tate is cs _HANDSHAKE | |
1288 | * or cs_RENE GOTIATE), do nothing and retur n | |
1289 | * | |
1290 | * . if the soc ket is alr eady close d, throw a n Exceptio n (interna l error) | |
1291 | * | |
1292 | * . otherwise (cs_START or cs_DATA ), create the approp riate hand shaker | |
1293 | * object, an d advance the connec tion state (to cs_HA NDSHAKE or | |
1294 | * cs_RENEGOT IATE, resp ectively). | |
1295 | * | |
1296 | * Thi s method i s called r ight after a new soc ket is cre ated, when | |
1297 | * sta rting rene gotiation, or when c hanging cl ient/ serv er mode of the | |
1298 | * soc ket. | |
1299 | */ | |
1300 | privat e void ini tHandshake r() { | |
1301 | sw itch (conn ectionStat e) { | |
1302 | ||
1303 | // | |
1304 | // Starting a new hand shake. | |
1305 | // | |
1306 | ca se cs_STAR T: | |
1307 | ca se cs_DATA : | |
1308 | break; | |
1309 | ||
1310 | // | |
1311 | // We're alr eady in th e middle o f a handsh ake. | |
1312 | // | |
1313 | ca se cs_HAND SHAKE: | |
1314 | ca se cs_RENE GOTIATE: | |
1315 | return; | |
1316 | ||
1317 | // | |
1318 | // Anyone al lowed to c all this r outine is required t o | |
1319 | // do so ONL Y if the c onnection state is r easonable. .. | |
1320 | // | |
1321 | de fault: | |
1322 | throw ne w IllegalS tateExcept ion("Inter nal error" ); | |
1323 | } | |
1324 | ||
1325 | // state is either cs_ START or c s_DATA | |
1326 | if (connecti onState == cs_START) { | |
1327 | connecti onState = cs_HANDSHA KE; | |
1328 | } else { // cs_DATA | |
1329 | connecti onState = cs_RENEGOT IATE; | |
1330 | } | |
1331 | if (roleIsSe rver) { | |
1332 | handshak er = new S erverHands haker(this , sslConte xt, | |
1333 | enabledPro tocols, do ClientAuth , | |
1334 | protocolVe rsion, con nectionSta te == cs_H ANDSHAKE, | |
1335 | secureRene gotiation, clientVer ifyData, s erverVerif yData); | |
1336 | handshak er.setSNIM atchers(sn iMatchers) ; | |
1337 | handshak er.setUseC ipherSuite sOrder(pre ferLocalCi pherSuites ); | |
1338 | } else { | |
1339 | handshak er = new C lientHands haker(this , sslConte xt, | |
1340 | enabledPro tocols, | |
1341 | protocolVe rsion, con nectionSta te == cs_H ANDSHAKE, | |
1342 | secureRene gotiation, clientVer ifyData, s erverVerif yData); | |
1343 | handshak er.setSNIS erverNames (serverNam es); | |
1344 | } | |
1345 | ha ndshaker.s etEnabledC ipherSuite s(enabledC ipherSuite s); | |
1346 | ha ndshaker.s etEnableSe ssionCreat ion(enable SessionCre ation); | |
1347 | } | |
1348 | ||
1349 | /** | |
1350 | * Syn chronously perform t he initial handshake . | |
1351 | * | |
1352 | * If the handsh ake is alr eady in pr ogress, th is method blocks unt il it | |
1353 | * is completed. If the in itial hand shake has already be en complet ed, | |
1354 | * it returns im mediately. | |
1355 | */ | |
1356 | privat e void per formInitia lHandshake () throws IOExceptio n { | |
1357 | // use hands hakeLock a nd the sta te check t o make sur e only | |
1358 | // one threa d performs the hands hake | |
1359 | sy nchronized (handshak eLock) { | |
1360 | if (getC onnectionS tate() == cs_HANDSHA KE) { | |
1361 | kick startHands hake(); | |
1362 | ||
1363 | /* | |
1364 | * A ll initial handshaki ng goes th rough this | |
1365 | * I nputRecord until we have a val id SSL con nection. | |
1366 | * O nce initia l handshak ing is fin ished, App InputStrea m's | |
1367 | * I nputRecord can handl e any futu re renegot iation. | |
1368 | * | |
1369 | * K eep this l ocal so th at it goes out of sc ope and is | |
1370 | * e ventually GC'd. | |
1371 | */ | |
1372 | if ( inrec == n ull) { | |
1373 | inrec = ne w InputRec ord(); | |
1374 | ||
1375 | /* | |
1376 | * Grab th e characte ristics al ready assi gned to | |
1377 | * AppInpu tStream's InputRecor d. Enable checking for | |
1378 | * SSLv2 h ellos on t his first handshake. | |
1379 | */ | |
1380 | inrec.setH andshakeHa sh(input.r .getHandsh akeHash()) ; | |
1381 | inrec.setH elloVersio n(input.r. getHelloVe rsion()); | |
1382 | inrec.enab leFormatCh ecks(); | |
1383 | } | |
1384 | ||
1385 | read Record(inr ec, false) ; | |
1386 | inre c = null; | |
1387 | } | |
1388 | } | |
1389 | } | |
1390 | ||
1391 | /** | |
1392 | * Sta rts an SSL handshake on this c onnection. | |
1393 | */ | |
1394 | @Overr ide | |
1395 | public void star tHandshake () throws IOExceptio n { | |
1396 | // start an ssl handsh ake that c ould be re sumed from timeout e xception | |
1397 | st artHandsha ke(true); | |
1398 | } | |
1399 | ||
1400 | /** | |
1401 | * Sta rts an ssl handshake on this c onnection. | |
1402 | * | |
1403 | * @pa ram resuma ble indica tes the ha ndshake pr ocess is r esumable f rom a | |
1404 | * cert ain except ion. If <c ode>resuma ble</code> , the sock et will | |
1405 | * be r eserved fo r exceptio ns like ti meout; oth erwise, th e socket | |
1406 | * will be closed , no furth er communi cations co uld be don e. | |
1407 | */ | |
1408 | privat e void sta rtHandshak e(boolean resumable) throws IO Exception { | |
1409 | ch eckWrite() ; | |
1410 | tr y { | |
1411 | if (getC onnectionS tate() == cs_HANDSHA KE) { | |
1412 | // d o initial handshake | |
1413 | perf ormInitial Handshake( ); | |
1414 | } else { | |
1415 | // s tart reneg otiation | |
1416 | kick startHands hake(); | |
1417 | } | |
1418 | } catch (Exc eption e) { | |
1419 | // shutd own and re throw (wra pped) exce ption as a ppropriate | |
1420 | handleEx ception(e, resumable ); | |
1421 | } | |
1422 | } | |
1423 | ||
1424 | /** | |
1425 | * Kic kstart the handshake if it is not alread y in progr ess. | |
1426 | * Thi s means: | |
1427 | * | |
1428 | * . if handsha king is al ready unde rway, do n othing and return | |
1429 | * | |
1430 | * . if the soc ket is not connected or alread y closed, throw an | |
1431 | * Exception. | |
1432 | * | |
1433 | * . otherwise, call init Handshake( ) to initi alize the handshaker | |
1434 | * object and progress the state. Then, sen d the init ial | |
1435 | * handshakin g message if appropr iate (alwa ys on clie nts and | |
1436 | * on servers when rene gotiating) . | |
1437 | */ | |
1438 | privat e synchron ized void kickstartH andshake() throws IO Exception { | |
1439 | ||
1440 | sw itch (conn ectionStat e) { | |
1441 | ||
1442 | ca se cs_HAND SHAKE: | |
1443 | // hands haker alre ady setup, proceed | |
1444 | break; | |
1445 | ||
1446 | ca se cs_DATA : | |
1447 | if (!sec ureRenegot iation && !Handshake r.allowUns afeRenegot iation) { | |
1448 | thro w new SSLH andshakeEx ception( | |
1449 | "Insec ure renego tiation is not allow ed"); | |
1450 | } | |
1451 | ||
1452 | if (!sec ureRenegot iation) { | |
1453 | if ( debug != n ull && Deb ug.isOn("h andshake") ) { | |
1454 | System.out .println( | |
1455 | "Warni ng: Using insecure r enegotiati on"); | |
1456 | } | |
1457 | } | |
1458 | ||
1459 | // initi alize the handshaker , move to cs_RENEGOT IATE | |
1460 | initHand shaker(); | |
1461 | break; | |
1462 | ||
1463 | ca se cs_RENE GOTIATE: | |
1464 | // hands haking alr eady in pr ogress, re turn | |
1465 | return; | |
1466 | ||
1467 | /* | |
1468 | * The only way to get a socket in the sta te is when | |
1469 | * you have an unconne cted socke t. | |
1470 | * / | |
1471 | ca se cs_STAR T: | |
1472 | throw ne w SocketEx ception( | |
1473 | "han dshaking a ttempted o n unconnec ted socket "); | |
1474 | ||
1475 | de fault: | |
1476 | throw ne w SocketEx ception("c onnection is closed" ); | |
1477 | } | |
1478 | ||
1479 | // | |
1480 | // Kickstart handshake state mac hine if we need to . .. | |
1481 | // | |
1482 | // Note that handshake r.kickstar t() writes the messa ge | |
1483 | // to its Ha ndshakeOut Stream, wh ich calls back into | |
1484 | // SSLSocket Impl.write Record() t o send it. | |
1485 | // | |
1486 | if (!handsha ker.activa ted()) { | |
1487 | // prio r to hands haking, ac tivate the handshake | |
1488 | if (conn ectionStat e == cs_RE NEGOTIATE) { | |
1489 | // d on't use S SLv2Hello when reneg otiating | |
1490 | hand shaker.act ivate(prot ocolVersio n); | |
1491 | } else { | |
1492 | hand shaker.act ivate(null ); | |
1493 | } | |
1494 | ||
1495 | if (hand shaker ins tanceof Cl ientHandsh aker) { | |
1496 | // s end client hello | |
1497 | hand shaker.kic kstart(); | |
1498 | } else { | |
1499 | if ( connection State == c s_HANDSHAK E) { | |
1500 | // initial handshake , no kicks tart messa ge to send | |
1501 | } el se { | |
1502 | // we want to renego tiate, sen d hello re quest | |
1503 | handshaker .kickstart (); | |
1504 | // hello r equest is not includ ed in the handshake | |
1505 | // hashes, reset the m | |
1506 | handshaker .handshake Hash.reset (); | |
1507 | } | |
1508 | } | |
1509 | } | |
1510 | } | |
1511 | ||
1512 | // | |
1513 | // CLO SURE RELAT ED CALLS | |
1514 | // | |
1515 | ||
1516 | /** | |
1517 | * Ret urn whethe r the sock et has bee n explicit ly closed by the app lication. | |
1518 | */ | |
1519 | @Overr ide | |
1520 | public boolean i sClosed() { | |
1521 | re turn conne ctionState == cs_APP _CLOSED; | |
1522 | } | |
1523 | ||
1524 | /** | |
1525 | * Ret urn whethe r we have reached en d-of-file. | |
1526 | * | |
1527 | * If the socket is not co nnected, h as been sh utdown bec ause of an error | |
1528 | * or has been c losed, thr ow an Exce ption. | |
1529 | */ | |
1530 | boolea n checkEOF () throws IOExceptio n { | |
1531 | sw itch (getC onnectionS tate()) { | |
1532 | ca se cs_STAR T: | |
1533 | throw ne w SocketEx ception("S ocket is n ot connect ed"); | |
1534 | ||
1535 | ca se cs_HAND SHAKE: | |
1536 | ca se cs_DATA : | |
1537 | ca se cs_RENE GOTIATE: | |
1538 | ca se cs_SENT _CLOSE: | |
1539 | return f alse; | |
1540 | ||
1541 | ca se cs_APP_ CLOSED: | |
1542 | throw ne w SocketEx ception("S ocket is c losed"); | |
1543 | ||
1544 | ca se cs_ERRO R: | |
1545 | ca se cs_CLOS ED: | |
1546 | de fault: | |
1547 | // eithe r closed b ecause of error, or normal EOF | |
1548 | if (clos eReason == null) { | |
1549 | retu rn true; | |
1550 | } | |
1551 | IOExcept ion e = ne w SSLExcep tion | |
1552 | ("Conn ection has been shut down: " + closeReaso n); | |
1553 | e.initCa use(closeR eason); | |
1554 | throw e; | |
1555 | ||
1556 | } | |
1557 | } | |
1558 | ||
1559 | /** | |
1560 | * Che ck if we c an write d ata to thi s socket. If not, th row an IOE xception. | |
1561 | */ | |
1562 | void c heckWrite( ) throws I OException { | |
1563 | if (checkEOF () || (get Connection State() == cs_SENT_C LOSE)) { | |
1564 | // we ar e at EOF, write must throw Exc eption | |
1565 | throw ne w SocketEx ception("C onnection closed by remote hos t"); | |
1566 | } | |
1567 | } | |
1568 | ||
1569 | protec ted void c loseSocket () throws IOExceptio n { | |
1570 | ||
1571 | if ((debug ! = null) && Debug.isO n("ssl")) { | |
1572 | System.o ut.println (Thread.cu rrentThrea d().getNam e() + | |
1573 | ", called cl oseSocket( )"); | |
1574 | } | |
1575 | ||
1576 | su per.close( ); | |
1577 | } | |
1578 | ||
1579 | privat e void clo seSocket(b oolean sel fInitiated ) throws I OException { | |
1580 | if ((debug ! = null) && Debug.isO n("ssl")) { | |
1581 | System.o ut.println (Thread.cu rrentThrea d().getNam e() + | |
1582 | ", c alled clos eSocket(" + selfInit iated + ") "); | |
1583 | } | |
1584 | if (!isLayer ed() || au toClose) { | |
1585 | super.cl ose(); | |
1586 | } else if (s elfInitiat ed) { | |
1587 | // layer ed && non- autoclose | |
1588 | // read close_noti fy alert t o clear in put stream | |
1589 | waitForC lose(false ); | |
1590 | } | |
1591 | } | |
1592 | ||
1593 | /* | |
1594 | * Clo sing the c onnection is tricky ... we can 't officia lly close the | |
1595 | * con nection un til we kno w the othe r end is r eady to go away too, | |
1596 | * and if ever t he connect ion gets a borted we must forge t session | |
1597 | * sta te (it bec omes inval id). | |
1598 | */ | |
1599 | ||
1600 | /** | |
1601 | * Clo ses the SS L connecti on. SSL i ncludes an applicati on level | |
1602 | * shu tdown hand shake; you should cl ose SSL so ckets expl icitly | |
1603 | * rat her than l eaving it for finali zation, so that your remote | |
1604 | * pee r does not experienc e a protoc ol error. | |
1605 | */ | |
1606 | @Overr ide | |
1607 | public void clos e() throws IOExcepti on { | |
1608 | if ((debug ! = null) && Debug.isO n("ssl")) { | |
1609 | System.o ut.println (Thread.cu rrentThrea d().getNam e() + | |
1610 | ", calle d close()" ); | |
1611 | } | |
1612 | cl oseInterna l(true); // caller is initiat ing close | |
1613 | se tConnectio nState(cs_ APP_CLOSED ); | |
1614 | } | |
1615 | ||
1616 | /** | |
1617 | * Don 't synchro nize the w hole metho d because waitForClo se() | |
1618 | * (wh ich calls readRecord ()) might be called. | |
1619 | * | |
1620 | * @pa ram selfIn itiated In dicates wh ich party initiated the close. | |
1621 | * If selfInitia ted, this side is in itiating a close; fo r layered and | |
1622 | * non -autoclose socket, w ait for cl ose_notify response. | |
1623 | * If !selfIniti ated, peer sent clos e_notify; we recipro cate but | |
1624 | * no need to wa it for res ponse. | |
1625 | */ | |
1626 | privat e void clo seInternal (boolean s elfInitiat ed) throws IOExcepti on { | |
1627 | if ((debug ! = null) && Debug.isO n("ssl")) { | |
1628 | System.o ut.println (Thread.cu rrentThrea d().getNam e() + | |
1629 | ", cal led closeI nternal(" + selfInit iated + ") "); | |
1630 | } | |
1631 | ||
1632 | in t state = getConnect ionState() ; | |
1633 | bo olean clos eSocketCal led = fals e; | |
1634 | Th rowable ca chedThrowa ble = null ; | |
1635 | tr y { | |
1636 | switch ( state) { | |
1637 | case cs_ START: | |
1638 | // u nconnected socket or handshaki ng has not been init ialized | |
1639 | clos eSocket(se lfInitiate d); | |
1640 | brea k; | |
1641 | ||
1642 | /* | |
1643 | * If we 're closin g down due to error, we alread y sent (or else | |
1644 | * recei ved) the f atal alert ... no ni ceties, bl ow the con nection | |
1645 | * away as quickly as possib le (even i f we didn' t allocate the | |
1646 | * socke t ourselve s; it's un usable, re gardless). | |
1647 | */ | |
1648 | case cs_ ERROR: | |
1649 | clos eSocket(); | |
1650 | brea k; | |
1651 | ||
1652 | /* | |
1653 | * Somet imes close () gets ca lled more than once. | |
1654 | */ | |
1655 | case cs_ CLOSED: | |
1656 | case cs_ APP_CLOSED : | |
1657 | bre ak; | |
1658 | ||
1659 | /* | |
1660 | * Other wise we in dicate cle an termina tion. | |
1661 | */ | |
1662 | // case cs_HANDSHA KE: | |
1663 | // case cs_DATA: | |
1664 | // case cs_RENEGOT IATE: | |
1665 | // case cs_SENT_CL OSE: | |
1666 | default: | |
1667 | sync hronized ( this) { | |
1668 | if (((stat e = getCon nectionSta te()) == c s_CLOSED) || | |
1669 | (state == cs_ERRO R) || (sta te == cs_A PP_CLOSED) ) { | |
1670 | return ; // conn ection was closed wh ile we wai ted | |
1671 | } | |
1672 | if (state != cs_SENT _CLOSE) { | |
1673 | try { | |
1674 | wa rning(Aler ts.alert_c lose_notif y); | |
1675 | co nnectionSt ate = cs_S ENT_CLOSE; | |
1676 | } catc h (Throwab le th) { | |
1677 | // we need t o ensure s ocket is c losed out | |
1678 | // if we enc ounter any errors. | |
1679 | co nnectionSt ate = cs_E RROR; | |
1680 | // cache thi s for late r use | |
1681 | ca chedThrowa ble = th; | |
1682 | cl oseSocketC alled = tr ue; | |
1683 | cl oseSocket( selfInitia ted); | |
1684 | } | |
1685 | } | |
1686 | } | |
1687 | // I f state wa s cs_SENT_ CLOSE befo re, we don 't do the actual | |
1688 | // c losing sin ce it is a lready in progress. | |
1689 | if ( state == c s_SENT_CLO SE) { | |
1690 | if (debug != null && Debug.isO n("ssl")) { | |
1691 | System .out.print ln(Thread. currentThr ead().getN ame() + | |
1692 | ", close inv oked again ; state = " + | |
1693 | ge tConnectio nState()); | |
1694 | } | |
1695 | if (selfIn itiated == false) { | |
1696 | // We were calle d because a close_no tify messa ge was | |
1697 | // rec eived. Thi s may be d ue to anot her thread calling | |
1698 | // rea d() or due to our ca ll to wait ForClose() below. | |
1699 | // In either cas e, just re turn. | |
1700 | return ; | |
1701 | } | |
1702 | // Another thread ex plicitly c alled clos e(). We ne ed to | |
1703 | // wait fo r the clos ing to com plete befo re returni ng. | |
1704 | synchroniz ed (this) { | |
1705 | while (connectio nState < c s_CLOSED) { | |
1706 | tr y { | |
1707 | this.wai t(); | |
1708 | } catch (Int erruptedEx ception e) { | |
1709 | // ignor e | |
1710 | } | |
1711 | } | |
1712 | } | |
1713 | if ((debug != null) && Debug.i sOn("ssl") ) { | |
1714 | System .out.print ln(Thread. currentThr ead().getN ame() + | |
1715 | ", after pri mary close ; state = " + | |
1716 | ge tConnectio nState()); | |
1717 | } | |
1718 | return; | |
1719 | } | |
1720 | ||
1721 | if ( !closeSock etCalled) { | |
1722 | closeSocke tCalled = true; | |
1723 | closeSocke t(selfInit iated); | |
1724 | } | |
1725 | ||
1726 | brea k; | |
1727 | } | |
1728 | } finally { | |
1729 | synchron ized (this ) { | |
1730 | // U pon exit f rom this m ethod, the state is always >= cs_CLOSED | |
1731 | conn ectionStat e = (conne ctionState == cs_APP _CLOSED) | |
1732 | ? cs_APP _CLOSED : cs_CLOSED; | |
1733 | // n otify any threads wa iting for the closin g to finis h | |
1734 | this .notifyAll (); | |
1735 | } | |
1736 | if (clos eSocketCal led) { | |
1737 | // D ispose of ciphers si nce we've closed soc ket | |
1738 | disp oseCiphers (); | |
1739 | } | |
1740 | if (cach edThrowabl e != null) { | |
1741 | /* | |
1742 | * Re throw the error to t he calling method | |
1743 | * Th e Throwabl e caught c an only be an Error or Runtime Exception | |
1744 | */ | |
1745 | if ( cachedThro wable inst anceof Err or) | |
1746 | throw (Err or) cached Throwable; | |
1747 | if ( cachedThro wable inst anceof Run timeExcept ion) | |
1748 | throw (Run timeExcept ion) cache dThrowable ; | |
1749 | } | |
1750 | } | |
1751 | } | |
1752 | ||
1753 | /** | |
1754 | * Rea ds a close _notify or a fatal a lert from the input stream. | |
1755 | * Kee p reading records un til we get a close_n otify or u ntil | |
1756 | * the connectio n is other wise close d. The cl ose_notify or alert | |
1757 | * mig ht be read by anothe r reader, | |
1758 | * whi ch will th en process the close and set t he connect ion state. | |
1759 | */ | |
1760 | void w aitForClos e(boolean rethrow) t hrows IOEx ception { | |
1761 | if (debug != null && D ebug.isOn( "ssl")) { | |
1762 | System.o ut.println (Thread.cu rrentThrea d().getNam e() + | |
1763 | ", w aiting for close_not ify or ale rt: state " | |
1764 | + ge tConnectio nState()); | |
1765 | } | |
1766 | ||
1767 | tr y { | |
1768 | int stat e; | |
1769 | ||
1770 | while (( (state = g etConnecti onState()) != cs_CLO SED) && | |
1771 | ( state != c s_ERROR) & & (state ! = cs_APP_C LOSED)) { | |
1772 | // c reate the InputRecor d if it is n't initia lized. | |
1773 | if ( inrec == n ull) { | |
1774 | inrec = ne w InputRec ord(); | |
1775 | } | |
1776 | ||
1777 | // A sk for app data and then throw it away | |
1778 | try { | |
1779 | readRecord (inrec, tr ue); | |
1780 | } ca tch (Socke tTimeoutEx ception e) { | |
1781 | // if time out, igno re the exc eption and continue | |
1782 | } | |
1783 | } | |
1784 | inrec = null; | |
1785 | } catch (IOE xception e ) { | |
1786 | if (debu g != null && Debug.i sOn("ssl") ) { | |
1787 | Syst em.out.pri ntln(Threa d.currentT hread().ge tName() + | |
1788 | ", Excepti on while w aiting for close " + e); | |
1789 | } | |
1790 | if (reth row) { | |
1791 | thro w e; // pa ss excepti on up | |
1792 | } | |
1793 | } | |
1794 | } | |
1795 | ||
1796 | /** | |
1797 | * Cal led by clo seInternal () only. B e sure to consider t he | |
1798 | * syn chronizati on locks c arefully b efore call ing it els ewhere. | |
1799 | */ | |
1800 | privat e void dis poseCipher s() { | |
1801 | // See comme nt in chan geReadCiph ers() | |
1802 | sy nchronized (readLock ) { | |
1803 | readCiph er.dispose (); | |
1804 | } | |
1805 | // See comme nt in chan geReadCiph ers() | |
1806 | wr iteLock.lo ck(); | |
1807 | tr y { | |
1808 | writeCip her.dispos e(); | |
1809 | } finally { | |
1810 | writeLoc k.unlock() ; | |
1811 | } | |
1812 | } | |
1813 | ||
1814 | // | |
1815 | // EXC EPTION AND ALERT HAN DLING | |
1816 | // | |
1817 | ||
1818 | /** | |
1819 | * Han dle an exc eption. Th is method is called by top lev el excepti on | |
1820 | * han dlers (in read(), wr ite()) to make sure we always shutdown t he | |
1821 | * con nection co rrectly an d do not p ass runtim e exceptio n to the | |
1822 | * app lication. | |
1823 | */ | |
1824 | void h andleExcep tion(Excep tion e) th rows IOExc eption { | |
1825 | ha ndleExcept ion(e, tru e); | |
1826 | } | |
1827 | ||
1828 | /** | |
1829 | * Han dle an exc eption. Th is method is called by top lev el excepti on | |
1830 | * han dlers (in read(), wr ite(), sta rtHandshak e()) to ma ke sure we | |
1831 | * alw ays shutdo wn the con nection co rrectly an d do not p ass runtim e | |
1832 | * exc eption to the applic ation. | |
1833 | * | |
1834 | * Thi s method n ever retur ns normall y, it alwa ys throws an IOExcep tion. | |
1835 | * | |
1836 | * We first chec k if the s ocket has already be en shutdow n because of an | |
1837 | * err or. If so, we just r ethrow the exception . If the s ocket has not | |
1838 | * bee n shutdown , we sent a fatal al ert and re member the exception . | |
1839 | * | |
1840 | * @pa ram e the Exception | |
1841 | * @pa ram resuma ble indica tes the ca ller proce ss is resu mable from the | |
1842 | * exce ption. If <code>resu mable</cod e>, the so cket will be | |
1843 | * rese rved for e xceptions like timeo ut; otherw ise, the s ocket | |
1844 | * will be closed , no furth er communi cations co uld be don e. | |
1845 | */ | |
1846 | synchr onized pri vate void handleExce ption(Exce ption e, b oolean res umable) | |
1847 | th rows IOExc eption { | |
1848 | if ((debug ! = null) && Debug.isO n("ssl")) { | |
1849 | System.o ut.println (Thread.cu rrentThrea d().getNam e() + | |
1850 | ", han dling exce ption: " + e.toStrin g()); | |
1851 | } | |
1852 | ||
1853 | // don't clo se the Soc ket in cas e of timeo uts or int errupts if | |
1854 | // the proce ss is resu mable. | |
1855 | if (e instan ceof Inter ruptedIOEx ception && resumable ) { | |
1856 | throw (I OException )e; | |
1857 | } | |
1858 | ||
1859 | // if we've already sh utdown bec ause of an error, | |
1860 | // there is nothing to do except rethrow t he excepti on | |
1861 | if (closeRea son != nul l) { | |
1862 | if (e in stanceof I OException ) { // inc ludes SSLE xception | |
1863 | thro w (IOExcep tion)e; | |
1864 | } else { | |
1865 | // t his is odd , not an I OException . | |
1866 | // n ormally, t his should not happe n | |
1867 | // i f closeRea son has be en already been set | |
1868 | thro w Alerts.g etSSLExcep tion(Alert s.alert_in ternal_err or, e, | |
1869 | "U nexpected exception" ); | |
1870 | } | |
1871 | } | |
1872 | ||
1873 | // need to p erform err or shutdow n | |
1874 | bo olean isSS LException = (e inst anceof SSL Exception) ; | |
1875 | if ((isSSLEx ception == false) && (e instan ceof IOExc eption)) { | |
1876 | // IOExc eption fro m the sock et | |
1877 | // this means the TCP connec tion is al ready dead | |
1878 | // we ca ll fatal j ust to set the error status | |
1879 | try { | |
1880 | fata l(Alerts.a lert_unexp ected_mess age, e); | |
1881 | } catch (IOExcepti on ee) { | |
1882 | // i gnore (IOE xception w rapped in SSLExcepti on) | |
1883 | } | |
1884 | // rethr ow origina l IOExcept ion | |
1885 | throw (I OException )e; | |
1886 | } | |
1887 | ||
1888 | // must be S SLExceptio n or Runti meExceptio n | |
1889 | by te alertTy pe; | |
1890 | if (isSSLExc eption) { | |
1891 | if (e in stanceof S SLHandshak eException ) { | |
1892 | aler tType = Al erts.alert _handshake _failure; | |
1893 | } else { | |
1894 | aler tType = Al erts.alert _unexpecte d_message; | |
1895 | } | |
1896 | } else { | |
1897 | alertTyp e = Alerts .alert_int ernal_erro r; | |
1898 | } | |
1899 | fa tal(alertT ype, e); | |
1900 | } | |
1901 | ||
1902 | /* | |
1903 | * Sen d a warnin g alert. | |
1904 | */ | |
1905 | void w arning(byt e descript ion) { | |
1906 | se ndAlert(Al erts.alert _warning, descriptio n); | |
1907 | } | |
1908 | ||
1909 | synchr onized voi d fatal(by te descrip tion, Stri ng diagnos tic) | |
1910 | throws I OException { | |
1911 | fa tal(descri ption, dia gnostic, n ull); | |
1912 | } | |
1913 | ||
1914 | synchr onized voi d fatal(by te descrip tion, Thro wable caus e) | |
1915 | throws I OException { | |
1916 | fa tal(descri ption, nul l, cause); | |
1917 | } | |
1918 | ||
1919 | /* | |
1920 | * Sen d a fatal alert, and throw an exception so that ca llers will | |
1921 | * nee d to stand on their heads to a ccidentall y continue processin g. | |
1922 | */ | |
1923 | synchr onized voi d fatal(by te descrip tion, Stri ng diagnos tic, | |
1924 | Throwabl e cause) t hrows IOEx ception { | |
1925 | if ((input ! = null) && (input.r != null)) { | |
1926 | input.r. close(); | |
1927 | } | |
1928 | se ss.invalid ate(); | |
1929 | if (handshak eSession ! = null) { | |
1930 | handshak eSession.i nvalidate( ); | |
1931 | } | |
1932 | ||
1933 | in t oldState = connect ionState; | |
1934 | if (connecti onState < cs_ERROR) { | |
1935 | connecti onState = cs_ERROR; | |
1936 | } | |
1937 | ||
1938 | /* | |
1939 | * Has there been an e rror recei ved yet? If not, re member it. | |
1940 | * By RFC 22 46, we don 't bother waiting fo r a respon se. | |
1941 | * Fatal err ors requir e immediat e shutdown . | |
1942 | * / | |
1943 | if (closeRea son == nul l) { | |
1944 | /* | |
1945 | * Try t o clear th e kernel b uffer to a void TCP c onnection resets. | |
1946 | */ | |
1947 | if (oldS tate == cs _HANDSHAKE ) { | |
1948 | sock Input.skip (sockInput .available ()); | |
1949 | } | |
1950 | ||
1951 | // If th e descript ion equals -1, the a lert won't be sent t o peer. | |
1952 | if (desc ription != -1) { | |
1953 | send Alert(Aler ts.alert_f atal, desc ription); | |
1954 | } | |
1955 | if (caus e instance of SSLExce ption) { / / only tru e if != nu ll | |
1956 | clos eReason = (SSLExcept ion)cause; | |
1957 | } else { | |
1958 | clos eReason = | |
1959 | Alerts.get SSLExcepti on(descrip tion, caus e, diagnos tic); | |
1960 | } | |
1961 | } | |
1962 | ||
1963 | /* | |
1964 | * Clean up our side. | |
1965 | * / | |
1966 | cl oseSocket( ); | |
1967 | // Another t hread may have dispo sed the ci phers duri ng closing | |
1968 | if (connecti onState < cs_CLOSED) { | |
1969 | connecti onState = (oldState == cs_APP_ CLOSED) ? cs_APP_CLO SED | |
1970 | : cs_CLO SED; | |
1971 | ||
1972 | // We sh ould lock readLock a nd writeLo ck if no d eadlock ri sks. | |
1973 | // See c omment in changeRead Ciphers() | |
1974 | readCiph er.dispose (); | |
1975 | writeCip her.dispos e(); | |
1976 | } | |
1977 | ||
1978 | th row closeR eason; | |
1979 | } | |
1980 | ||
1981 | ||
1982 | /* | |
1983 | * Pro cess an in coming ale rt ... cal ler must a lready hav e synchron ized | |
1984 | * acc ess to "th is". | |
1985 | */ | |
1986 | privat e void rec vAlert(Inp utRecord r ) throws I OException { | |
1987 | by te level = (byte)r.r ead(); | |
1988 | by te descrip tion = (by te)r.read( ); | |
1989 | if (descript ion == -1) { // chec k for shor t message | |
1990 | fatal(Al erts.alert _illegal_p arameter, "Short ale rt message "); | |
1991 | } | |
1992 | ||
1993 | if (debug != null && ( Debug.isOn ("record") || | |
1994 | Debu g.isOn("ha ndshake")) ) { | |
1995 | synchron ized (Syst em.out) { | |
1996 | Syst em.out.pri nt(Thread. currentThr ead().getN ame()); | |
1997 | Syst em.out.pri nt(", RECV " + proto colVersion + " ALERT : "); | |
1998 | if ( level == A lerts.aler t_fatal) { | |
1999 | System.out .print("fa tal, "); | |
2000 | } el se if (lev el == Aler ts.alert_w arning) { | |
2001 | System.out .print("wa rning, "); | |
2002 | } el se { | |
2003 | System.out .print("<l evel " + ( 0x0ff & le vel) + ">, "); | |
2004 | } | |
2005 | Syst em.out.pri ntln(Alert s.alertDes cription(d escription )); | |
2006 | } | |
2007 | } | |
2008 | ||
2009 | if (level == Alerts.al ert_warnin g) { | |
2010 | if (desc ription == Alerts.al ert_close_ notify) { | |
2011 | if ( connection State == c s_HANDSHAK E) { | |
2012 | fatal(Aler ts.alert_u nexpected_ message, | |
2013 | "Receive d close_no tify durin g handshak e"); | |
2014 | } el se { | |
2015 | closeInter nal(false) ; // repl y to close | |
2016 | } | |
2017 | } else { | |
2018 | ||
2019 | // | |
2020 | // T he other l egal warni ngs relate to certif icates, | |
2021 | // e .g. no_cer tificate, bad_certif icate, etc ; these | |
2022 | // a re importa nt to the handshakin g code, wh ich can | |
2023 | // a lso handle illegal p rotocol al erts if ne eded. | |
2024 | // | |
2025 | if ( handshaker != null) { | |
2026 | handshaker .handshake Alert(desc ription); | |
2027 | } | |
2028 | } | |
2029 | } else { // fatal or u nknown lev el | |
2030 | String r eason = "R eceived fa tal alert: " | |
2031 | + Al erts.alert Descriptio n(descript ion); | |
2032 | if (clos eReason == null) { | |
2033 | clos eReason = Alerts.get SSLExcepti on(descrip tion, reas on); | |
2034 | } | |
2035 | fatal(Al erts.alert _unexpecte d_message, reason); | |
2036 | } | |
2037 | } | |
2038 | ||
2039 | ||
2040 | /* | |
2041 | * Emi t alerts. Caller mu st have sy nchronized with "thi s". | |
2042 | */ | |
2043 | privat e void sen dAlert(byt e level, b yte descri ption) { | |
2044 | // the conne ctionState cannot be cs_START | |
2045 | if (connecti onState >= cs_SENT_C LOSE) { | |
2046 | return; | |
2047 | } | |
2048 | ||
2049 | // For initi al handsha king, don' t send ale rt message to peer i f | |
2050 | // handshake r has not started. | |
2051 | if (connecti onState == cs_HANDSH AKE && | |
2052 | (handsha ker == nul l || !hand shaker.sta rted())) { | |
2053 | return; | |
2054 | } | |
2055 | ||
2056 | Ou tputRecord r = new O utputRecor d(Record.c t_alert); | |
2057 | r. setVersion (protocolV ersion); | |
2058 | ||
2059 | bo olean useD ebug = deb ug != null && Debug. isOn("ssl" ); | |
2060 | if (useDebug ) { | |
2061 | synchron ized (Syst em.out) { | |
2062 | Syst em.out.pri nt(Thread. currentThr ead().getN ame()); | |
2063 | Syst em.out.pri nt(", SEND " + proto colVersion + " ALERT : "); | |
2064 | if ( level == A lerts.aler t_fatal) { | |
2065 | System.out .print("fa tal, "); | |
2066 | } el se if (lev el == Aler ts.alert_w arning) { | |
2067 | System.out .print("wa rning, "); | |
2068 | } el se { | |
2069 | System.out .print("<l evel = " + (0x0ff & level) + " >, "); | |
2070 | } | |
2071 | Syst em.out.pri ntln("desc ription = " | |
2072 | + Aler ts.alertDe scription( descriptio n)); | |
2073 | } | |
2074 | } | |
2075 | ||
2076 | r. write(leve l); | |
2077 | r. write(desc ription); | |
2078 | tr y { | |
2079 | writeRec ord(r); | |
2080 | } catch (IOE xception e ) { | |
2081 | if (useD ebug) { | |
2082 | Syst em.out.pri ntln(Threa d.currentT hread().ge tName() + | |
2083 | ", Excepti on sending alert: " + e); | |
2084 | } | |
2085 | } | |
2086 | } | |
2087 | ||
2088 | // | |
2089 | // VAR IOUS OTHER METHODS | |
2090 | // | |
2091 | ||
2092 | /* | |
2093 | * Whe n a connec tion finis hes handsh aking by e nabling us e of a new ly | |
2094 | * neg otiated se ssion, eac h end lear ns about i t in two h alves (rea d, | |
2095 | * and write). When both read and w rite ciphe rs have ch anged, and the | |
2096 | * las t handshak e message has been r ead, the c onnection has joined | |
2097 | * (re joined) th e new sess ion. | |
2098 | * | |
2099 | * NOT E: The SS Lv3 spec i s rather u nclear on the concep ts here. | |
2100 | * Ses sions don' t change o nce they'r e establis hed (inclu ding ciphe r | |
2101 | * suite an d master PW ) but conn ections ca n join the m (and lea ve | |
2102 | * the m). They' re created by handsh aking, tho ugh someti me handsha king | |
2103 | * cau ses connec tions to j oin up wit h pre-esta blished se ssions. | |
2104 | */ | |
2105 | privat e void cha ngeReadCip hers() thr ows SSLExc eption { | |
2106 | if (connecti onState != cs_HANDSH AKE | |
2107 | && c onnectionS tate != cs _RENEGOTIA TE) { | |
2108 | throw ne w SSLProto colExcepti on( | |
2109 | "Sta te error, change cip her specs" ); | |
2110 | } | |
2111 | ||
2112 | // ... creat e decompre ssor | |
2113 | ||
2114 | Ci pherBox ol dCipher = readCipher ; | |
2115 | ||
2116 | tr y { | |
2117 | readCiph er = hands haker.newR eadCipher( ); | |
2118 | readAuth enticator = handshak er.newRead Authentica tor(); | |
2119 | } catch (Gen eralSecuri tyExceptio n e) { | |
2120 | // "can' t happen" | |
2121 | throw ne w SSLExcep tion("Algo rithm miss ing: ", e ); | |
2122 | } | |
2123 | ||
2124 | /* | |
2125 | * Dispose o f any inte rmediate s tate in th e underlyi ng cipher. | |
2126 | * For PKCS1 1 ciphers, this will release a ny attache d sessions , | |
2127 | * and thus make final ization fa ster. | |
2128 | * | |
2129 | * Since MAC 's doFinal () is call ed for eve ry SSL/TLS packet, i t's | |
2130 | * not neces sary to do the same with MAC's . | |
2131 | * / | |
2132 | ol dCipher.di spose(); | |
2133 | } | |
2134 | ||
2135 | // use d by Hands haker | |
2136 | void c hangeWrite Ciphers() throws SSL Exception { | |
2137 | if (connecti onState != cs_HANDSH AKE | |
2138 | && c onnectionS tate != cs _RENEGOTIA TE) { | |
2139 | throw ne w SSLProto colExcepti on( | |
2140 | "Sta te error, change cip her specs" ); | |
2141 | } | |
2142 | ||
2143 | // ... creat e compress or | |
2144 | ||
2145 | Ci pherBox ol dCipher = writeCiphe r; | |
2146 | ||
2147 | tr y { | |
2148 | writeCip her = hand shaker.new WriteCiphe r(); | |
2149 | writeAut henticator = handsha ker.newWri teAuthenti cator(); | |
2150 | } catch (Gen eralSecuri tyExceptio n e) { | |
2151 | // "can' t happen" | |
2152 | throw ne w SSLExcep tion("Algo rithm miss ing: ", e ); | |
2153 | } | |
2154 | ||
2155 | // See comme nt above. | |
2156 | ol dCipher.di spose(); | |
2157 | ||
2158 | // reset the flag of t he first a pplication record | |
2159 | is FirstAppOu tputRecord = true; | |
2160 | } | |
2161 | ||
2162 | /* | |
2163 | * Upd ates the S SL version associate d with thi s connecti on. | |
2164 | * Cal led from H andshaker once it ha s determin ed the neg otiated ve rsion. | |
2165 | */ | |
2166 | synchr onized voi d setVersi on(Protoco lVersion p rotocolVer sion) { | |
2167 | th is.protoco lVersion = protocolV ersion; | |
2168 | ou tput.r.set Version(pr otocolVers ion); | |
2169 | } | |
2170 | ||
2171 | // | |
2172 | // ONL Y used by ClientHand shaker for the serve r hostname during ha ndshaking | |
2173 | // | |
2174 | synchr onized Str ing getHos t() { | |
2175 | // Note that the host may be nul l or empty for local host. | |
2176 | if (host == null || ho st.length( ) == 0) { | |
2177 | useImpli citHost(tr ue); | |
2178 | } | |
2179 | ||
2180 | re turn host; | |
2181 | } | |
2182 | ||
2183 | /* | |
2184 | * Try to set an d use the implicit s pecified h ostname | |
2185 | */ | |
2186 | privat e synchron ized void useImplici tHost(bool ean noSniU pdate) { | |
2187 | ||
2188 | // Note: If the local name servi ce is not trustworth y, reverse | |
2189 | // host name resolutio n should n ot be perf ormed for endpoint | |
2190 | // identific ation. Us e the appl ication or iginal spe cified | |
2191 | // hostname or IP addr ess instea d. | |
2192 | ||
2193 | // Get the o riginal ho stname via jdk.inter nal.misc.S haredSecre ts | |
2194 | In etAddress inetAddres s = getIne tAddress() ; | |
2195 | if (inetAddr ess == nul l) { // not con nected | |
2196 | return; | |
2197 | } | |
2198 | ||
2199 | Ja vaNetAcces s jna = Sh aredSecret s.getJavaN etAccess() ; | |
2200 | St ring origi nalHostnam e = jna.ge tOriginalH ostName(in etAddress) ; | |
2201 | if ((origina lHostname != null) & & | |
2202 | (ori ginalHostn ame.length () != 0)) { | |
2203 | ||
2204 | host = o riginalHos tname; | |
2205 | if (!noS niUpdate & & serverNa mes.isEmpt y() && !no SniExtensi on) { | |
2206 | serv erNames = | |
2207 | Utilit ies.addToS NIServerNa meList(ser verNames, host); | |
2208 | ||
2209 | if ( !roleIsSer ver && | |
2210 | (hands haker != n ull) && !h andshaker. started()) { | |
2211 | handshaker .setSNISer verNames(s erverNames ); | |
2212 | } | |
2213 | } | |
2214 | ||
2215 | return; | |
2216 | } | |
2217 | ||
2218 | // No explic itly speci fied hostn ame, no se rver name indication . | |
2219 | if (!trustNa meService) { | |
2220 | // The l ocal name service is not trust worthy, us e IP addre ss. | |
2221 | host = i netAddress .getHostAd dress(); | |
2222 | } else { | |
2223 | // Use t he underly ing revers e host nam e resoluti on service . | |
2224 | host = g etInetAddr ess().getH ostName(); | |
2225 | } | |
2226 | } | |
2227 | ||
2228 | ||
2229 | // ONL Y used by HttpsClien t to setup the URI s pecified h ostname | |
2230 | // | |
2231 | // Ple ase NOTE t hat this m ethod MUST be called before ca lling to | |
2232 | // SSL Socket.set SSLParamet ers(). Oth erwise, th e {@code h ost} param eter | |
2233 | // may override SNIHostNam e in the c ustomized server nam e indicati on. | |
2234 | synchr onized pub lic void s etHost(Str ing host) { | |
2235 | th is.host = host; | |
2236 | th is.serverN ames = | |
2237 | Utilitie s.addToSNI ServerName List(this. serverName s, this.ho st); | |
2238 | ||
2239 | if (!roleIsS erver && ( handshaker != null) && !handsh aker.start ed()) { | |
2240 | handshak er.setSNIS erverNames (serverNam es); | |
2241 | } | |
2242 | } | |
2243 | ||
2244 | /** | |
2245 | * Get s an input stream to read from the peer on the oth er side. | |
2246 | * Dat a read fro m this str eam was al ways integ rity prote cted in | |
2247 | * tra nsit, and will usual ly have be en confide ntiality p rotected. | |
2248 | */ | |
2249 | @Overr ide | |
2250 | synchr onized pub lic InputS tream getI nputStream () throws IOExceptio n { | |
2251 | if (isClosed ()) { | |
2252 | throw ne w SocketEx ception("S ocket is c losed"); | |
2253 | } | |
2254 | ||
2255 | /* | |
2256 | * Can't cal l isConnec ted() here , because the Handsh akers | |
2257 | * do some i nitializat ion before we actual ly connect . | |
2258 | * / | |
2259 | if (connecti onState == cs_START) { | |
2260 | throw ne w SocketEx ception("S ocket is n ot connect ed"); | |
2261 | } | |
2262 | ||
2263 | re turn input ; | |
2264 | } | |
2265 | ||
2266 | /** | |
2267 | * Get s an outpu t stream t o write to the peer on the oth er side. | |
2268 | * Dat a written on this st ream is al ways integ rity prote cted, and | |
2269 | * wil l usually be confide ntiality p rotected. | |
2270 | */ | |
2271 | @Overr ide | |
2272 | synchr onized pub lic Output Stream get OutputStre am() throw s IOExcept ion { | |
2273 | if (isClosed ()) { | |
2274 | throw ne w SocketEx ception("S ocket is c losed"); | |
2275 | } | |
2276 | ||
2277 | /* | |
2278 | * Can't cal l isConnec ted() here , because the Handsh akers | |
2279 | * do some i nitializat ion before we actual ly connect . | |
2280 | * / | |
2281 | if (connecti onState == cs_START) { | |
2282 | throw ne w SocketEx ception("S ocket is n ot connect ed"); | |
2283 | } | |
2284 | ||
2285 | re turn outpu t; | |
2286 | } | |
2287 | ||
2288 | /** | |
2289 | * Ret urns the t he SSL Ses sion in us e by this connection . These c an | |
2290 | * be long lived , and freq uently cor respond to an entire login ses sion | |
2291 | * for some user . | |
2292 | */ | |
2293 | @Overr ide | |
2294 | public SSLSessio n getSessi on() { | |
2295 | /* | |
2296 | * Force a s ynchronous handshake , if appro priate. | |
2297 | * / | |
2298 | if (getConne ctionState () == cs_H ANDSHAKE) { | |
2299 | try { | |
2300 | // s tart hands haking, if failed, t he connect ion will b e closed. | |
2301 | star tHandshake (false); | |
2302 | } catch (IOExcepti on e) { | |
2303 | // h andshake f ailed. log and retur n a nullSe ssion | |
2304 | if ( debug != n ull && Deb ug.isOn("h andshake") ) { | |
2305 | System.o ut.println (Thread.cu rrentThrea d().getNam e() + | |
2306 | ", I OException in getSes sion(): " + e); | |
2307 | } | |
2308 | } | |
2309 | } | |
2310 | sy nchronized (this) { | |
2311 | return s ess; | |
2312 | } | |
2313 | } | |
2314 | ||
2315 | @Overr ide | |
2316 | synchr onized pub lic SSLSes sion getHa ndshakeSes sion() { | |
2317 | re turn hands hakeSessio n; | |
2318 | } | |
2319 | ||
2320 | synchr onized voi d setHands hakeSessio n(SSLSessi onImpl ses sion) { | |
2321 | ha ndshakeSes sion = ses sion; | |
2322 | } | |
2323 | ||
2324 | /** | |
2325 | * Con trols whet her new co nnections may cause creation o f new SSL | |
2326 | * ses sions. | |
2327 | * | |
2328 | * As long as ha ndshaking has not st arted, we can change | |
2329 | * whe ther we en able sessi on creatio ns. Other wise, | |
2330 | * we will need to wait fo r the next handshake . | |
2331 | */ | |
2332 | @Overr ide | |
2333 | synchr onized pub lic void s etEnableSe ssionCreat ion(boolea n flag) { | |
2334 | en ableSessio nCreation = flag; | |
2335 | ||
2336 | if ((handsha ker != nul l) && !han dshaker.ac tivated()) { | |
2337 | handshak er.setEnab leSessionC reation(en ableSessio nCreation) ; | |
2338 | } | |
2339 | } | |
2340 | ||
2341 | /** | |
2342 | * Ret urns true if new con nections m ay cause c reation of new SSL | |
2343 | * ses sions. | |
2344 | */ | |
2345 | @Overr ide | |
2346 | synchr onized pub lic boolea n getEnabl eSessionCr eation() { | |
2347 | re turn enabl eSessionCr eation; | |
2348 | } | |
2349 | ||
2350 | ||
2351 | /** | |
2352 | * Set s the flag controlli ng whether a server mode socke t | |
2353 | * *RE QUIRES* SS L client a uthenticat ion. | |
2354 | * | |
2355 | * As long as ha ndshaking has not st arted, we can change | |
2356 | * whe ther clien t authenti cation is needed. O therwise, | |
2357 | * we will need to wait fo r the next handshake . | |
2358 | */ | |
2359 | @Overr ide | |
2360 | synchr onized pub lic void s etNeedClie ntAuth(boo lean flag) { | |
2361 | do ClientAuth = (flag ? | |
2362 | SSLEngin eImpl.clau th_require d : SSLEng ineImpl.cl auth_none) ; | |
2363 | ||
2364 | if ((handsha ker != nul l) && | |
2365 | (han dshaker in stanceof S erverHands haker) && | |
2366 | !han dshaker.ac tivated()) { | |
2367 | ((Server Handshaker ) handshak er).setCli entAuth(do ClientAuth ); | |
2368 | } | |
2369 | } | |
2370 | ||
2371 | @Overr ide | |
2372 | synchr onized pub lic boolea n getNeedC lientAuth( ) { | |
2373 | re turn (doCl ientAuth = = SSLEngin eImpl.clau th_require d); | |
2374 | } | |
2375 | ||
2376 | /** | |
2377 | * Set s the flag controlli ng whether a server mode socke t | |
2378 | * *RE QUESTS* SS L client a uthenticat ion. | |
2379 | * | |
2380 | * As long as ha ndshaking has not st arted, we can change | |
2381 | * whe ther clien t authenti cation is requested. Otherwis e, | |
2382 | * we will need to wait fo r the next handshake . | |
2383 | */ | |
2384 | @Overr ide | |
2385 | synchr onized pub lic void s etWantClie ntAuth(boo lean flag) { | |
2386 | do ClientAuth = (flag ? | |
2387 | SSLEngin eImpl.clau th_request ed : SSLEn gineImpl.c lauth_none ); | |
2388 | ||
2389 | if ((handsha ker != nul l) && | |
2390 | (han dshaker in stanceof S erverHands haker) && | |
2391 | !han dshaker.ac tivated()) { | |
2392 | ((Server Handshaker ) handshak er).setCli entAuth(do ClientAuth ); | |
2393 | } | |
2394 | } | |
2395 | ||
2396 | @Overr ide | |
2397 | synchr onized pub lic boolea n getWantC lientAuth( ) { | |
2398 | re turn (doCl ientAuth = = SSLEngin eImpl.clau th_request ed); | |
2399 | } | |
2400 | ||
2401 | ||
2402 | /** | |
2403 | * Set s the flag controlli ng whether the socke t is in SS L | |
2404 | * cli ent or ser ver mode. Must be c alled befo re any SSL | |
2405 | * tra ffic has s tarted. | |
2406 | */ | |
2407 | @Overr ide | |
2408 | @Suppr essWarning s("fallthr ough") | |
2409 | synchr onized pub lic void s etUseClien tMode(bool ean flag) { | |
2410 | sw itch (conn ectionStat e) { | |
2411 | ||
2412 | ca se cs_STAR T: | |
2413 | /* | |
2414 | * If we need to c hange the socket mod e and the enabled | |
2415 | * proto cols haven 't specifi cally been set by th e user, | |
2416 | * chang e them to the corres ponding de fault ones . | |
2417 | */ | |
2418 | if (role IsServer ! = (!flag) && | |
2419 | sslContext .isDefault ProtocolLi st(enabled Protocols) ) { | |
2420 | enab ledProtoco ls = sslCo ntext.getD efaultProt ocolList(! flag); | |
2421 | } | |
2422 | roleIsSe rver = !fl ag; | |
2423 | break; | |
2424 | ||
2425 | ca se cs_HAND SHAKE: | |
2426 | /* | |
2427 | * If we have a ha ndshaker, but haven' t started | |
2428 | * SSL t raffic, we can throw away our current | |
2429 | * hands haker, and start fro m scratch. Don't | |
2430 | * need to call do neConnect( ) again, w e already | |
2431 | * have the stream s. | |
2432 | */ | |
2433 | assert(h andshaker != null); | |
2434 | if (!han dshaker.ac tivated()) { | |
2435 | /* | |
2436 | * I f we need to change the socket mode and the enable d | |
2437 | * p rotocols h aven't spe cifically been set b y the user , | |
2438 | * c hange them to the co rrespondin g default ones. | |
2439 | */ | |
2440 | if ( roleIsServ er != (!fl ag) && | |
2441 | sslCon text.isDef aultProtoc olList(ena bledProtoc ols)) { | |
2442 | enabledPro tocols = s slContext. getDefault ProtocolLi st(!flag); | |
2443 | } | |
2444 | role IsServer = !flag; | |
2445 | conn ectionStat e = cs_STA RT; | |
2446 | init Handshaker (); | |
2447 | brea k; | |
2448 | } | |
2449 | ||
2450 | // If ha ndshake ha s started, that's an error. F all throug h... | |
2451 | ||
2452 | de fault: | |
2453 | if (debu g != null && Debug.i sOn("ssl") ) { | |
2454 | Syst em.out.pri ntln(Threa d.currentT hread().ge tName() + | |
2455 | ", setUseC lientMode( ) invoked in state = " + | |
2456 | connection State); | |
2457 | } | |
2458 | throw ne w IllegalA rgumentExc eption( | |
2459 | "Can not change mode afte r SSL traf fic has st arted"); | |
2460 | } | |
2461 | } | |
2462 | ||
2463 | @Overr ide | |
2464 | synchr onized pub lic boolea n getUseCl ientMode() { | |
2465 | re turn !role IsServer; | |
2466 | } | |
2467 | ||
2468 | ||
2469 | /** | |
2470 | * Ret urns the n ames of th e cipher s uites whic h could be enabled f or use | |
2471 | * on an SSL con nection. Normally, only a sub set of the se will ac tually | |
2472 | * be enabled by default, since this list may include ci pher suite s which | |
2473 | * do not suppor t the mutu al authent ication of servers a nd clients , or | |
2474 | * whi ch do not protect da ta confide ntiality. Servers m ay also ne ed | |
2475 | * cer tain kinds of certif icates to use certai n cipher s uites. | |
2476 | * | |
2477 | * @re turn an ar ray of cip her suite names | |
2478 | */ | |
2479 | @Overr ide | |
2480 | public String[] getSupport edCipherSu ites() { | |
2481 | re turn sslCo ntext.getS upportedCi pherSuiteL ist().toSt ringArray( ); | |
2482 | } | |
2483 | ||
2484 | /** | |
2485 | * Con trols whic h particul ar cipher suites are enabled f or use on | |
2486 | * thi s connecti on. The c ipher suit es must ha ve been li sted by | |
2487 | * get CipherSuit es() as be ing suppor ted. Even if a suit e has been | |
2488 | * ena bled, it m ight never be used i f no peer supports i t or the | |
2489 | * req uisite cer tificates (and priva te keys) a re not ava ilable. | |
2490 | * | |
2491 | * @pa ram suites Names of all the ci pher suite s to enabl e. | |
2492 | */ | |
2493 | @Overr ide | |
2494 | synchr onized pub lic void s etEnabledC ipherSuite s(String[] suites) { | |
2495 | en abledCiphe rSuites = new Cipher SuiteList( suites); | |
2496 | if ((handsha ker != nul l) && !han dshaker.ac tivated()) { | |
2497 | handshak er.setEnab ledCipherS uites(enab ledCipherS uites); | |
2498 | } | |
2499 | } | |
2500 | ||
2501 | /** | |
2502 | * Ret urns the n ames of th e SSL ciph er suites which are currently enabled | |
2503 | * for use on th is connect ion. When an SSL so cket is fi rst create d, | |
2504 | * all enabled c ipher suit es <em>(a) </em> prot ect data c onfidentia lity, | |
2505 | * by traffic en cryption, and <em>(b )</em> can mutually authentica te | |
2506 | * bot h clients and server s. Thus, in some en vironments , this val ue | |
2507 | * mig ht be empt y. | |
2508 | * | |
2509 | * @re turn an ar ray of cip her suite names | |
2510 | */ | |
2511 | @Overr ide | |
2512 | synchr onized pub lic String [] getEnab ledCipherS uites() { | |
2513 | re turn enabl edCipherSu ites.toStr ingArray() ; | |
2514 | } | |
2515 | ||
2516 | ||
2517 | /** | |
2518 | * Ret urns the p rotocols t hat are su pported by this impl ementation . | |
2519 | * A s ubset of t he support ed protoco ls may be enabled fo r this con nection | |
2520 | * @re turn an ar ray of pro tocol name s. | |
2521 | */ | |
2522 | @Overr ide | |
2523 | public String[] getSupport edProtocol s() { | |
2524 | re turn sslCo ntext.getS uportedPro tocolList( ).toString Array(); | |
2525 | } | |
2526 | ||
2527 | /** | |
2528 | * Con trols whic h protocol s are enab led for us e on | |
2529 | * thi s connecti on. The p rotocols m ust have b een listed by | |
2530 | * get SupportedP rotocols() as being supported. | |
2531 | * | |
2532 | * @pa ram protoc ols protoc ols to ena ble. | |
2533 | * @ex ception Il legalArgum entExcepti on when on e of the p rotocols | |
2534 | * na med by the parameter is not su pported. | |
2535 | */ | |
2536 | @Overr ide | |
2537 | synchr onized pub lic void s etEnabledP rotocols(S tring[] pr otocols) { | |
2538 | en abledProto cols = new ProtocolL ist(protoc ols); | |
2539 | if ((handsha ker != nul l) && !han dshaker.ac tivated()) { | |
2540 | handshak er.setEnab ledProtoco ls(enabled Protocols) ; | |
2541 | } | |
2542 | } | |
2543 | ||
2544 | @Overr ide | |
2545 | synchr onized pub lic String [] getEnab ledProtoco ls() { | |
2546 | re turn enabl edProtocol s.toString Array(); | |
2547 | } | |
2548 | ||
2549 | /** | |
2550 | * Ass igns the s ocket time out. | |
2551 | * @se e java.net .Socket#se tSoTimeout | |
2552 | */ | |
2553 | @Overr ide | |
2554 | public void setS oTimeout(i nt timeout ) throws S ocketExcep tion { | |
2555 | if ((debug ! = null) && Debug.isO n("ssl")) { | |
2556 | System.o ut.println (Thread.cu rrentThrea d().getNam e() + | |
2557 | ", s etSoTimeou t(" + time out + ") c alled"); | |
2558 | } | |
2559 | ||
2560 | su per.setSoT imeout(tim eout); | |
2561 | } | |
2562 | ||
2563 | /** | |
2564 | * Reg isters an event list ener to re ceive noti fications that an | |
2565 | * SSL handshake has compl eted on th is connect ion. | |
2566 | */ | |
2567 | @Overr ide | |
2568 | public synchroni zed void a ddHandshak eCompleted Listener( | |
2569 | Handshak eCompleted Listener l istener) { | |
2570 | if (listener == null) { | |
2571 | throw ne w IllegalA rgumentExc eption("li stener is null"); | |
2572 | } | |
2573 | if (handshak eListeners == null) { | |
2574 | handshak eListeners = new | |
2575 | Hash Map<Handsh akeComplet edListener , AccessCo ntrolConte xt>(4); | |
2576 | } | |
2577 | ha ndshakeLis teners.put (listener, AccessCon troller.ge tContext() ); | |
2578 | } | |
2579 | ||
2580 | ||
2581 | /** | |
2582 | * Rem oves a pre viously re gistered h andshake c ompletion listener. | |
2583 | */ | |
2584 | @Overr ide | |
2585 | public synchroni zed void r emoveHands hakeComple tedListene r( | |
2586 | Handshak eCompleted Listener l istener) { | |
2587 | if (handshak eListeners == null) { | |
2588 | throw ne w IllegalA rgumentExc eption("no listeners "); | |
2589 | } | |
2590 | if (handshak eListeners .remove(li stener) == null) { | |
2591 | throw ne w IllegalA rgumentExc eption("li stener not registere d"); | |
2592 | } | |
2593 | if (handshak eListeners .isEmpty() ) { | |
2594 | handshak eListeners = null; | |
2595 | } | |
2596 | } | |
2597 | ||
2598 | /** | |
2599 | * Ret urns the S SLParamete rs in effe ct for thi s SSLSocke t. | |
2600 | */ | |
2601 | @Overr ide | |
2602 | synchr onized pub lic SSLPar ameters ge tSSLParame ters() { | |
2603 | SS LParameter s params = super.get SSLParamet ers(); | |
2604 | ||
2605 | // the super implement ation does not handl e the foll owing para meters | |
2606 | pa rams.setEn dpointIden tification Algorithm( identifica tionProtoc ol); | |
2607 | pa rams.setAl gorithmCon straints(a lgorithmCo nstraints) ; | |
2608 | ||
2609 | if (sniMatch ers.isEmpt y() && !no SniMatcher ) { | |
2610 | // 'null ' indicate s none has been set | |
2611 | params.s etSNIMatch ers(null); | |
2612 | } else { | |
2613 | params.s etSNIMatch ers(sniMat chers); | |
2614 | } | |
2615 | ||
2616 | if (serverNa mes.isEmpt y() && !no SniExtensi on) { | |
2617 | // 'null ' indicate s none has been set | |
2618 | params.s etServerNa mes(null); | |
2619 | } else { | |
2620 | params.s etServerNa mes(server Names); | |
2621 | } | |
2622 | ||
2623 | pa rams.setUs eCipherSui tesOrder(p referLocal CipherSuit es); | |
2624 | ||
2625 | re turn param s; | |
2626 | } | |
2627 | ||
2628 | /** | |
2629 | * App lies SSLPa rameters t o this soc ket. | |
2630 | */ | |
2631 | @Overr ide | |
2632 | synchr onized pub lic void s etSSLParam eters(SSLP arameters params) { | |
2633 | su per.setSSL Parameters (params); | |
2634 | ||
2635 | // the super implement ation does not handl e the foll owing para meters | |
2636 | id entificati onProtocol = params. getEndpoin tIdentific ationAlgor ithm(); | |
2637 | al gorithmCon straints = params.ge tAlgorithm Constraint s(); | |
2638 | pr eferLocalC ipherSuite s = params .getUseCip herSuitesO rder(); | |
2639 | ||
2640 | Li st<SNIServ erName> sn iNames = p arams.getS erverNames (); | |
2641 | if (sniNames != null) { | |
2642 | noSniExt ension = s niNames.is Empty(); | |
2643 | serverNa mes = sniN ames; | |
2644 | } | |
2645 | ||
2646 | Co llection<S NIMatcher> matchers = params.g etSNIMatch ers(); | |
2647 | if (matchers != null) { | |
2648 | noSniMat cher = mat chers.isEm pty(); | |
2649 | sniMatch ers = matc hers; | |
2650 | } | |
2651 | ||
2652 | if ((handsha ker != nul l) && !han dshaker.st arted()) { | |
2653 | handshak er.setIden tification Protocol(i dentificat ionProtoco l); | |
2654 | handshak er.setAlgo rithmConst raints(alg orithmCons traints); | |
2655 | if (role IsServer) { | |
2656 | hand shaker.set SNIMatcher s(sniMatch ers); | |
2657 | hand shaker.set UseCipherS uitesOrder (preferLoc alCipherSu ites); | |
2658 | } else { | |
2659 | hand shaker.set SNIServerN ames(serve rNames); | |
2660 | } | |
2661 | } | |
2662 | } | |
2663 | ||
2664 | /* | |
2665 | * Ret urns a boo lean indic ating whet her the Ch angeCipher Spec messa ge | |
2666 | * has been rece ived for t his handsh ake. | |
2667 | */ | |
2668 | boolea n received ChangeCiph erSpec() { | |
2669 | re turn recei vedCCS; | |
2670 | } | |
2671 | ||
2672 | // | |
2673 | // We allocate a separate thread to deliver ha ndshake co mpletion | |
2674 | // eve nts. This ensures t hat the no tification s don't bl ock the | |
2675 | // pro tocol stat e machine. | |
2676 | // | |
2677 | privat e static c lass Notif yHandshake Thread ext ends Threa d { | |
2678 | ||
2679 | pr ivate Set< Map.Entry< HandshakeC ompletedLi stener,Acc essControl Context>> | |
2680 | targ ets; // who g ets notifi ed | |
2681 | pr ivate Hand shakeCompl etedEvent event; // t he notific ation | |
2682 | ||
2683 | No tifyHandsh akeThread( | |
2684 | Set<Map. Entry<Hand shakeCompl etedListen er,AccessC ontrolCont ext>> | |
2685 | entrySet , Handshak eCompleted Event e) { | |
2686 | ||
2687 | super("H andshakeCo mpletedNot ify-Thread "); | |
2688 | targets = new Hash Set<>(entr ySet); // c lone the e ntry set | |
2689 | event = e; | |
2690 | } | |
2691 | ||
2692 | @O verride | |
2693 | pu blic void run() { | |
2694 | // Don't need to s ynchronize , as it on ly runs in one threa d. | |
2695 | for (Map .Entry<Han dshakeComp letedListe ner,Access ControlCon text> | |
2696 | entr y : target s) { | |
2697 | ||
2698 | fina l Handshak eCompleted Listener l = entry.g etKey(); | |
2699 | Acce ssControlC ontext acc = entry.g etValue(); | |
2700 | Acce ssControll er.doPrivi leged(new Privileged Action<Voi d>() { | |
2701 | @Override | |
2702 | public Voi d run() { | |
2703 | l.hand shakeCompl eted(event ); | |
2704 | return null; | |
2705 | } | |
2706 | }, a cc); | |
2707 | } | |
2708 | } | |
2709 | } | |
2710 | ||
2711 | /** | |
2712 | * Ret urns a pri ntable rep resentatio n of this end of the connectio n. | |
2713 | */ | |
2714 | @Overr ide | |
2715 | public String to String() { | |
2716 | St ringBuffer retval = new String Buffer(80) ; | |
2717 | ||
2718 | re tval.appen d(Integer. toHexStrin g(hashCode ())); | |
2719 | re tval.appen d("["); | |
2720 | re tval.appen d(sess.get CipherSuit e()); | |
2721 | re tval.appen d(": "); | |
2722 | ||
2723 | re tval.appen d(super.to String()); | |
2724 | re tval.appen d("]"); | |
2725 | ||
2726 | re turn retva l.toString (); | |
2727 | } | |
2728 | } |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.