diff options
author | jsing <> | 2017-10-10 15:13:26 +0000 |
---|---|---|
committer | jsing <> | 2017-10-10 15:13:26 +0000 |
commit | 50b0edb9d3ae72d9c4ace7aa8779e76a2b64068f (patch) | |
tree | f95f7f0c3a406dd1dd25069a69ae5946e7eb8ad5 /src/lib/libssl/d1_clnt.c | |
parent | dd1d617d105867f42195ad190923c6c1fe92e710 (diff) | |
download | openbsd-50b0edb9d3ae72d9c4ace7aa8779e76a2b64068f.tar.gz openbsd-50b0edb9d3ae72d9c4ace7aa8779e76a2b64068f.tar.bz2 openbsd-50b0edb9d3ae72d9c4ace7aa8779e76a2b64068f.zip |
Merge dtls1_connect() into ssl3_connect(), removing a large amount of
duplicated code. For now this is essentially adds a diff of the two
functions with 'if (SSL_IS_DTLS(s))' - further clean up and improvement
will follow.
ok inoguchi@
Diffstat (limited to 'src/lib/libssl/d1_clnt.c')
-rw-r--r-- | src/lib/libssl/d1_clnt.c | 436 |
1 files changed, 2 insertions, 434 deletions
diff --git a/src/lib/libssl/d1_clnt.c b/src/lib/libssl/d1_clnt.c index 5a5e17699d..f3a7e5ff22 100644 --- a/src/lib/libssl/d1_clnt.c +++ b/src/lib/libssl/d1_clnt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: d1_clnt.c,v 1.78 2017/10/08 16:54:28 jsing Exp $ */ | 1 | /* $OpenBSD: d1_clnt.c,v 1.79 2017/10/10 15:13:26 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * DTLS implementation written by Nagendra Modadugu | 3 | * DTLS implementation written by Nagendra Modadugu |
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | 4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. |
@@ -127,8 +127,6 @@ | |||
127 | 127 | ||
128 | #include "bytestring.h" | 128 | #include "bytestring.h" |
129 | 129 | ||
130 | static int dtls1_get_hello_verify(SSL *s); | ||
131 | |||
132 | static const SSL_METHOD_INTERNAL DTLSv1_client_method_internal_data = { | 130 | static const SSL_METHOD_INTERNAL DTLSv1_client_method_internal_data = { |
133 | .version = DTLS1_VERSION, | 131 | .version = DTLS1_VERSION, |
134 | .min_version = DTLS1_VERSION, | 132 | .min_version = DTLS1_VERSION, |
@@ -137,7 +135,7 @@ static const SSL_METHOD_INTERNAL DTLSv1_client_method_internal_data = { | |||
137 | .ssl_clear = dtls1_clear, | 135 | .ssl_clear = dtls1_clear, |
138 | .ssl_free = dtls1_free, | 136 | .ssl_free = dtls1_free, |
139 | .ssl_accept = ssl_undefined_function, | 137 | .ssl_accept = ssl_undefined_function, |
140 | .ssl_connect = dtls1_connect, | 138 | .ssl_connect = ssl3_connect, |
141 | .ssl_read = ssl3_read, | 139 | .ssl_read = ssl3_read, |
142 | .ssl_peek = ssl3_peek, | 140 | .ssl_peek = ssl3_peek, |
143 | .ssl_write = ssl3_write, | 141 | .ssl_write = ssl3_write, |
@@ -178,436 +176,6 @@ dtls1_get_client_method(int ver) | |||
178 | } | 176 | } |
179 | 177 | ||
180 | int | 178 | int |
181 | dtls1_connect(SSL *s) | ||
182 | { | ||
183 | void (*cb)(const SSL *ssl, int type, int val) = NULL; | ||
184 | int ret = -1; | ||
185 | int new_state, state, skip = 0; | ||
186 | |||
187 | ERR_clear_error(); | ||
188 | errno = 0; | ||
189 | |||
190 | if (s->internal->info_callback != NULL) | ||
191 | cb = s->internal->info_callback; | ||
192 | else if (s->ctx->internal->info_callback != NULL) | ||
193 | cb = s->ctx->internal->info_callback; | ||
194 | |||
195 | s->internal->in_handshake++; | ||
196 | if (!SSL_in_init(s) || SSL_in_before(s)) | ||
197 | SSL_clear(s); | ||
198 | |||
199 | for (;;) { | ||
200 | state = S3I(s)->hs.state; | ||
201 | |||
202 | switch (S3I(s)->hs.state) { | ||
203 | case SSL_ST_RENEGOTIATE: | ||
204 | s->internal->renegotiate = 1; | ||
205 | S3I(s)->hs.state = SSL_ST_CONNECT; | ||
206 | s->ctx->internal->stats.sess_connect_renegotiate++; | ||
207 | /* break */ | ||
208 | case SSL_ST_BEFORE: | ||
209 | case SSL_ST_CONNECT: | ||
210 | case SSL_ST_BEFORE|SSL_ST_CONNECT: | ||
211 | case SSL_ST_OK|SSL_ST_CONNECT: | ||
212 | |||
213 | s->server = 0; | ||
214 | if (cb != NULL) | ||
215 | cb(s, SSL_CB_HANDSHAKE_START, 1); | ||
216 | |||
217 | if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { | ||
218 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
219 | ret = -1; | ||
220 | goto end; | ||
221 | } | ||
222 | |||
223 | /* s->version=SSL3_VERSION; */ | ||
224 | s->internal->type = SSL_ST_CONNECT; | ||
225 | |||
226 | if (!ssl3_setup_init_buffer(s)) { | ||
227 | ret = -1; | ||
228 | goto end; | ||
229 | } | ||
230 | if (!ssl3_setup_buffers(s)) { | ||
231 | ret = -1; | ||
232 | goto end; | ||
233 | } | ||
234 | if (!ssl_init_wbio_buffer(s, 0)) { | ||
235 | ret = -1; | ||
236 | goto end; | ||
237 | } | ||
238 | |||
239 | /* don't push the buffering BIO quite yet */ | ||
240 | |||
241 | S3I(s)->hs.state = SSL3_ST_CW_CLNT_HELLO_A; | ||
242 | s->ctx->internal->stats.sess_connect++; | ||
243 | s->internal->init_num = 0; | ||
244 | /* mark client_random uninitialized */ | ||
245 | memset(s->s3->client_random, 0, | ||
246 | sizeof(s->s3->client_random)); | ||
247 | D1I(s)->send_cookie = 0; | ||
248 | s->internal->hit = 0; | ||
249 | break; | ||
250 | |||
251 | case SSL3_ST_CW_CLNT_HELLO_A: | ||
252 | case SSL3_ST_CW_CLNT_HELLO_B: | ||
253 | |||
254 | s->internal->shutdown = 0; | ||
255 | |||
256 | /* every DTLS ClientHello resets Finished MAC */ | ||
257 | if (!tls1_init_finished_mac(s)) { | ||
258 | ret = -1; | ||
259 | goto end; | ||
260 | } | ||
261 | |||
262 | dtls1_start_timer(s); | ||
263 | ret = ssl3_client_hello(s); | ||
264 | if (ret <= 0) | ||
265 | goto end; | ||
266 | |||
267 | if (D1I(s)->send_cookie) { | ||
268 | S3I(s)->hs.state = SSL3_ST_CW_FLUSH; | ||
269 | S3I(s)->hs.next_state = SSL3_ST_CR_SRVR_HELLO_A; | ||
270 | } else | ||
271 | S3I(s)->hs.state = SSL3_ST_CR_SRVR_HELLO_A; | ||
272 | |||
273 | s->internal->init_num = 0; | ||
274 | |||
275 | /* turn on buffering for the next lot of output */ | ||
276 | if (s->bbio != s->wbio) | ||
277 | s->wbio = BIO_push(s->bbio, s->wbio); | ||
278 | |||
279 | break; | ||
280 | |||
281 | case SSL3_ST_CR_SRVR_HELLO_A: | ||
282 | case SSL3_ST_CR_SRVR_HELLO_B: | ||
283 | ret = ssl3_get_server_hello(s); | ||
284 | if (ret <= 0) | ||
285 | goto end; | ||
286 | if (s->internal->hit) | ||
287 | S3I(s)->hs.state = SSL3_ST_CR_FINISHED_A; | ||
288 | else | ||
289 | S3I(s)->hs.state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; | ||
290 | s->internal->init_num = 0; | ||
291 | break; | ||
292 | |||
293 | case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: | ||
294 | case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: | ||
295 | |||
296 | ret = dtls1_get_hello_verify(s); | ||
297 | if (ret <= 0) | ||
298 | goto end; | ||
299 | dtls1_stop_timer(s); | ||
300 | if ( D1I(s)->send_cookie) /* start again, with a cookie */ | ||
301 | S3I(s)->hs.state = SSL3_ST_CW_CLNT_HELLO_A; | ||
302 | else | ||
303 | S3I(s)->hs.state = SSL3_ST_CR_CERT_A; | ||
304 | s->internal->init_num = 0; | ||
305 | break; | ||
306 | |||
307 | case SSL3_ST_CR_CERT_A: | ||
308 | case SSL3_ST_CR_CERT_B: | ||
309 | ret = ssl3_check_finished(s); | ||
310 | if (ret <= 0) | ||
311 | goto end; | ||
312 | if (ret == 2) { | ||
313 | s->internal->hit = 1; | ||
314 | if (s->internal->tlsext_ticket_expected) | ||
315 | S3I(s)->hs.state = SSL3_ST_CR_SESSION_TICKET_A; | ||
316 | else | ||
317 | S3I(s)->hs.state = SSL3_ST_CR_FINISHED_A; | ||
318 | s->internal->init_num = 0; | ||
319 | break; | ||
320 | } | ||
321 | /* Check if it is anon DH/ECDH. */ | ||
322 | if (!(S3I(s)->hs.new_cipher->algorithm_auth & | ||
323 | SSL_aNULL)) { | ||
324 | ret = ssl3_get_server_certificate(s); | ||
325 | if (ret <= 0) | ||
326 | goto end; | ||
327 | if (s->internal->tlsext_status_expected) | ||
328 | S3I(s)->hs.state = SSL3_ST_CR_CERT_STATUS_A; | ||
329 | else | ||
330 | S3I(s)->hs.state = SSL3_ST_CR_KEY_EXCH_A; | ||
331 | } else { | ||
332 | skip = 1; | ||
333 | S3I(s)->hs.state = SSL3_ST_CR_KEY_EXCH_A; | ||
334 | } | ||
335 | s->internal->init_num = 0; | ||
336 | break; | ||
337 | |||
338 | case SSL3_ST_CR_KEY_EXCH_A: | ||
339 | case SSL3_ST_CR_KEY_EXCH_B: | ||
340 | ret = ssl3_get_server_key_exchange(s); | ||
341 | if (ret <= 0) | ||
342 | goto end; | ||
343 | S3I(s)->hs.state = SSL3_ST_CR_CERT_REQ_A; | ||
344 | s->internal->init_num = 0; | ||
345 | |||
346 | /* | ||
347 | * At this point we check that we have the | ||
348 | * required stuff from the server. | ||
349 | */ | ||
350 | if (!ssl3_check_cert_and_algorithm(s)) { | ||
351 | ret = -1; | ||
352 | goto end; | ||
353 | } | ||
354 | break; | ||
355 | |||
356 | case SSL3_ST_CR_CERT_REQ_A: | ||
357 | case SSL3_ST_CR_CERT_REQ_B: | ||
358 | ret = ssl3_get_certificate_request(s); | ||
359 | if (ret <= 0) | ||
360 | goto end; | ||
361 | S3I(s)->hs.state = SSL3_ST_CR_SRVR_DONE_A; | ||
362 | s->internal->init_num = 0; | ||
363 | break; | ||
364 | |||
365 | case SSL3_ST_CR_SRVR_DONE_A: | ||
366 | case SSL3_ST_CR_SRVR_DONE_B: | ||
367 | ret = ssl3_get_server_done(s); | ||
368 | if (ret <= 0) | ||
369 | goto end; | ||
370 | dtls1_stop_timer(s); | ||
371 | if (S3I(s)->tmp.cert_req) | ||
372 | S3I(s)->hs.state = SSL3_ST_CW_CERT_A; | ||
373 | else | ||
374 | S3I(s)->hs.state = SSL3_ST_CW_KEY_EXCH_A; | ||
375 | s->internal->init_num = 0; | ||
376 | break; | ||
377 | |||
378 | case SSL3_ST_CW_CERT_A: | ||
379 | case SSL3_ST_CW_CERT_B: | ||
380 | case SSL3_ST_CW_CERT_C: | ||
381 | case SSL3_ST_CW_CERT_D: | ||
382 | dtls1_start_timer(s); | ||
383 | ret = ssl3_send_client_certificate(s); | ||
384 | if (ret <= 0) | ||
385 | goto end; | ||
386 | S3I(s)->hs.state = SSL3_ST_CW_KEY_EXCH_A; | ||
387 | s->internal->init_num = 0; | ||
388 | break; | ||
389 | |||
390 | case SSL3_ST_CW_KEY_EXCH_A: | ||
391 | case SSL3_ST_CW_KEY_EXCH_B: | ||
392 | dtls1_start_timer(s); | ||
393 | ret = ssl3_send_client_key_exchange(s); | ||
394 | if (ret <= 0) | ||
395 | goto end; | ||
396 | /* | ||
397 | * EAY EAY EAY need to check for DH fix cert | ||
398 | * sent back | ||
399 | */ | ||
400 | /* | ||
401 | * For TLS, cert_req is set to 2, so a cert chain | ||
402 | * of nothing is sent, but no verify packet is sent | ||
403 | */ | ||
404 | /* | ||
405 | * XXX: For now, we do not support client | ||
406 | * authentication in ECDH cipher suites with | ||
407 | * ECDH (rather than ECDSA) certificates. | ||
408 | * We need to skip the certificate verify | ||
409 | * message when client's ECDH public key is sent | ||
410 | * inside the client certificate. | ||
411 | */ | ||
412 | if (S3I(s)->tmp.cert_req == 1) { | ||
413 | S3I(s)->hs.state = SSL3_ST_CW_CERT_VRFY_A; | ||
414 | } else { | ||
415 | S3I(s)->hs.state = SSL3_ST_CW_CHANGE_A; | ||
416 | S3I(s)->change_cipher_spec = 0; | ||
417 | } | ||
418 | |||
419 | s->internal->init_num = 0; | ||
420 | break; | ||
421 | |||
422 | case SSL3_ST_CW_CERT_VRFY_A: | ||
423 | case SSL3_ST_CW_CERT_VRFY_B: | ||
424 | dtls1_start_timer(s); | ||
425 | ret = ssl3_send_client_verify(s); | ||
426 | if (ret <= 0) | ||
427 | goto end; | ||
428 | S3I(s)->hs.state = SSL3_ST_CW_CHANGE_A; | ||
429 | s->internal->init_num = 0; | ||
430 | S3I(s)->change_cipher_spec = 0; | ||
431 | break; | ||
432 | |||
433 | case SSL3_ST_CW_CHANGE_A: | ||
434 | case SSL3_ST_CW_CHANGE_B: | ||
435 | if (!s->internal->hit) | ||
436 | dtls1_start_timer(s); | ||
437 | ret = ssl3_send_change_cipher_spec(s, | ||
438 | SSL3_ST_CW_CHANGE_A, SSL3_ST_CW_CHANGE_B); | ||
439 | if (ret <= 0) | ||
440 | goto end; | ||
441 | |||
442 | S3I(s)->hs.state = SSL3_ST_CW_FINISHED_A; | ||
443 | s->internal->init_num = 0; | ||
444 | |||
445 | s->session->cipher = S3I(s)->hs.new_cipher; | ||
446 | if (!tls1_setup_key_block(s)) { | ||
447 | ret = -1; | ||
448 | goto end; | ||
449 | } | ||
450 | |||
451 | if (!tls1_change_cipher_state(s, | ||
452 | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { | ||
453 | ret = -1; | ||
454 | goto end; | ||
455 | } | ||
456 | |||
457 | dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); | ||
458 | break; | ||
459 | |||
460 | case SSL3_ST_CW_FINISHED_A: | ||
461 | case SSL3_ST_CW_FINISHED_B: | ||
462 | if (!s->internal->hit) | ||
463 | dtls1_start_timer(s); | ||
464 | ret = ssl3_send_finished(s, SSL3_ST_CW_FINISHED_A, | ||
465 | SSL3_ST_CW_FINISHED_B, TLS_MD_CLIENT_FINISH_CONST, | ||
466 | TLS_MD_CLIENT_FINISH_CONST_SIZE); | ||
467 | if (ret <= 0) | ||
468 | goto end; | ||
469 | S3I(s)->hs.state = SSL3_ST_CW_FLUSH; | ||
470 | |||
471 | /* clear flags */ | ||
472 | s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; | ||
473 | if (s->internal->hit) { | ||
474 | S3I(s)->hs.next_state = SSL_ST_OK; | ||
475 | if (s->s3->flags & | ||
476 | SSL3_FLAGS_DELAY_CLIENT_FINISHED) { | ||
477 | S3I(s)->hs.state = SSL_ST_OK; | ||
478 | s->s3->flags |= SSL3_FLAGS_POP_BUFFER; | ||
479 | S3I(s)->delay_buf_pop_ret = 0; | ||
480 | } | ||
481 | } else { | ||
482 | /* Allow NewSessionTicket if ticket expected */ | ||
483 | if (s->internal->tlsext_ticket_expected) | ||
484 | S3I(s)->hs.next_state = | ||
485 | SSL3_ST_CR_SESSION_TICKET_A; | ||
486 | else | ||
487 | S3I(s)->hs.next_state = | ||
488 | SSL3_ST_CR_FINISHED_A; | ||
489 | } | ||
490 | s->internal->init_num = 0; | ||
491 | break; | ||
492 | |||
493 | case SSL3_ST_CR_SESSION_TICKET_A: | ||
494 | case SSL3_ST_CR_SESSION_TICKET_B: | ||
495 | ret = ssl3_get_new_session_ticket(s); | ||
496 | if (ret <= 0) | ||
497 | goto end; | ||
498 | S3I(s)->hs.state = SSL3_ST_CR_FINISHED_A; | ||
499 | s->internal->init_num = 0; | ||
500 | break; | ||
501 | |||
502 | case SSL3_ST_CR_CERT_STATUS_A: | ||
503 | case SSL3_ST_CR_CERT_STATUS_B: | ||
504 | ret = ssl3_get_cert_status(s); | ||
505 | if (ret <= 0) | ||
506 | goto end; | ||
507 | S3I(s)->hs.state = SSL3_ST_CR_KEY_EXCH_A; | ||
508 | s->internal->init_num = 0; | ||
509 | break; | ||
510 | |||
511 | case SSL3_ST_CR_FINISHED_A: | ||
512 | case SSL3_ST_CR_FINISHED_B: | ||
513 | D1I(s)->change_cipher_spec_ok = 1; | ||
514 | ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, | ||
515 | SSL3_ST_CR_FINISHED_B); | ||
516 | if (ret <= 0) | ||
517 | goto end; | ||
518 | dtls1_stop_timer(s); | ||
519 | |||
520 | if (s->internal->hit) | ||
521 | S3I(s)->hs.state = SSL3_ST_CW_CHANGE_A; | ||
522 | else | ||
523 | S3I(s)->hs.state = SSL_ST_OK; | ||
524 | |||
525 | s->internal->init_num = 0; | ||
526 | break; | ||
527 | |||
528 | case SSL3_ST_CW_FLUSH: | ||
529 | s->internal->rwstate = SSL_WRITING; | ||
530 | if (BIO_flush(s->wbio) <= 0) { | ||
531 | /* If the write error was fatal, stop trying */ | ||
532 | if (!BIO_should_retry(s->wbio)) { | ||
533 | s->internal->rwstate = SSL_NOTHING; | ||
534 | S3I(s)->hs.state = S3I(s)->hs.next_state; | ||
535 | } | ||
536 | |||
537 | ret = -1; | ||
538 | goto end; | ||
539 | } | ||
540 | s->internal->rwstate = SSL_NOTHING; | ||
541 | S3I(s)->hs.state = S3I(s)->hs.next_state; | ||
542 | break; | ||
543 | |||
544 | case SSL_ST_OK: | ||
545 | /* clean a few things up */ | ||
546 | tls1_cleanup_key_block(s); | ||
547 | |||
548 | /* | ||
549 | * If we are not 'joining' the last two packets, | ||
550 | * remove the buffering now | ||
551 | */ | ||
552 | if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) | ||
553 | ssl_free_wbio_buffer(s); | ||
554 | /* else do it later in ssl3_write */ | ||
555 | |||
556 | s->internal->init_num = 0; | ||
557 | s->internal->renegotiate = 0; | ||
558 | s->internal->new_session = 0; | ||
559 | |||
560 | ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); | ||
561 | if (s->internal->hit) | ||
562 | s->ctx->internal->stats.sess_hit++; | ||
563 | |||
564 | ret = 1; | ||
565 | /* s->server=0; */ | ||
566 | s->internal->handshake_func = dtls1_connect; | ||
567 | s->ctx->internal->stats.sess_connect_good++; | ||
568 | |||
569 | if (cb != NULL) | ||
570 | cb(s, SSL_CB_HANDSHAKE_DONE, 1); | ||
571 | |||
572 | /* done with handshaking */ | ||
573 | D1I(s)->handshake_read_seq = 0; | ||
574 | D1I(s)->next_handshake_write_seq = 0; | ||
575 | goto end; | ||
576 | /* break; */ | ||
577 | |||
578 | default: | ||
579 | SSLerror(s, SSL_R_UNKNOWN_STATE); | ||
580 | ret = -1; | ||
581 | goto end; | ||
582 | /* break; */ | ||
583 | } | ||
584 | |||
585 | /* did we do anything */ | ||
586 | if (!S3I(s)->tmp.reuse_message && !skip) { | ||
587 | if (s->internal->debug) { | ||
588 | if ((ret = BIO_flush(s->wbio)) <= 0) | ||
589 | goto end; | ||
590 | } | ||
591 | |||
592 | if ((cb != NULL) && (S3I(s)->hs.state != state)) { | ||
593 | new_state = S3I(s)->hs.state; | ||
594 | S3I(s)->hs.state = state; | ||
595 | cb(s, SSL_CB_CONNECT_LOOP, 1); | ||
596 | S3I(s)->hs.state = new_state; | ||
597 | } | ||
598 | } | ||
599 | skip = 0; | ||
600 | } | ||
601 | |||
602 | end: | ||
603 | s->internal->in_handshake--; | ||
604 | if (cb != NULL) | ||
605 | cb(s, SSL_CB_CONNECT_EXIT, ret); | ||
606 | |||
607 | return (ret); | ||
608 | } | ||
609 | |||
610 | static int | ||
611 | dtls1_get_hello_verify(SSL *s) | 179 | dtls1_get_hello_verify(SSL *s) |
612 | { | 180 | { |
613 | long n; | 181 | long n; |