Branch data Line data Source code
1 : : // $Id: SSLv3.cc 5988 2008-07-19 07:02:12Z vern $
2 : :
3 : : #include "SSLv3.h"
4 : : #include "SSLCiphers.h"
5 : :
6 : : // --- Initalization of static variables --------------------------------------
7 : :
8 : : bool SSLv3_Interpreter::bInited = false;
9 : :
10 : : uint SSLv3_Interpreter::totalConnections = 0;
11 : : uint SSLv3_Interpreter::openedConnections = 0;
12 : : uint SSLv3_Interpreter::totalRecords = 0;
13 : : uint SSLv3_Interpreter::handshakeRecords = 0;
14 : : uint SSLv3_Interpreter::clientHelloRecords = 0;
15 : : uint SSLv3_Interpreter::serverHelloRecords = 0;
16 : : uint SSLv3_Interpreter::alertRecords = 0;
17 : : uint SSLv3_Interpreter::changeCipherRecords = 0;
18 : :
19 : :
20 : : // ---SSLv3_Interpreter--------------------------------------------------------
21 : :
22 : : // Initialize static:
23 : 6 : SSLv3_Automaton SSLv3_Interpreter::sslAutomaton(SSL3_1_NUM_STATES,
24 : 3 : SSL3_1_NUM_TRANS, SSL3_1_STATE_ERROR);
25 : :
26 : 0 : SSLv3_Interpreter::SSLv3_Interpreter(SSLProxy_Analyzer* proxy)
27 : 0 : : SSL_Interpreter(proxy)
28 : : {
29 : 0 : pCipherSuite = 0;
30 : 0 : cipherSuiteIdentifier = 0;
31 : 0 : pClientCipherSpecs = 0;
32 : 0 : clientSessionID = 0;
33 : 0 : serverSessionID = 0;
34 : 0 : clientRandom = 0;
35 : 0 : serverRandom = 0;
36 : 0 : serverRSApars = 0;
37 : 0 : serverDHPars = 0;
38 : 0 : encryptedPreSecret = 0;
39 : 0 : clientDHpublic = 0;
40 : : // keyXAlgorithm = SSL_KEY_EXCHANGE_NULL;
41 : 0 : change_cipher_client_seen = false;
42 : 0 : change_cipher_server_seen = false;
43 : 0 : fin_client_seen = false;
44 : 0 : fin_server_seen = false;
45 : 0 : helloRequestValid = true;
46 : :
47 [ # # # # ]: 0 : if ( ! bInited )
48 : : {
49 : 0 : BuildAutomaton();
50 : : // BuildCipherDict();
51 : 0 : bInited = true;
52 : : }
53 : :
54 : 0 : currentState = SSL3_1_STATE_INIT;
55 : 0 : ++totalConnections;
56 : 0 : }
57 : :
58 : 0 : SSLv3_Interpreter::~SSLv3_Interpreter()
59 : : {
60 [ # # ][ # # ]: 0 : delete pClientCipherSpecs;
[ # # ]
61 [ # # ][ # # ]: 0 : delete clientSessionID;
[ # # ]
62 [ # # ][ # # ]: 0 : delete serverSessionID;
[ # # ]
63 : :
64 [ # # ][ # # ]: 0 : if ( ssl_store_key_material )
[ # # ]
65 : : {
66 [ # # ][ # # ]: 0 : if ( clientRandom )
[ # # ]
67 [ # # ][ # # ]: 0 : delete clientRandom->random_bytes;
[ # # ]
68 : 0 : delete clientRandom;
69 [ # # # # # : 0 : if ( serverRandom )
# ]
70 [ # # ][ # # ]: 0 : delete serverRandom->random_bytes;
[ # # ]
71 : 0 : delete serverRandom;
72 : 0 : delete serverRSApars;
73 : 0 : delete serverDHPars;
74 : 0 : delete encryptedPreSecret;
75 : 0 : delete clientDHpublic;
76 : : }
77 [ # # ][ # # ]: 0 : }
[ # # ]
78 : :
79 : 0 : void SSLv3_Interpreter::BuildInterpreterEndpoints()
80 : : {
81 : 0 : orig = new SSLv3_Endpoint(this, 1);
82 : 0 : resp = new SSLv3_Endpoint(this, 0);
83 : 0 : }
84 : :
85 : 0 : void SSLv3_Interpreter::BuildAutomaton()
86 : : {
87 : : sslAutomaton.addTrans(SSL3_1_STATE_INIT, SSL3_1_TRANS_SERVER_HELLO_REQ,
88 : 0 : SSL3_1_STATE_SERVER_HELLO_REQ_SENT);
89 : :
90 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_HELLO_REQ_SENT,
91 : 0 : SSL3_1_TRANS_CLIENT_HELLO, SSL3_1_STATE_CLIENT_HELLO_SENT);
92 : :
93 : : sslAutomaton.addTrans(SSL3_1_STATE_INIT, SSL3_1_TRANS_CLIENT_HELLO,
94 : 0 : SSL3_1_STATE_CLIENT_HELLO_SENT);
95 : :
96 : : sslAutomaton.addTrans(SSL3_1_STATE_CLIENT_HELLO_SENT,
97 : 0 : SSL3_1_TRANS_SERVER_HELLO, SSL3_1_STATE_SERVER_HELLO_SENT);
98 : :
99 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_HELLO_SENT,
100 : 0 : SSL3_1_TRANS_SERVER_CERT, SSL3_1_STATE_SERVER_CERT_SENT);
101 : :
102 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_HELLO_SENT,
103 : : SSL3_1_TRANS_SERVER_KEY_EXCHANGE,
104 : 0 : SSL3_1_STATE_SERVER_KEY_EXCHANGE_SENT);
105 : :
106 : : // Server key-exchange and/or server requests cert from client.
107 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_CERT_SENT,
108 : : SSL3_1_TRANS_SERVER_KEY_EXCHANGE,
109 : 0 : SSL3_1_STATE_SERVER_KEY_EXCHANGE_SENT);
110 : :
111 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_KEY_EXCHANGE_SENT,
112 : : SSL3_1_TRANS_SERVER_HELLO_DONE,
113 : 0 : SSL3_1_STATE_SERVER_HELLO_DONE_SENT_A);
114 : :
115 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_KEY_EXCHANGE_SENT,
116 : : SSL3_1_TRANS_SERVER_CERT_REQ,
117 : 0 : SSL3_1_STATE_SERVER_CERT_REQ_SENT);
118 : :
119 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_CERT_SENT,
120 : : SSL3_1_TRANS_SERVER_CERT_REQ,
121 : 0 : SSL3_1_STATE_SERVER_CERT_REQ_SENT);
122 : :
123 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_CERT_REQ_SENT,
124 : : SSL3_1_TRANS_SERVER_HELLO_DONE,
125 : 0 : SSL3_1_STATE_SERVER_HELLO_DONE_SENT_B);
126 : :
127 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_HELLO_DONE_SENT_B,
128 : 0 : SSL3_1_TRANS_CLIENT_CERT, SSL3_1_STATE_CLIENT_CERT_SENT);
129 : :
130 : : sslAutomaton.addTrans(SSL3_1_STATE_CLIENT_CERT_SENT,
131 : : SSL3_1_TRANS_CLIENT_KEY_EXCHANGE,
132 : 0 : SSL3_1_STATE_CLIENT_KEY_EXCHANGE_SENT_B);
133 : :
134 : : sslAutomaton.addTrans(SSL3_1_STATE_CLIENT_KEY_EXCHANGE_SENT_B,
135 : : SSL3_1_TRANS_CLIENT_CERT_VERIFY,
136 : 0 : SSL3_1_STATE_CLIENT_CERT_VERIFY_SENT);
137 : :
138 : : sslAutomaton.addTrans(SSL3_1_STATE_CLIENT_KEY_EXCHANGE_SENT_B,
139 : 0 : SSL3_1_TRANS_CLIENT_FIN, SSL3_1_STATE_CLIENT_FIN_SENT_A);
140 : :
141 : : sslAutomaton.addTrans(SSL3_1_STATE_CLIENT_CERT_VERIFY_SENT,
142 : 0 : SSL3_1_TRANS_CLIENT_FIN, SSL3_1_STATE_CLIENT_FIN_SENT_A);
143 : :
144 : : sslAutomaton.addTrans(SSL3_1_STATE_CLIENT_FIN_SENT_A,
145 : 0 : SSL3_1_TRANS_SERVER_FIN, SSL3_1_STATE_HS_FIN_A);
146 : :
147 : : sslAutomaton.addTrans(SSL3_1_STATE_CLIENT_KEY_EXCHANGE_SENT_B,
148 : 0 : SSL3_1_TRANS_SERVER_FIN, SSL3_1_STATE_SERVER_FIN_SENT_A);
149 : :
150 : : sslAutomaton.addTrans(SSL3_1_STATE_CLIENT_CERT_VERIFY_SENT,
151 : 0 : SSL3_1_TRANS_SERVER_FIN, SSL3_1_STATE_SERVER_FIN_SENT_A);
152 : :
153 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_FIN_SENT_A,
154 : 0 : SSL3_1_TRANS_CLIENT_FIN, SSL3_1_STATE_HS_FIN_A);
155 : :
156 : : // Server hello done after server cert sent.
157 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_CERT_SENT,
158 : : SSL3_1_TRANS_SERVER_HELLO_DONE,
159 : 0 : SSL3_1_STATE_SERVER_HELLO_DONE_SENT_A);
160 : :
161 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_HELLO_DONE_SENT_A,
162 : : SSL3_1_TRANS_CLIENT_KEY_EXCHANGE,
163 : 0 : SSL3_1_STATE_CLIENT_KEY_EXCHANGE_SENT_A);
164 : :
165 : : sslAutomaton.addTrans(SSL3_1_STATE_CLIENT_KEY_EXCHANGE_SENT_A,
166 : 0 : SSL3_1_TRANS_CLIENT_FIN, SSL3_1_STATE_CLIENT_FIN_SENT_A);
167 : :
168 : : sslAutomaton.addTrans(SSL3_1_STATE_CLIENT_KEY_EXCHANGE_SENT_A,
169 : 0 : SSL3_1_TRANS_SERVER_FIN, SSL3_1_STATE_SERVER_FIN_SENT_A);
170 : :
171 : : sslAutomaton.addTrans(SSL3_1_STATE_CLIENT_FIN_SENT_A,
172 : 0 : SSL3_1_TRANS_SERVER_FIN, SSL3_1_STATE_HS_FIN_A);
173 : :
174 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_FIN_SENT_A,
175 : 0 : SSL3_1_TRANS_CLIENT_FIN, SSL3_1_STATE_HS_FIN_A);
176 : :
177 : : // When reestablishing a session:
178 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_HELLO_SENT,
179 : 0 : SSL3_1_TRANS_CLIENT_FIN, SSL3_1_STATE_CLIENT_FIN_SENT_B);
180 : :
181 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_HELLO_SENT,
182 : 0 : SSL3_1_TRANS_SERVER_FIN, SSL3_1_STATE_SERVER_FIN_SENT_B);
183 : :
184 : : sslAutomaton.addTrans(SSL3_1_STATE_CLIENT_FIN_SENT_B,
185 : 0 : SSL3_1_TRANS_SERVER_FIN, SSL3_1_STATE_HS_FIN_B);
186 : :
187 : : sslAutomaton.addTrans(SSL3_1_STATE_SERVER_FIN_SENT_B,
188 : 0 : SSL3_1_TRANS_CLIENT_FIN, SSL3_1_STATE_HS_FIN_B);
189 : :
190 : 0 : sslAutomaton.setStartState(SSL3_1_STATE_INIT);
191 : 0 : }
192 : :
193 : 0 : void SSLv3_Interpreter::printStats()
194 : : {
195 : 0 : printf( "SSLv3x:\n" );
196 : 0 : printf( "Note: Because handshake messages may be coalesced into a \n");
197 : 0 : printf( " single SSLv3x record, the number of total messages for SSLv3x plus \n");
198 : 0 : printf( " the number of total records seen for SSLv2 won't match \n");
199 : 0 : printf( " SSLProxy_Analyzer::totalRecords! \n");
200 : 0 : printf( "total connections = %u\n", totalConnections );
201 : 0 : printf( "opened connections (complete handshake) = %u\n", openedConnections );
202 : :
203 : 0 : printf( "total messages seen = %u\n", totalRecords );
204 : 0 : printf( "handshake messages seen = %u\n", handshakeRecords );
205 : 0 : printf( "alert records seen = %u\n", alertRecords );
206 : 0 : printf( "change cipher records seen = %u\n", changeCipherRecords );
207 : 0 : printf( "client hello messages seen = %u\n", clientHelloRecords );
208 : 0 : printf( "server hello messages seen = %u\n", serverHelloRecords );
209 : 0 : }
210 : :
211 : 0 : int SSLv3_Interpreter::HandshakeType2Trans(int type)
212 : : {
213 [ # # # # # : 0 : switch ( SSL3_1_HandshakeType(type) ) {
# # # # #
# ]
214 : 0 : case SSL3_1_HELLO_REQUEST: return SSL3_1_TRANS_SERVER_HELLO_REQ;
215 : 0 : case SSL3_1_CLIENT_HELLO: return SSL3_1_TRANS_CLIENT_HELLO;
216 : 0 : case SSL3_1_SERVER_HELLO: return SSL3_1_TRANS_SERVER_HELLO;
217 : :
218 : : case SSL3_1_CERTIFICATE:
219 : : // Client- and server certificate handshake records lead
220 : : // to the same transition in the SSL automaton
221 : : // (see SSLDefines.h)
222 : 0 : return SSL3_1_TRANS_SERVER_CERT;
223 : :
224 : 0 : case SSL3_1_SERVER_KEY_EXCHANGE: return SSL3_1_TRANS_SERVER_KEY_EXCHANGE;
225 : 0 : case SSL3_1_CERTIFICATE_REQUEST: return SSL3_1_TRANS_SERVER_CERT_REQ;
226 : 0 : case SSL3_1_SERVER_HELLO_DONE: return SSL3_1_TRANS_SERVER_HELLO_DONE;
227 : 0 : case SSL3_1_CERTIFICATE_VERIFY: return SSL3_1_TRANS_CLIENT_CERT_VERIFY;
228 : 0 : case SSL3_1_CLIENT_KEY_EXCHANGE: return SSL3_1_TRANS_CLIENT_KEY_EXCHANGE;
229 : :
230 : : case SSL3_1_FINISHED:
231 : : // Client- and server certificate handshake records lead
232 : : // to the same transition in the SSL automaton
233 : : // (see SSLDefines.h)
234 : 0 : return SSL3_1_TRANS_CLIENT_FIN;
235 : : default:
236 : 0 : return -1;
237 : : }
238 : : }
239 : :
240 : 0 : void SSLv3_Interpreter::DeliverSSLv3_Record(SSLv3_HandshakeRecord* rec)
241 : : {
242 : 0 : ++SSLv3_Interpreter::totalRecords;
243 : 0 : ++SSLv3_Interpreter::handshakeRecords;
244 : :
245 : 0 : TableVal* currentCipherSuites = 0;
246 : :
247 : : // First: consistency checks.
248 : : // Special treatment for finished messages, because they are
249 : : // already encrypted (encrypted handshake message).
250 [ # # ][ # # ]: 0 : if ( (change_cipher_client_seen && (rec->endp)->IsOrig() &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
251 : : ! fin_client_seen) ||
252 : : (change_cipher_server_seen && ! rec->endp->IsOrig() &&
253 : : ! fin_server_seen) )
254 : : {
255 : : // no checks can be performed due encryption...
256 : : }
257 : : else
258 : : {
259 : 0 : SSL3_1_HandshakeType ht = SSL3_1_HandshakeType(rec->type);
260 [ # # # # # : 0 : switch ( ht ) {
# # # # #
# ]
261 : : case SSL3_1_HELLO_REQUEST:
262 [ # # ]: 0 : if ( rec->length != 0 )
263 : 0 : Weird("SSLv3x: Hello request too long!");
264 [ # # ]: 0 : if ( ! helloRequestValid )
265 : 0 : Weird("SSLv3x: Received hello request during handshake!");
266 : : // There should only be sent one hello request at a
267 : : // time.
268 : 0 : helloRequestValid = false;
269 : 0 : break;
270 : :
271 : : case SSL3_1_CLIENT_HELLO:
272 : : {
273 : 0 : ++SSLv3_Interpreter::clientHelloRecords;
274 : :
275 : : // During the handshaking phase, we don't want any
276 : : // more hello requests.
277 : 0 : helloRequestValid = false;
278 : :
279 [ # # ]: 0 : if ( rec->checkClientHello() == 0 )
280 : 0 : return;
281 : :
282 : 0 : const u_char* pTemp = rec->data;
283 : 0 : uint8 sessionIDLength = uint8(pTemp[38]);
284 : : clientSessionID =
285 : 0 : new SSL_DataBlock((pTemp + 39), sessionIDLength);
286 : : uint16 cipherSuiteLength =
287 : : uint16(pTemp[39 + sessionIDLength] << 8 ) |
288 : 0 : pTemp[40 + sessionIDLength];
289 : :
290 : : currentCipherSuites =
291 : : analyzeCiphers(rec->endp, cipherSuiteLength,
292 : : rec->data + 41 + sessionIDLength,
293 : 0 : rec->sslVersion);
294 : :
295 [ # # ]: 0 : if ( ssl_store_key_material )
296 : : {
297 : 0 : clientRandom = new SSLv3x_Random();
298 : 0 : clientRandom->random_bytes = 0;
299 : : clientRandom->gmt_unix_time =
300 : : uint32(((pTemp[6] << 24) |
301 : : pTemp[7] << 16) |
302 : 0 : pTemp[8] << 8) | pTemp[9];
303 : :
304 : : clientRandom->random_bytes =
305 : 0 : new SSL_DataBlock(pTemp + 10, 28);
306 : : }
307 : 0 : break;
308 : : }
309 : :
310 : : case SSL3_1_SERVER_HELLO:
311 : : {
312 : 0 : ++SSLv3_Interpreter::serverHelloRecords;
313 [ # # ]: 0 : if ( rec->checkServerHello() == 0)
314 : 0 : return;
315 : :
316 : 0 : const u_char* pTemp = rec->data;
317 : 0 : uint8 sessionIDLength = uint8(pTemp[38]);
318 : : serverSessionID =
319 : 0 : new SSL_DataBlock(pTemp + 39, sessionIDLength);
320 : : currentCipherSuites =
321 : : analyzeCiphers(rec->endp, 2,
322 : : rec->data + 39 + sessionIDLength,
323 : 0 : rec->sslVersion);
324 : :
325 : : // Check whether the cipher suite the server choose
326 : : // was included in the cipher suites the client
327 : : // anounced.
328 [ # # # # ]: 0 : if ( pClientCipherSpecs && pCipherSuite )
329 : : {
330 : 0 : bool bFound = false;
331 : : uint16 tempClientCipher;
332 [ # # ]: 0 : for ( int i = 0; i < pClientCipherSpecs->len;
333 : : i += 2 )
334 : : {
335 : : tempClientCipher =
336 : : (pClientCipherSpecs->data[i] << 8) |
337 : 0 : pClientCipherSpecs->data[i+1];
338 : :
339 [ # # ]: 0 : if ( tempClientCipher ==
340 : : pCipherSuite->identifier )
341 : : {
342 : 0 : bFound = true;
343 : 0 : i = pClientCipherSpecs->len;
344 : : }
345 : : }
346 : :
347 [ # # ]: 0 : if ( ! bFound )
348 : 0 : Weird("SSLv3x: Server choosed cipher spec that client didn't anounce!");
349 : :
350 [ # # ]: 0 : delete pClientCipherSpecs;
351 : 0 : pClientCipherSpecs = 0;
352 : : }
353 : :
354 [ # # ]: 0 : if ( ssl_store_key_material )
355 : : {
356 : 0 : serverRandom = new SSLv3x_Random();
357 : : serverRandom->gmt_unix_time =
358 : : uint32(((pTemp[6] << 8) |
359 : : pTemp[7] << 8) |
360 : 0 : pTemp[8] << 8) | pTemp[9];
361 : : serverRandom->random_bytes =
362 : 0 : new SSL_DataBlock(pTemp + 10, 28);
363 : : }
364 : :
365 : : // Insert session injection into here.
366 : :
367 [ # # ]: 0 : if ( ! ssl_session_insertion )
368 : 0 : break; // in place of below
369 : :
370 : : TableVal* sessionIDTable =
371 : : serverSessionID ?
372 : : MakeSessionID(serverSessionID->data,
373 : : serverSessionID->len) :
374 [ # # ]: 0 : MakeSessionID(0, 0);
375 : :
376 : 0 : val_list* vl = new val_list;
377 : 0 : vl->append(proxy->BuildConnVal());
378 : 0 : vl->append(sessionIDTable);
379 : :
380 : 0 : proxy->ConnectionEvent(ssl_session_insertion, vl);
381 : 0 : break;
382 : : }
383 : :
384 : : case SSL3_1_CERTIFICATE:
385 : : {
386 [ # # ]: 0 : if ( rec->length >= 3 )
387 : : {
388 : 0 : const u_char* pData = rec->data;
389 : : uint32 certListLength =
390 : : uint32((pData[4] << 16) |
391 : 0 : pData[5] << 8) | pData[6];
392 : :
393 : : // Size consistency checks.
394 [ # # ]: 0 : if ( certListLength + 3 != uint32(rec->length) )
395 : : {
396 [ # # ]: 0 : if ( rec->endp->IsOrig() )
397 : 0 : Weird("SSLv3x: Corrupt length field in client certificate list!");
398 : : else
399 : 0 : Weird("SSLv3x: Corrupt length field in server certificate list!");
400 : 0 : return;
401 : : }
402 : :
403 : : // Sum of all cert sizes has to match
404 : : // certListLength.
405 : 0 : uint tempLength = 0;
406 : 0 : uint certCount = 0;
407 [ # # ]: 0 : while ( tempLength < certListLength )
408 : : {
409 [ # # ]: 0 : if ( tempLength + 3 <= certListLength )
410 : : {
411 : 0 : ++certCount;
412 : : uint32 certLength =
413 : 0 : uint32((pData[tempLength + 7] << 16) | pData[tempLength + 8] << 8) | pData[tempLength + 9];
414 : 0 : tempLength += certLength + 3;
415 : : }
416 : : else
417 : : {
418 : 0 : Weird("SSLv3x: Corrupt length field in certificate list!");
419 : 0 : return;
420 : : }
421 : : }
422 : :
423 [ # # ]: 0 : if ( tempLength > certListLength )
424 : : {
425 : 0 : Weird("SSLv3x: sum of size of certificates doesn't match size of certificate chain");
426 : 0 : return;
427 : : }
428 : :
429 : : SSL_InterpreterEndpoint* pEp =
430 : 0 : (SSL_InterpreterEndpoint*) rec->endp;
431 : :
432 [ # # ]: 0 : if ( certCount == 0 )
433 : : { // we don't have a certificate...
434 [ # # ]: 0 : if ( rec->endp->IsOrig() )
435 : : {
436 : 0 : Weird("SSLv3x: Client certificate is missing!");
437 : 0 : break;
438 : : }
439 : : else
440 : : {
441 : 0 : Weird("SSLv3x: Server certificate is missing!");
442 : 0 : break;
443 : : }
444 : : }
445 : :
446 [ # # ]: 0 : if ( certCount > 1 )
447 : : { // we have a chain
448 : : analyzeCertificate(pEp,
449 : : rec->data + 7,
450 : 0 : certListLength, 1, true);
451 : : }
452 : : else
453 : : {
454 : : // We have a single certificate.
455 : : // FIXME.
456 : : analyzeCertificate(pEp,
457 : : rec->data + 10,
458 : 0 : certListLength-3, 1, false);
459 : : }
460 : :
461 : : }
462 : : else
463 : 0 : Weird("SSLv3x: Certificate record too small!" );
464 : 0 : break;
465 : : }
466 : :
467 : : case SSL3_1_SERVER_KEY_EXCHANGE:
468 : : {
469 : : /*
470 : : switch (cipherSuite)
471 : : {
472 : : // It would be necessary to have the RSA key length
473 : : // out of the server's certificate. If the cipher suite
474 : : // is EXPORT, than a RSA key length larger than 512 bits
475 : : // is not allowed for encryption and thus, the server needs
476 : : // to send a key-exchange-message in order to negotiate the
477 : : // pre-master secret (see rfc 2246 page 39)
478 : : case TLS_RSA_WITH_NULL_MD5:
479 : : case TLS_RSA_WITH_NULL_SHA:
480 : : // case TLS_RSA_EXPORT_WITH_RC4_40_MD5: //see comment above
481 : : case TLS_RSA_WITH_RC4_128_MD5:
482 : : case TLS_RSA_WITH_RC4_128_SHA:
483 : : // case TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5: //see comment above
484 : : case TLS_RSA_WITH_IDEA_CBC_SHA:
485 : : // case TLS_RSA_EXPORT_WITH_DES40_CBC_SHA: //see comment above
486 : : case TLS_RSA_WITH_DES_CBC_SHA:
487 : : case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
488 : : case TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
489 : : case TLS_DH_DSS_WITH_DES_CBC_SHA:
490 : : case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
491 : : case TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
492 : : case TLS_DH_RSA_WITH_DES_CBC_SHA:
493 : : case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
494 : : {
495 : : Weird("SSLv3x: Sending server-key-exchange not allowed for this cipher suite!");
496 : : return;
497 : : break;
498 : : }
499 : : default:
500 : : break;
501 : : }
502 : : */
503 : :
504 [ # # ]: 0 : if ( ! pCipherSuite )
505 : : // If we have an unknown CIPHER-SPEC,
506 : : // we can't do our weird checks.
507 : 0 : break;
508 : :
509 : : SSL_KeyExchangeAlgorithm keyXAlgorithm =
510 : 0 : pCipherSuite->keyExchangeAlgorithm;
511 : :
512 [ # # ][ # # ]: 0 : if ( keyXAlgorithm == SSL_KEY_EXCHANGE_RSA ||
[ # # ]
513 : : keyXAlgorithm == SSL_KEY_EXCHANGE_DH_DSS ||
514 : : keyXAlgorithm == SSL_KEY_EXCHANGE_DH_RSA )
515 : : {
516 : 0 : Weird("SSLv3x: Sending server-key-exchange not allowed for this cipher suite!");
517 : 0 : return;
518 : :
519 : : }
520 : : // FIXME: check where DHE_RSA etc. belongs to
521 : 0 : const u_char* pTemp = rec->data;
522 [ # # ]: 0 : if ( ssl_store_key_material )
523 : : {
524 [ # # ][ # # ]: 0 : if ( keyXAlgorithm == SSL_KEY_EXCHANGE_RSA ||
[ # # ]
525 : : keyXAlgorithm == SSL_KEY_EXCHANGE_RSA ||
526 : : keyXAlgorithm == SSL_KEY_EXCHANGE_RSA_EXPORT1024 )
527 : : { // some weird checks
528 [ # # ]: 0 : if ( rec->length < 2 )
529 : : {
530 : 0 : Weird("SSLv3x: server-key-exchange empty!");
531 : 0 : return;
532 : : }
533 : :
534 : 0 : uint16 modulusLength = uint16(pTemp[4] << 8 ) | pTemp[5];
535 [ # # ]: 0 : if ( modulusLength + 4 > rec->length )
536 : : {
537 : 0 : Weird("SSLv3x: Corrupt length fields in server-key-exchange!");
538 : 0 : break;
539 : : }
540 : :
541 : 0 : uint16 exponentLength = uint16(pTemp[6 + modulusLength] << 8 ) | pTemp[7 + modulusLength];
542 [ # # ]: 0 : if ( modulusLength + exponentLength + 4 > rec->length )
543 : : {
544 : 0 : Weird("SSLv3x: Corrupt length fields in server-key-exchange!");
545 : 0 : return;
546 : : }
547 : :
548 : : serverRSApars =
549 : 0 : new SSLv3x_ServerRSAParams;
550 : : serverRSApars->rsa_modulus =
551 : 0 : new SSL_DataBlock(pTemp + 6, modulusLength);
552 : : serverRSApars->rsa_exponent =
553 : 0 : new SSL_DataBlock( pTemp + 8 + modulusLength, exponentLength);
554 : : }
555 : : else
556 : : {
557 [ # # ][ # # ]: 0 : if ( keyXAlgorithm == SSL_KEY_EXCHANGE_DH || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_DSS || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_DSS_EXPORT || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_RSA || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_RSA_EXPORT || keyXAlgorithm == SSL_KEY_EXCHANGE_DHE_DSS || keyXAlgorithm == SSL_KEY_EXCHANGE_DHE_DSS_EXPORT || keyXAlgorithm == SSL_KEY_EXCHANGE_DHE_RSA || keyXAlgorithm == SSL_KEY_EXCHANGE_DHE_RSA_EXPORT || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_ANON || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_ANON_EXPORT || keyXAlgorithm == SSL_KEY_EXCHANGE_DHE_DSS_EXPORT1024 )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
558 : : {
559 [ # # ]: 0 : if ( rec->length < 2 )
560 : : {
561 : 0 : Weird("SSLv3x: server-key-exchange empty!");
562 : 0 : return;
563 : : }
564 : :
565 : 0 : uint16 dh_pLength = (uint16) (pTemp[4] << 8 ) | pTemp[5];
566 [ # # ]: 0 : if ( dh_pLength + 4 > rec->length )
567 : : {
568 : 0 : Weird("SSLv3x: Corrupt length fields in server-key-exchange!");
569 : 0 : break;
570 : : }
571 : :
572 : 0 : uint16 dh_gLength = uint16(pTemp[6 + dh_pLength] << 8 ) | pTemp[7 + dh_pLength];
573 : 0 : uint16 dh_YsLength = uint16(pTemp[8 + dh_pLength + dh_gLength] << 8 ) | pTemp[9 + dh_pLength + dh_gLength];
574 [ # # ]: 0 : if ( dh_pLength + dh_gLength + dh_YsLength + 6 > rec->length )
575 : : {
576 : 0 : Weird("SSLv3x: Corrupt length fields in server-key-exchange!");
577 : 0 : printf("xxx %u > %u \n", (dh_pLength + dh_gLength + dh_YsLength + 6), rec->length);
578 : 0 : return;
579 : : }
580 : :
581 : 0 : serverDHPars = new SSLv3x_ServerDHParams;
582 : 0 : serverDHPars->dh_p = new SSL_DataBlock(pTemp + 6 , dh_pLength);
583 : 0 : serverDHPars->dh_g = new SSL_DataBlock(pTemp + 8 + dh_pLength, dh_gLength);
584 : 0 : serverDHPars->dh_Ys = new SSL_DataBlock(pTemp + 10 + dh_pLength + dh_gLength, dh_YsLength);
585 : : }
586 : : }
587 : : }
588 : 0 : break;
589 : : }
590 : :
591 : : case SSL3_1_CERTIFICATE_REQUEST:
592 : : {
593 : : // Only if server not anonymous
594 : : /*
595 : : switch (cipherSuite)
596 : : {
597 : : case TLS_NULL_WITH_NULL_NULL:
598 : : case TLS_DH_ANON_EXPORT_WITH_RC4_40_MD5:
599 : : case TLS_DH_ANON_WITH_RC4_128_MD5:
600 : : case TLS_DH_ANON_EXPORT_WITH_DES40_CBC_SHA:
601 : : case TLS_DH_ANON_WITH_DES_CBC_SHA:
602 : : case TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA:
603 : : {
604 : : Weird("SSLv3x: Sending certificate-request not allowed for anonymous servers!");
605 : : break;
606 : : }
607 : : default:
608 : : {
609 : : break;
610 : : }
611 : : }
612 : : */
613 : :
614 [ # # ]: 0 : if ( ! pCipherSuite )
615 : : {
616 : : // if we have an unknown CIPHER-SPEC,
617 : : // we can't do our weird checks.
618 : 0 : break;
619 : : }
620 : :
621 [ # # ][ # # ]: 0 : if ( pCipherSuite->keyExchangeAlgorithm == SSL_KEY_EXCHANGE_DH_ANON || pCipherSuite->keyExchangeAlgorithm == SSL_KEY_EXCHANGE_DH_ANON_EXPORT )
622 : 0 : Weird("SSLv3x: Sending certificate-request not allowed for anonymous servers!");
623 : :
624 : : // FIXME: Insert weird checks!
625 : 0 : break;
626 : : }
627 : :
628 : : case SSL3_1_SERVER_HELLO_DONE:
629 : : {
630 [ # # ]: 0 : if ( rec->length != 0 )
631 : 0 : Weird("SSLv3x: Server hello too long!");
632 : 0 : break;
633 : : }
634 : :
635 : : case SSL3_1_CLIENT_KEY_EXCHANGE:
636 : : {
637 [ # # ]: 0 : if ( ! pCipherSuite )
638 : : // if we have an unknown CIPHER-SPEC,
639 : : // we can't do our weird checks
640 : 0 : break;
641 : :
642 : 0 : const u_char* pTemp = rec->data;
643 [ # # ]: 0 : if ( ssl_store_key_material )
644 : : {
645 : : SSL_KeyExchangeAlgorithm keyXAlgorithm =
646 : 0 : pCipherSuite->keyExchangeAlgorithm;
647 : :
648 [ # # ][ # # ]: 0 : if ( keyXAlgorithm == SSL_KEY_EXCHANGE_RSA || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_DSS || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_RSA )
[ # # ]
649 : : {
650 : : encryptedPreSecret =
651 : 0 : new SSLv3x_EncryptedPremasterSecret;
652 : : encryptedPreSecret->encryptedSecret =
653 : 0 : new SSL_DataBlock( pTemp + 4, rec->length);
654 : : }
655 : : else
656 : : {
657 [ # # ][ # # ]: 0 : if ( keyXAlgorithm == SSL_KEY_EXCHANGE_DH || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_DSS || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_DSS_EXPORT || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_RSA || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_RSA_EXPORT || keyXAlgorithm == SSL_KEY_EXCHANGE_DHE_DSS || keyXAlgorithm == SSL_KEY_EXCHANGE_DHE_DSS_EXPORT || keyXAlgorithm == SSL_KEY_EXCHANGE_DHE_RSA || keyXAlgorithm == SSL_KEY_EXCHANGE_DHE_RSA_EXPORT || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_ANON || keyXAlgorithm == SSL_KEY_EXCHANGE_DH_ANON_EXPORT || keyXAlgorithm == SSL_KEY_EXCHANGE_DHE_DSS_EXPORT1024 )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
658 : : {
659 [ # # ]: 0 : if ( rec->length < 2 )
660 : : {
661 : : // This can happen (see RFC 2246, p. 45).
662 : 0 : return;
663 : : }
664 : :
665 : : uint16 DHpublicLength =
666 : 0 : uint16(pTemp[4] << 8) | pTemp[5];
667 [ # # ]: 0 : if ( DHpublicLength + 2 < rec->length )
668 : : {
669 : 0 : Weird("SSLv3x: Corrupt length fields in client-key-exchange!");
670 : 0 : return;
671 : : }
672 : :
673 : 0 : clientDHpublic = new SSLv3x_ClientDHPublic;
674 : 0 : clientDHpublic->dh_Yc = new SSL_DataBlock(pTemp + 6, DHpublicLength);
675 : : }
676 : : }
677 : :
678 : : }
679 : 0 : break;
680 : : }
681 : :
682 : : case SSL3_1_CERTIFICATE_VERIFY:
683 : : {
684 : : // FIXME: Insert Weird checks!
685 : 0 : break;
686 : : }
687 : :
688 : : case SSL3_1_FINISHED:
689 : : {
690 : : // We won't get here, because finished messages
691 : : // are already encrypted, so we can't get
692 : : // the content type of this handshake-message...
693 : 0 : break;
694 : : }
695 : :
696 : : default:
697 : : {
698 [ # # ][ # # ]: 0 : if ( currentState == SSL3_1_STATE_SERVER_FIN_SENT_A ||
699 : : currentState == SSL3_1_STATE_CLIENT_FIN_SENT_B )
700 : : {
701 : 0 : Weird("SSLv3x: Handshake message (unknown type) after finished message!");
702 : 0 : return;
703 : : }
704 : : else
705 : : {
706 : 0 : Weird("SSLv3x: Invalid HandshakeType! Maybe finished message without predecessing change-cipher-message!");
707 : 0 : return; }
708 : : }
709 : : }
710 : : }
711 : :
712 : 0 : int oldState = currentState;
713 : 0 : bool alreadySwitchedState = false;
714 : :
715 : : // First: Special handling of finished messages. They must be
716 : : // sent immediately after a change cipher message - already encrypted.
717 : : // from client?
718 [ # # ][ # # ]: 0 : if ( rec->endp->IsOrig() && change_cipher_client_seen )
[ # # ]
719 : : {
720 [ # # ]: 0 : if ( ! fin_client_seen )
721 : : {
722 : : // This must be a (valid) client finished.
723 : : // We assume it to be one, because the predecessing
724 : : // message was a change cipher.
725 : 0 : fin_client_seen = true;
726 : 0 : change_cipher_client_seen = false;
727 : 0 : alreadySwitchedState = true;
728 : : currentState = sslAutomaton.getNextState(currentState,
729 : 0 : SSL3_1_TRANS_CLIENT_FIN);
730 : : }
731 : : else
732 : : {
733 : : // We already saw a client finished (should not be
734 : : // possible).
735 : 0 : Weird("SSLv3x: Already received client finished message!");
736 : : currentState = sslAutomaton.getNextState(currentState,
737 : 0 : SSL3_1_TRANS_CLIENT_FIN);
738 : 0 : fin_client_seen = true;
739 : 0 : change_cipher_client_seen = false;
740 : 0 : alreadySwitchedState = true;
741 : : }
742 : : }
743 : :
744 : : // from server
745 [ # # ][ # # ]: 0 : else if ( ! rec->endp->IsOrig() && change_cipher_server_seen )
[ # # ]
746 : : {
747 [ # # ]: 0 : if ( ! fin_server_seen )
748 : : {
749 : : // This must be a (valid) server finished.
750 : : // We assume it to be one, because the predecessing
751 : : // message was a change cipher.
752 : 0 : fin_server_seen = true;
753 : 0 : change_cipher_server_seen = false;
754 : 0 : alreadySwitchedState = true;
755 : : currentState = sslAutomaton.getNextState(currentState,
756 : 0 : SSL3_1_TRANS_SERVER_FIN);
757 : : }
758 : : else
759 : : {
760 : : // We already saw a server-finished (should not be
761 : : // possible).
762 : 0 : Weird("SSLv3x: Already received server finished message!");
763 : : currentState = sslAutomaton.getNextState(currentState,
764 : 0 : SSL3_1_TRANS_SERVER_FIN);
765 : 0 : alreadySwitchedState = true;
766 : 0 : fin_server_seen = true;
767 : 0 : change_cipher_server_seen = false;
768 : : }
769 : : }
770 : :
771 [ # # ]: 0 : if ( ! alreadySwitchedState )
772 : : {
773 : : // Check whether we are already finished with the
774 : : // handshaking process...
775 [ # # ]: 0 : switch ( currentState ) {
776 : : case SSL3_1_STATE_HS_FIN_A:
777 : : case SSL3_1_STATE_HS_FIN_B:
778 : 0 : Weird("SSLv3x: Received handshake message after finishing handshake!");
779 : 0 : break;
780 : :
781 : : default:
782 : : // It's a "normal" handshake message...
783 : : currentState = sslAutomaton.getNextState(currentState,
784 : 0 : HandshakeType2Trans(rec->type));
785 : : break;
786 : : }
787 : : }
788 : :
789 : 0 : if ( currentState == SSL3_1_STATE_ERROR )
790 : : {
791 : : // proxy->SetSkip(1);
792 : : }
793 : :
794 : : // Only if we changed the currentState, we need to call GenerateEvents
795 : : // because event generation in GenerateEvents() is based on
796 : : // currentState.
797 [ # # ]: 0 : if ( oldState != currentState )
798 : 0 : GenerateEvents(rec, currentCipherSuites);
799 : : else
800 : 0 : Unref(currentCipherSuites);
801 : : }
802 : :
803 : 0 : void SSLv3_Interpreter::DeliverSSLv3_Record(SSLv3_AlertRecord* rec)
804 : : {
805 : 0 : ++SSLv3_Interpreter::totalRecords;
806 : 0 : ++SSLv3_Interpreter::alertRecords;
807 : :
808 : : // First: consistency-checks.
809 : : // Only if handshake not already finished.
810 : : // Otherwise alerts may be encrypted, so we could do nothing...
811 [ # # ][ # # ]: 0 : if ( currentState == SSL3_1_STATE_SERVER_FIN_SENT_A ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
812 : : currentState == SSL3_1_STATE_CLIENT_FIN_SENT_B ||
813 : : currentState == SSL3_1_STATE_CLIENT_FIN_SENT_A ||
814 : : currentState == SSL3_1_STATE_SERVER_FIN_SENT_B ||
815 : : currentState == SSL3_1_STATE_HS_FIN_A ||
816 : : currentState == SSL3_1_STATE_HS_FIN_B ||
817 : : change_cipher_client_seen || change_cipher_server_seen )
818 : 0 : return;
819 : :
820 [ # # ][ # # ]: 0 : if ( rec->level != SSL3x_ALERT_LEVEL_WARNING &&
821 : : rec->level != SSL3x_ALERT_LEVEL_FATAL )
822 : 0 : Weird("SSLv3x: Unknown ssl alert level");
823 : :
824 : 0 : SSL3_1_AlertDescription ad = SSL3_1_AlertDescription(rec->description);
825 [ # # # # ]: 0 : switch ( ad ) {
826 : : case SSL3_1_CLOSE_NOTIFY:
827 : : case SSL3_1_UNEXPECTED_MESSAGE:
828 : : case SSL3_1_BAD_RECORD_MAC:
829 : : case SSL3_1_DECRYPTION_FAILED:
830 : : case SSL3_1_RECORD_OVERFLOW:
831 : : case SSL3_1_DECOMPRESSION_FAILURE:
832 : : case SSL3_1_HANDSHAKE_FAILURE:
833 : 0 : break;
834 : :
835 : : case SSL3_0_NO_CERTIFICATE:
836 : : // This may happen ONLY in SSLv3.0 when the server sends
837 : : // a certificate request but the client has none.
838 [ # # ]: 0 : if ( rec->sslVersion == SSLProxy_Analyzer::SSLv30 )
839 : 0 : currentState = SSL3_1_STATE_SERVER_HELLO_DONE_SENT_A;
840 : : else
841 : 0 : Weird("SSLv3x: No certificate alert not defined for SSL 3.1!");
842 : 0 : break;
843 : :
844 : : case SSL3_1_BAD_CERTIFICATE:
845 : : case SSL3_1_UNSUPPORTED_CERTIFICATE:
846 : : case SSL3_1_CERTIFICATE_REVOKED:
847 : : case SSL3_1_CERTIFICATE_EXPIRED:
848 : : case SSL3_1_CERTIFICATE_UNKNOWN:
849 : : case SSL3_1_ILLEGAL_PARAMETER:
850 : : case SSL3_1_UNKNOWN_CA:
851 : : case SSL3_1_ACCESS_DENIED:
852 : : case SSL3_1_DECODE_ERROR:
853 : : case SSL3_1_DECRYPT_ERROR:
854 : : case SSL3_1_EXPORT_RESTRICTION:
855 : : case SSL3_1_PROTOCOL_VERSION:
856 : : case SSL3_1_INSUFFICIENT_SECURITY:
857 : : case SSL3_1_INTERNAL_ERROR:
858 : : case SSL3_1_USER_CANCELED:
859 : : case SSL3_1_NO_RENEGOTIATION:
860 : 0 : break;
861 : :
862 : : default:
863 : 0 : Weird(" SSLv3x: Unknown ssl alert description!" );
864 : : break;
865 : : }
866 : :
867 [ # # ]: 0 : if ( rec->level == 2 )
868 : : // Fatal alert!
869 : 0 : currentState = SSL3_1_STATE_INIT;
870 : :
871 [ # # ][ # # ]: 0 : if ( rec->level == 1 && ad == SSL3_1_CLOSE_NOTIFY )
872 : 0 : currentState = SSL3_1_STATE_INIT;
873 : :
874 : 0 : fire_ssl_conn_alert(rec->sslVersion, rec->level, rec->description);
875 : : }
876 : :
877 : 0 : void SSLv3_Interpreter::DeliverSSLv3_Record(SSLv3_ChangeCipherRecord* rec)
878 : : {
879 : 0 : ++SSLv3_Interpreter::totalRecords;
880 : 0 : ++SSLv3_Interpreter::changeCipherRecords;
881 : :
882 [ # # ]: 0 : if ( rec->type != 1 )
883 : 0 : Weird("SSLv3x: Unknown change cipher type!");
884 [ # # ]: 0 : if ( rec->recordLength != 1 )
885 : 0 : Weird("SSLv3x: Change cipher message too long!");
886 : :
887 : : // After receiving a change cipher spec message, the next message sent
888 : : // MUST be a finished message. So we set the appropriate flag:
889 : : // change_cipher_client/server_seen.
890 [ # # ]: 0 : if ( rec->endp->IsOrig())
891 : : {
892 [ # # ]: 0 : if ( change_cipher_client_seen )
893 : 0 : Weird("SSLv3x: Received multiple change cipher message from client!");
894 : 0 : change_cipher_client_seen = true;
895 : 0 : fin_client_seen = false;
896 : : }
897 : : else
898 : : {
899 [ # # ]: 0 : if ( change_cipher_server_seen )
900 : 0 : Weird("SSLv3x: Received multiple change cipher message from server!");
901 : 0 : change_cipher_server_seen = true;
902 : 0 : fin_server_seen = false;
903 : : }
904 : :
905 : 0 : if ( currentState == SSL3_1_STATE_ERROR )
906 : : {
907 : : // proxy->SetSkip(1);
908 : : }
909 : :
910 : : // We don't need a GenerateEvents here, because we didn't change
911 : : // the currentState of the SSL automaton. (Event generation
912 : : // in GenerateEvents() is done based on currentState.)
913 : : // GenerateEvents(rec);
914 : 0 : }
915 : :
916 : 0 : void SSLv3_Interpreter::DeliverSSLv3_Record(SSLv3_ApplicationRecord* rec)
917 : : {
918 : 0 : ++SSLv3_Interpreter::totalRecords;
919 : :
920 [ # # ][ # # ]: 0 : if ( currentState == SSL3_1_STATE_HS_FIN_A ||
921 : : currentState == SSL3_1_STATE_HS_FIN_B )
922 : : // O.K., sending application data is valid
923 : : // this was the last record we analyzed...
924 : 0 : proxy->SetSkip(1);
925 : : else
926 : : {
927 : : // Sending application data now is not valid, so the SSL
928 : : // connection is probably already established and we
929 : : // didn't get the handshake.
930 : 0 : Weird("SSLv3_data_without_full_handshake");
931 : 0 : currentState = SSL3_1_STATE_ERROR;
932 : 0 : GenerateEvents(rec, 0);
933 : : }
934 : 0 : }
935 : :
936 : : TableVal* SSLv3_Interpreter::analyzeCiphers(const SSLv3_Endpoint* s, int length,
937 : 0 : const u_char* data, uint16 version)
938 : : {
939 : 0 : int is_orig = (SSL_InterpreterEndpoint*) s == orig;
940 : :
941 [ # # ]: 0 : if ( length > ssl_max_cipherspec_size )
942 : : {
943 [ # # ]: 0 : if ( is_orig )
944 : 0 : Weird("SSLv2: Client has CipherSpecs > ssl_max_cipherspec_size");
945 : : else
946 : 0 : Weird("SSLv2: Server has CipherSpecs > ssl_max_cipherspec_size");
947 : : }
948 : :
949 : 0 : const u_char* pCipher = data;
950 : 0 : SSL_CipherSpec* pCipherSuiteTemp = 0;
951 : : uint16 cipherSuite;
952 [ # # ]: 0 : for ( int i = 0; i < length; i += 2 )
953 : : {
954 : 0 : cipherSuite = uint16(pCipher[0+i] << 8) | pCipher[1+i];
955 : 0 : HashKey h(static_cast<bro_uint_t>(cipherSuite));
956 : :
957 : : pCipherSuiteTemp =
958 : 0 : (SSL_CipherSpec*) SSL_CipherSpecDict.Lookup(&h);
959 [ # # ]: 0 : if ( ! pCipherSuiteTemp )
960 : : {
961 [ # # ]: 0 : if ( is_orig )
962 : 0 : proxy->Weird("SSLv3x: Unknown CIPHER-SPEC in CLIENT-HELLO");
963 : : else
964 : 0 : proxy->Weird("SSLv3x: Unknown CIPHER-SPEC in SERVER-HELLO");
965 : : }
966 : : }
967 : :
968 : : // Store server's cipher specs.
969 [ # # ]: 0 : if ( ! is_orig )
970 : : {
971 : 0 : pCipherSuite = pCipherSuiteTemp;
972 [ # # ]: 0 : if ( ! pCipherSuite )
973 : : {
974 : : // Special case: we store the identifier directly
975 : : // for unknown cipher-specs.
976 : : cipherSuiteIdentifier =
977 : 0 : uint16(pCipher[0] << 8) | pCipher[1];
978 : : }
979 : : }
980 : :
981 [ # # ][ # # ]: 0 : if ( ssl_compare_cipherspecs && length <= ssl_max_cipherspec_size )
982 : : {
983 : : // Store cipher specs for analysis: was the choosen
984 : : // server cipher suite announced by the client?
985 [ # # ]: 0 : if ( is_orig )
986 : : {
987 : : pClientCipherSpecs =
988 : 0 : new SSL_DataBlock(data, length);
989 : : }
990 : : }
991 : :
992 [ # # ][ # # ]: 0 : if ( (! is_orig && ssl_conn_server_reply) ||
[ # # ][ # # ]
[ # # ]
993 : : (is_orig && ssl_conn_attempt) )
994 : : {
995 : 0 : TableVal* pCipherTable = new TableVal(cipher_suites_list);
996 [ # # ]: 0 : for ( int i = 0; i < length; i += 2 )
997 : : {
998 : 0 : uint32 cipherSpec = (pCipher[0] << 8) | pCipher[1];
999 : 0 : Val* index = new Val(cipherSpec, TYPE_COUNT);
1000 : 0 : pCipherTable->Assign(index, 0);
1001 : 0 : Unref(index);
1002 : 0 : pCipher += 2;
1003 : : }
1004 : :
1005 : 0 : return pCipherTable;
1006 : : }
1007 : :
1008 : : else
1009 : 0 : return 0;
1010 : : }
1011 : :
1012 : 0 : void SSLv3_Interpreter::GenerateEvents(SSLv3_Record* rec, TableVal* curCipherSuites)
1013 : : {
1014 [ # # ][ # # ]: 0 : if ( curCipherSuites &&
[ # # ]
1015 : : currentState != SSL3_1_STATE_CLIENT_HELLO_SENT &&
1016 : : currentState != SSL3_1_STATE_SERVER_HELLO_SENT )
1017 : : // Unref here, since the events won't do so in this case.
1018 : 0 : Unref(curCipherSuites);
1019 : :
1020 [ # # # # # : 0 : switch ( currentState ) {
# ]
1021 : : case SSL3_1_STATE_CLIENT_HELLO_SENT:
1022 : 0 : fire_ssl_conn_attempt(rec->sslVersion, curCipherSuites);
1023 : 0 : break;
1024 : :
1025 : : case SSL3_1_STATE_SERVER_HELLO_SENT:
1026 : 0 : fire_ssl_conn_server_reply(rec->sslVersion, curCipherSuites);
1027 : 0 : break;
1028 : :
1029 : : case SSL3_1_STATE_HS_FIN_A:
1030 : : case SSL3_1_STATE_HS_FIN_B:
1031 : 0 : ++SSLv3_Interpreter::openedConnections;
1032 : : fire_ssl_conn_established(rec->sslVersion,
1033 : : pCipherSuite ?
1034 [ # # ]: 0 : pCipherSuite->identifier : 0);
1035 : :
1036 : : // We finished handshake. Skip all further data.
1037 : 0 : proxy->SetSkip(1);
1038 : 0 : helloRequestValid = true;
1039 : 0 : break;
1040 : :
1041 : : case SSL3_1_STATE_SERVER_FIN_SENT_B:
1042 : : // First, check for session-ID match.
1043 [ # # ][ # # ]: 0 : if ( clientSessionID && serverSessionID &&
[ # # ]
1044 : : memcmp(clientSessionID->data, serverSessionID->data,
1045 : : clientSessionID->len) != 0 )
1046 : 0 : Weird("SSLv3x: Reusing session but session ID mismatch!");
1047 : 0 : fire_ssl_conn_reused(serverSessionID);
1048 : 0 : break;
1049 : :
1050 : : case SSL3_1_STATE_ERROR:
1051 : 0 : Weird("unexpected_SSLv3_record");
1052 : 0 : proxy->SetSkip(1);
1053 : : }
1054 : 0 : }
1055 : :
1056 : 0 : void SSLv3_Interpreter::SetState(int i)
1057 : : {
1058 [ # # ][ # # ]: 0 : if ( i >= 0 && i < SSL3_1_NUM_STATES )
1059 : 0 : currentState = i;
1060 : 0 : }
1061 : :
1062 : : // ---SSLv3_Endpoint--------------------------------------------------------------
1063 : :
1064 : 0 : SSLv3_Endpoint::SSLv3_Endpoint(SSL_Interpreter* interpreter, int is_orig)
1065 : 0 : : SSL_InterpreterEndpoint(interpreter, is_orig)
1066 : : {
1067 : 0 : sslVersion = 0;
1068 : 0 : }
1069 : :
1070 : 0 : SSLv3_Endpoint::~SSLv3_Endpoint()
1071 : : {
1072 [ # # ][ # # ]: 0 : }
[ # # ]
1073 : :
1074 : 0 : void SSLv3_Endpoint::Deliver(int len, const u_char* data)
1075 : : {
1076 [ # # ]: 0 : if ( SSL3_1_LENGTHOFFSET + sizeof(uint16) <= unsigned(len) )
1077 : : {
1078 : : currentMessage_length =
1079 : : uint16(data[SSL3_1_LENGTHOFFSET] << 8) |
1080 : 0 : data[SSL3_1_LENGTHOFFSET+1];
1081 : :
1082 : : // ### where does this magic number come from?
1083 [ # # ]: 0 : if ( currentMessage_length > 18432 )
1084 : 0 : interpreter->Weird("SSLv3x: Message length too long!");
1085 : : }
1086 : : else
1087 : : {
1088 : 0 : interpreter->Weird("SSLv3x: Could not determine message length!");
1089 : 0 : return;
1090 : : }
1091 : :
1092 [ # # ]: 0 : if ( currentMessage_length + 2 + SSL3_1_LENGTHOFFSET != len )
1093 : : {
1094 : : // This should never happen; otherwise there is a bug in the
1095 : : // SSL_RecordBuilder.
1096 : 0 : interpreter->Weird("SSLv3x: FATAL: recordLength doesn't match data block length!");
1097 : 0 : interpreter->Proxy()->SetSkip(1);
1098 : 0 : return;
1099 : : }
1100 : :
1101 : 0 : ProcessMessage(data, len);
1102 : : }
1103 : :
1104 : 0 : void SSLv3_Endpoint::ProcessMessage(const u_char* data, int len)
1105 : : {
1106 : 0 : SSL3_1_ContentType ct = ExtractContentType(data, len);
1107 [ # # ]: 0 : if ( ! ExtractVersion(data, len) )
1108 : 0 : return;
1109 : :
1110 [ # # # # : 0 : switch ( ct ) {
# ]
1111 : : case SSL3_1_TYPE_CHANGE_CIPHER_SPEC:
1112 : : {
1113 : : SSLv3_ChangeCipherRecord* rec = new
1114 : : SSLv3_ChangeCipherRecord(data + SSL3_1_HEADERLENGTH,
1115 : 0 : len - SSL3_1_HEADERLENGTH, sslVersion, this);
1116 : :
1117 : : // Multiple handshake messages may be coalesced into
1118 : : // a single record.
1119 : 0 : rec->Deliver((SSLv3_Interpreter*) interpreter);
1120 : 0 : Unref(rec);
1121 : 0 : break;
1122 : : }
1123 : :
1124 : : case SSL3_1_TYPE_ALERT:
1125 : : {
1126 : : SSLv3_AlertRecord* rec = new
1127 : : SSLv3_AlertRecord(data + SSL3_1_HEADERLENGTH,
1128 : 0 : len - SSL3_1_HEADERLENGTH, sslVersion, this);
1129 : 0 : rec->Deliver((SSLv3_Interpreter*) interpreter);
1130 : 0 : Unref(rec);
1131 : 0 : break;
1132 : : }
1133 : :
1134 : : case SSL3_1_TYPE_HANDSHAKE:
1135 : : {
1136 : : SSLv3_HandshakeRecord* rec =
1137 : : new SSLv3_HandshakeRecord(data + SSL3_1_HEADERLENGTH,
1138 : 0 : len - SSL3_1_HEADERLENGTH, sslVersion, this);
1139 : 0 : rec->Deliver((SSLv3_Interpreter*) interpreter);
1140 : 0 : Unref(rec);
1141 : 0 : break;
1142 : : }
1143 : :
1144 : : case SSL3_1_TYPE_APPLICATION_DATA:
1145 : : {
1146 : : SSLv3_ApplicationRecord* rec =
1147 : : new SSLv3_ApplicationRecord(data + SSL3_1_HEADERLENGTH,
1148 : 0 : len - SSL3_1_HEADERLENGTH, sslVersion, this);
1149 : 0 : rec->Deliver((SSLv3_Interpreter*) interpreter);
1150 : 0 : Unref(rec);
1151 : 0 : break;
1152 : : }
1153 : :
1154 : : default:
1155 : : {
1156 : 0 : interpreter->Weird("SSLv3x: Could not determine content type!");
1157 : : break;
1158 : : }
1159 : : }
1160 : : }
1161 : :
1162 : : SSL3_1_ContentType SSLv3_Endpoint::ExtractContentType(const u_char* data,
1163 : 0 : int len)
1164 : : {
1165 : 0 : return SSL3_1_ContentType(uint8(*(data + SSL3_1_CONTENTTYPEOFFSET)));
1166 : : }
1167 : :
1168 : 0 : int SSLv3_Endpoint::ExtractVersion(const u_char* data, int len)
1169 : : {
1170 : : sslVersion = uint16(data[SSL3_1_VERSIONTYPEOFFSET] << 8) |
1171 : 0 : data[SSL3_1_VERSIONTYPEOFFSET + 1];
1172 : :
1173 [ # # ][ # # ]: 0 : if ( sslVersion != SSLProxy_Analyzer::SSLv30 &&
1174 : : sslVersion != SSLProxy_Analyzer::SSLv31 )
1175 : : {
1176 : 0 : interpreter->Weird("SSLv3x: Unsupported SSL-Version (not SSLv3x)!");
1177 : 0 : return 0;
1178 : : }
1179 : : else
1180 : 0 : return 1;
1181 : : }
1182 : :
1183 : : // ---SSLv3_Record----------------------------------------------------------------
1184 : :
1185 : : SSLv3_Record::SSLv3_Record(const u_char* data, int len,
1186 : 0 : uint16 version, SSLv3_Endpoint const* e)
1187 : : {
1188 : 0 : recordLength = len;
1189 : 0 : sslVersion = version;
1190 : 0 : endp = e;
1191 : 0 : this->data = data;
1192 : 0 : }
1193 : :
1194 : 0 : SSLv3_Record::~SSLv3_Record()
1195 : : {
1196 : : // The memory for data is deleted after processing the ssl record
1197 : : // in the common ssl reassembler.
1198 [ # # ][ # # ]: 0 : }
[ # # ]
1199 : :
1200 : 0 : void SSLv3_Record::Describe(ODesc* d) const
1201 : : {
1202 : 0 : d->Add("sslrecord");
1203 : 0 : }
1204 : :
1205 : 0 : SSLv3_Endpoint const* SSLv3_Record::GetEndpoint() const
1206 : : {
1207 : 0 : return endp;
1208 : : }
1209 : :
1210 : 0 : const u_char* SSLv3_Record::GetData() const
1211 : : {
1212 : 0 : return data;
1213 : : }
1214 : :
1215 : 0 : int SSLv3_Record::ExtractInt24(const u_char* data, int len, int offset)
1216 : : {
1217 [ # # ]: 0 : if ( offset + int(sizeof(unsigned long)) - 1 > len)
1218 : 0 : return 0;
1219 : :
1220 : : uint32 val;
1221 : :
1222 : 0 : val = 0;
1223 : 0 : val = uint32(*(data + offset + 2));
1224 : 0 : val |= uint32(*(data + offset + 1)) << 8;
1225 : 0 : val |= uint32(*(data + offset)) << 16;
1226 : :
1227 : 0 : return val;
1228 : : }
1229 : :
1230 : 0 : int SSLv3_Record::GetRecordLength() const
1231 : : {
1232 : 0 : return recordLength;
1233 : : }
1234 : :
1235 : : SSLv3_HandshakeRecord::SSLv3_HandshakeRecord(const u_char* data, int len,
1236 : 0 : uint16 version, SSLv3_Endpoint const* e)
1237 : 0 : : SSLv3_Record(data, len, version, e)
1238 : : {
1239 : : // Weird-check for minimum handshake length header.
1240 [ # # # # ]: 0 : if ( len < 4 )
1241 : : {
1242 : 0 : e->Interpreter()->Weird("SSLv3x: Handshake-header-length too small!");
1243 : 0 : type = 255;
1244 : 0 : length = 0;
1245 : 0 : next = 0;
1246 : 0 : return;
1247 : : }
1248 : :
1249 : : // Don't analyze encrypted client handshake messages.
1250 [ # # ][ # # ]: 0 : if ( e->IsOrig() &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1251 : : ((SSLv3_Interpreter*) e->Interpreter())->change_cipher_client_seen &&
1252 : : ! ((SSLv3_Interpreter*) e->Interpreter())->fin_client_seen )
1253 : : {
1254 : 0 : type = 255;
1255 : 0 : length = 0;
1256 : 0 : next = 0;
1257 : 0 : return;
1258 : : }
1259 : :
1260 : : // Don't analyze encrypted server handshake messages.
1261 [ # # ][ # # ]: 0 : if ( ! e->IsOrig() &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1262 : : ((SSLv3_Interpreter*) e->Interpreter())->change_cipher_server_seen &&
1263 : : ! ((SSLv3_Interpreter*) e->Interpreter())->fin_server_seen )
1264 : : {
1265 : 0 : type = 255;
1266 : 0 : length = 0;
1267 : 0 : next = 0;
1268 : 0 : return;
1269 : : }
1270 : :
1271 : 0 : type = uint8(*(this->data));
1272 : 0 : length = ExtractInt24(data, len, 1);
1273 [ # # # # ]: 0 : if ( length + 4 < len )
1274 : : next = new SSLv3_HandshakeRecord(data + length + 4,
1275 : 0 : len - (length + 4), version, e);
1276 [ # # ][ # # ]: 0 : else if ( length + 4 > len )
1277 : : {
1278 : 0 : e->Interpreter()->Weird("SSLv3x: Handshake-header-length inconsistent (too big)");
1279 : 0 : next = 0;
1280 : : }
1281 : : else
1282 : 0 : next = 0;
1283 : 0 : }
1284 : :
1285 : 0 : SSLv3_HandshakeRecord::~SSLv3_HandshakeRecord()
1286 : : {
1287 [ # # ][ # # ]: 0 : if ( next )
[ # # ]
1288 : : {
1289 [ # # ][ # # ]: 0 : delete next;
[ # # ]
1290 : : }
1291 [ # # ][ # # ]: 0 : }
[ # # ]
1292 : :
1293 : 0 : void SSLv3_HandshakeRecord::Deliver(SSLv3_Interpreter* conn)
1294 : : {
1295 : 0 : SSLv3_HandshakeRecord* it = this;
1296 [ # # ]: 0 : while ( it != 0)
1297 : : {
1298 : 0 : conn->DeliverSSLv3_Record(it);
1299 : 0 : it = it->GetNext();
1300 : : }
1301 : 0 : }
1302 : :
1303 : 0 : int SSLv3_HandshakeRecord::GetType() const
1304 : : {
1305 : 0 : return type;
1306 : : }
1307 : :
1308 : 0 : int SSLv3_HandshakeRecord::GetLength() const
1309 : : {
1310 : 0 : return length;
1311 : : }
1312 : :
1313 : 0 : SSLv3_HandshakeRecord* SSLv3_HandshakeRecord::GetNext()
1314 : : {
1315 : 0 : return next;
1316 : : }
1317 : :
1318 : 0 : int SSLv3_HandshakeRecord::checkClientHello()
1319 : : {
1320 [ # # ]: 0 : if ( recordLength < 42 )
1321 : : {
1322 : 0 : endp->Interpreter()->Weird("SSLv3x: Client hello too small!");
1323 : 0 : return 0;
1324 : : }
1325 : :
1326 : 0 : uint16 version = uint16(data[4] << 8 ) | data[5];
1327 [ # # ][ # # ]: 0 : if ( version != SSLProxy_Analyzer::SSLv30 &&
1328 : : version != SSLProxy_Analyzer::SSLv31 )
1329 : 0 : endp->Interpreter()->Weird("SSLv3x: Corrupt version information in Client hello!");
1330 : :
1331 : 0 : uint8 sessionIDLength = uint8(data[38]);
1332 [ # # ]: 0 : if ( sessionIDLength > 32 )
1333 : : {
1334 : 0 : endp->Interpreter()->Weird("SSLv3x: SessionID too long in Client hello!");
1335 : 0 : return 0;
1336 : : }
1337 : :
1338 : : uint16 cipherSuiteLength =
1339 : : uint16(data[39 + sessionIDLength] << 8 ) |
1340 : 0 : data[40 + sessionIDLength];
1341 : :
1342 [ # # ]: 0 : if ( cipherSuiteLength < 2 )
1343 : 0 : endp->Interpreter()->Weird("SSLv3x: CipherSuite length too small!");
1344 : :
1345 [ # # ]: 0 : if ( cipherSuiteLength + sessionIDLength + 41 > recordLength )
1346 : : {
1347 : 0 : endp->Interpreter()->Weird("SSLv3x: Client hello too small, corrupt length fields!");
1348 : 0 : return 0;
1349 : : }
1350 : :
1351 : : uint8 compressionMethodLength =
1352 : 0 : uint8(data[41 + sessionIDLength + cipherSuiteLength]);
1353 : :
1354 [ # # ]: 0 : if ( compressionMethodLength < 1 )
1355 : 0 : endp->Interpreter()->Weird("SSLv3x: CompressionMethod length too small!");
1356 : :
1357 [ # # ]: 0 : if ( sessionIDLength + cipherSuiteLength +
1358 : : compressionMethodLength + 38 != length )
1359 : : {
1360 : 0 : endp->Interpreter()->Weird("SSLv3x: Corrupt length fields in Client hello!");
1361 : 0 : return 0;
1362 : : }
1363 : :
1364 : 0 : return 1;
1365 : : }
1366 : :
1367 : 0 : int SSLv3_HandshakeRecord::checkServerHello()
1368 : : {
1369 [ # # ]: 0 : if ( recordLength < 42 )
1370 : : {
1371 : 0 : endp->Interpreter()->Weird("SSLv3x: Server hello too small!");
1372 : 0 : return 0;
1373 : : }
1374 : :
1375 : 0 : uint16 version = uint16(data[4] << 8) | data[5];
1376 [ # # ][ # # ]: 0 : if ( version != SSLProxy_Analyzer::SSLv30 &&
1377 : : version != SSLProxy_Analyzer::SSLv31 )
1378 : 0 : endp->Interpreter()->Weird("SSLv3x: Corrupt version information in Server hello!");
1379 : :
1380 : 0 : uint8 sessionIDLength = uint8(data[38]);
1381 [ # # ]: 0 : if ( sessionIDLength > 32 )
1382 : : {
1383 : 0 : endp->Interpreter()->Weird("SSLv3x: SessionID too long in Server hello!");
1384 : 0 : return 0;
1385 : : }
1386 : :
1387 [ # # ]: 0 : if ( (sessionIDLength + 38) != length )
1388 : : {
1389 : 0 : endp->Interpreter()->Weird("SSLv3x: Corrupt length fields in Server hello!");
1390 : 0 : return 0;
1391 : : }
1392 : :
1393 : 0 : return 1;
1394 : : }
1395 : :
1396 : : SSLv3_AlertRecord::SSLv3_AlertRecord(const u_char* data, int len,
1397 : 0 : uint16 version, SSLv3_Endpoint const* e)
1398 : 0 : : SSLv3_Record(data, len, version, e)
1399 : : {
1400 [ # # # # ]: 0 : if ( len < 2 )
1401 : : {
1402 : 0 : e->Interpreter()->Weird("SSLv3x: Alert header length too small!");
1403 : 0 : level = 255;
1404 : 0 : description = 255;
1405 : : }
1406 : :
1407 : : // No further consistency-check, because alerts may be
1408 : : // already encrypted.
1409 : 0 : level = uint8(*((this->data) + SSL3_1_ALERT_LEVEL_OFFSET));
1410 : 0 : description = uint8(*((this->data) + SSL3_1_ALERT_DESCRIPTION_OFFSET));
1411 : 0 : }
1412 : :
1413 : 0 : SSLv3_AlertRecord::~SSLv3_AlertRecord()
1414 : : {
1415 [ # # ][ # # ]: 0 : }
[ # # ]
1416 : :
1417 : 0 : int SSLv3_AlertRecord::GetDescription() const
1418 : : {
1419 : 0 : return description;
1420 : : }
1421 : :
1422 : 0 : int SSLv3_AlertRecord::GetLevel() const
1423 : : {
1424 : 0 : return level;
1425 : : }
1426 : :
1427 : 0 : void SSLv3_AlertRecord::Deliver(SSLv3_Interpreter* conn)
1428 : : {
1429 : 0 : conn->DeliverSSLv3_Record(this);
1430 : 0 : }
1431 : :
1432 : : SSLv3_ChangeCipherRecord::SSLv3_ChangeCipherRecord(const u_char* data, int len,
1433 : 0 : uint16 version, SSLv3_Endpoint const* e)
1434 : 0 : : SSLv3_Record(data, len, version, e)
1435 : : {
1436 [ # # # # ]: 0 : if ( len < 1 )
1437 : : {
1438 : 0 : e->Interpreter()->Weird("SSLv3x: Change cipher header length too small!");
1439 : 0 : type = 255;
1440 : : }
1441 : : else
1442 : 0 : type = uint8(*((this->data) + SSL3_1_CHANGE_CIPHER_TYPE_OFFSET));
1443 : 0 : }
1444 : :
1445 : 0 : SSLv3_ChangeCipherRecord::~SSLv3_ChangeCipherRecord()
1446 : : {
1447 [ # # ][ # # ]: 0 : }
[ # # ]
1448 : :
1449 : 0 : int SSLv3_ChangeCipherRecord::GetType() const
1450 : : {
1451 : 0 : return type;
1452 : : }
1453 : :
1454 : 0 : void SSLv3_ChangeCipherRecord::Deliver(SSLv3_Interpreter* conn)
1455 : : {
1456 : 0 : conn->DeliverSSLv3_Record(this);
1457 : 0 : }
1458 : :
1459 : 0 : SSLv3_ApplicationRecord::SSLv3_ApplicationRecord(const u_char* data, int len, uint16 version, SSLv3_Endpoint const* e)
1460 : 0 : : SSLv3_Record(data, len, version, e)
1461 : : {
1462 : 0 : }
1463 : :
1464 : 0 : SSLv3_ApplicationRecord::~SSLv3_ApplicationRecord()
1465 : : {
1466 [ # # ][ # # ]: 0 : }
[ # # ]
1467 : :
1468 : 0 : void SSLv3_ApplicationRecord::Deliver(SSLv3_Interpreter* conn)
1469 : : {
1470 : 0 : conn->DeliverSSLv3_Record(this);
1471 [ + - ][ + - ]: 6 : }
|