From 9f1dc8254effa6c430618020b08e04ab3ce8157c Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Tue, 7 Jun 2016 17:03:46 -0400 Subject: [PATCH] A bit of cleanup post state machine merging. Reorder states and functions by where they appear in the handshake. Remove unnecessary hooks on SSL_PROTOCOL_METHOD. Change-Id: I78dae9cf70792170abed6f38510ce870707e82ff Reviewed-on: https://boringssl-review.googlesource.com/8184 Reviewed-by: David Benjamin --- ssl/d1_meth.c | 2 - ssl/internal.h | 2 - ssl/s3_clnt.c | 472 +++++++++++++++++++------------------- ssl/s3_meth.c | 2 - ssl/s3_srvr.c | 606 ++++++++++++++++++++++++------------------------- ssl/ssl_lib.c | 8 +- 6 files changed, 540 insertions(+), 552 deletions(-) diff --git a/ssl/d1_meth.c b/ssl/d1_meth.c index 368238d2..32a4651a 100644 --- a/ssl/d1_meth.c +++ b/ssl/d1_meth.c @@ -63,8 +63,6 @@ static const SSL_PROTOCOL_METHOD DTLS_protocol_method = { 1 /* is_dtls */, dtls1_new, dtls1_free, - ssl3_accept, - ssl3_connect, dtls1_get_message, dtls1_read_app_data, dtls1_read_change_cipher_spec, diff --git a/ssl/internal.h b/ssl/internal.h index 31b09ff7..07e4c982 100644 --- a/ssl/internal.h +++ b/ssl/internal.h @@ -806,8 +806,6 @@ struct ssl_protocol_method_st { char is_dtls; int (*ssl_new)(SSL *ssl); void (*ssl_free)(SSL *ssl); - int (*ssl_accept)(SSL *ssl); - int (*ssl_connect)(SSL *ssl); long (*ssl_get_message)(SSL *ssl, int msg_type, enum ssl_hash_message_t hash_message, int *ok); int (*ssl_read_app_data)(SSL *ssl, uint8_t *buf, int len, int peek); diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 831d5575..0360b5e5 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -173,20 +173,18 @@ static int ssl3_send_client_hello(SSL *ssl); static int dtls1_get_hello_verify(SSL *ssl); static int ssl3_get_server_hello(SSL *ssl); -static int ssl3_get_certificate_request(SSL *ssl); -static int ssl3_get_new_session_ticket(SSL *ssl); +static int ssl3_get_server_certificate(SSL *ssl); static int ssl3_get_cert_status(SSL *ssl); +static int ssl3_verify_server_cert(SSL *ssl); +static int ssl3_get_server_key_exchange(SSL *ssl); +static int ssl3_get_certificate_request(SSL *ssl); static int ssl3_get_server_done(SSL *ssl); -static int ssl3_send_cert_verify(SSL *ssl); static int ssl3_send_client_certificate(SSL *ssl); -static int ssl_do_client_cert_cb(SSL *ssl, X509 **out_x509, - EVP_PKEY **out_pkey); static int ssl3_send_client_key_exchange(SSL *ssl); -static int ssl3_get_server_key_exchange(SSL *ssl); -static int ssl3_get_server_certificate(SSL *ssl); +static int ssl3_send_cert_verify(SSL *ssl); static int ssl3_send_next_proto(SSL *ssl); static int ssl3_send_channel_id(SSL *ssl); -static int ssl3_verify_server_cert(SSL *ssl); +static int ssl3_get_new_session_ticket(SSL *ssl); int ssl3_connect(SSL *ssl) { BUF_MEM *buf = NULL; @@ -287,6 +285,14 @@ int ssl3_connect(SSL *ssl) { } break; + case SSL3_ST_CR_CERT_STATUS_A: + ret = ssl3_get_cert_status(ssl); + if (ret <= 0) { + goto end; + } + ssl->state = SSL3_ST_VERIFY_SERVER_CERT; + break; + case SSL3_ST_VERIFY_SERVER_CERT: ret = ssl3_verify_server_cert(ssl); if (ret <= 0) { @@ -448,6 +454,19 @@ int ssl3_connect(SSL *ssl) { } break; + case SSL3_ST_FALSE_START: + /* Allow NewSessionTicket if ticket expected */ + if (ssl->tlsext_ticket_expected) { + ssl->state = SSL3_ST_CR_SESSION_TICKET_A; + } else { + ssl->state = SSL3_ST_CR_CHANGE; + } + ssl->s3->tmp.in_false_start = 1; + + ssl_free_wbio_buffer(ssl); + ret = 1; + goto end; + case SSL3_ST_CR_SESSION_TICKET_A: ret = ssl3_get_new_session_ticket(ssl); if (ret <= 0) { @@ -456,14 +475,6 @@ int ssl3_connect(SSL *ssl) { ssl->state = SSL3_ST_CR_CHANGE; break; - case SSL3_ST_CR_CERT_STATUS_A: - ret = ssl3_get_cert_status(ssl); - if (ret <= 0) { - goto end; - } - ssl->state = SSL3_ST_VERIFY_SERVER_CERT; - break; - case SSL3_ST_CR_CHANGE: ret = ssl->method->ssl_read_change_cipher_spec(ssl); if (ret <= 0) { @@ -503,19 +514,6 @@ int ssl3_connect(SSL *ssl) { } break; - case SSL3_ST_FALSE_START: - /* Allow NewSessionTicket if ticket expected */ - if (ssl->tlsext_ticket_expected) { - ssl->state = SSL3_ST_CR_SESSION_TICKET_A; - } else { - ssl->state = SSL3_ST_CR_CHANGE; - } - ssl->s3->tmp.in_false_start = 1; - - ssl_free_wbio_buffer(ssl); - ret = 1; - goto end; - case SSL_ST_OK: /* clean a few things up */ ssl3_cleanup_key_block(ssl); @@ -1083,6 +1081,63 @@ err: return ret; } +static int ssl3_get_cert_status(SSL *ssl) { + int ok, al; + long n; + CBS certificate_status, ocsp_response; + uint8_t status_type; + + n = ssl->method->ssl_get_message(ssl, -1, ssl_hash_message, &ok); + + if (!ok) { + return n; + } + + if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE_STATUS) { + /* A server may send status_request in ServerHello and then change + * its mind about sending CertificateStatus. */ + ssl->s3->tmp.reuse_message = 1; + return 1; + } + + CBS_init(&certificate_status, ssl->init_msg, n); + if (!CBS_get_u8(&certificate_status, &status_type) || + status_type != TLSEXT_STATUSTYPE_ocsp || + !CBS_get_u24_length_prefixed(&certificate_status, &ocsp_response) || + CBS_len(&ocsp_response) == 0 || + CBS_len(&certificate_status) != 0) { + al = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + goto f_err; + } + + if (!CBS_stow(&ocsp_response, &ssl->session->ocsp_response, + &ssl->session->ocsp_response_length)) { + al = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto f_err; + } + return 1; + +f_err: + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); + return -1; +} + +static int ssl3_verify_server_cert(SSL *ssl) { + int ret = ssl_verify_cert_chain(ssl, ssl->session->cert_chain); + if (ssl->verify_mode != SSL_VERIFY_NONE && ret <= 0) { + int al = ssl_verify_alarm_type(ssl->verify_result); + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED); + } else { + ret = 1; + ERR_clear_error(); /* but we keep ssl->verify_result */ + } + + return ret; +} + static int ssl3_get_server_key_exchange(SSL *ssl) { EVP_MD_CTX md_ctx; int al, ok; @@ -1460,141 +1515,120 @@ err: return ret; } -static int ssl3_get_new_session_ticket(SSL *ssl) { - int ok, al; - long n = ssl->method->ssl_get_message(ssl, SSL3_MT_NEW_SESSION_TICKET, - ssl_hash_message, &ok); +static int ssl3_get_server_done(SSL *ssl) { + int ok; + long n; + + n = ssl->method->ssl_get_message(ssl, SSL3_MT_SERVER_DONE, ssl_hash_message, + &ok); if (!ok) { return n; } - CBS new_session_ticket, ticket; - uint32_t ticket_lifetime_hint; - CBS_init(&new_session_ticket, ssl->init_msg, n); - if (!CBS_get_u32(&new_session_ticket, &ticket_lifetime_hint) || - !CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) || - CBS_len(&new_session_ticket) != 0) { - al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); - goto f_err; - } - - if (CBS_len(&ticket) == 0) { - /* RFC 5077 allows a server to change its mind and send no ticket after - * negotiating the extension. The value of |tlsext_ticket_expected| is - * checked in |ssl_update_cache| so is cleared here to avoid an unnecessary - * update. */ - ssl->tlsext_ticket_expected = 0; - return 1; + if (n > 0) { + /* should contain no data */ + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH); + return -1; } - if (ssl->hit) { - /* The server is sending a new ticket for an existing session. Sessions are - * immutable once established, so duplicate all but the ticket of the - * existing session. */ - uint8_t *bytes; - size_t bytes_len; - if (!SSL_SESSION_to_bytes_for_ticket(ssl->session, &bytes, &bytes_len)) { - goto err; - } - SSL_SESSION *new_session = SSL_SESSION_from_bytes(bytes, bytes_len); - OPENSSL_free(bytes); - if (new_session == NULL) { - /* This should never happen. */ - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - goto err; - } + return 1; +} - SSL_SESSION_free(ssl->session); - ssl->session = new_session; - } +/* ssl3_has_client_certificate returns true if a client certificate is + * configured. */ +static int ssl3_has_client_certificate(SSL *ssl) { + return ssl->cert && ssl->cert->x509 && ssl_has_private_key(ssl); +} - if (!CBS_stow(&ticket, &ssl->session->tlsext_tick, - &ssl->session->tlsext_ticklen)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; +static int ssl_do_client_cert_cb(SSL *ssl, X509 **out_x509, + EVP_PKEY **out_pkey) { + if (ssl->ctx->client_cert_cb == NULL) { + return 0; } - ssl->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint; - /* Generate a session ID for this session based on the session ticket. We use - * the session ID mechanism for detecting ticket resumption. This also fits in - * with assumptions elsewhere in OpenSSL.*/ - if (!EVP_Digest(CBS_data(&ticket), CBS_len(&ticket), ssl->session->session_id, - &ssl->session->session_id_length, EVP_sha256(), NULL)) { - goto err; + int ret = ssl->ctx->client_cert_cb(ssl, out_x509, out_pkey); + if (ret <= 0) { + return ret; } + assert(*out_x509 != NULL); + assert(*out_pkey != NULL); return 1; - -f_err: - ssl3_send_alert(ssl, SSL3_AL_FATAL, al); -err: - return -1; } -static int ssl3_get_cert_status(SSL *ssl) { - int ok, al; - long n; - CBS certificate_status, ocsp_response; - uint8_t status_type; - - n = ssl->method->ssl_get_message(ssl, -1, ssl_hash_message, &ok); +static int ssl3_send_client_certificate(SSL *ssl) { + if (ssl->state == SSL3_ST_CW_CERT_A) { + /* Call cert_cb to update the certificate. */ + if (ssl->cert->cert_cb) { + int ret = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg); + if (ret < 0) { + ssl->rwstate = SSL_X509_LOOKUP; + return -1; + } + if (ret == 0) { + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return -1; + } + } - if (!ok) { - return n; + if (ssl3_has_client_certificate(ssl)) { + ssl->state = SSL3_ST_CW_CERT_C; + } else { + ssl->state = SSL3_ST_CW_CERT_B; + } } - if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE_STATUS) { - /* A server may send status_request in ServerHello and then change - * its mind about sending CertificateStatus. */ - ssl->s3->tmp.reuse_message = 1; - return 1; - } + if (ssl->state == SSL3_ST_CW_CERT_B) { + /* Call client_cert_cb to update the certificate. */ + X509 *x509 = NULL; + EVP_PKEY *pkey = NULL; + int ret = ssl_do_client_cert_cb(ssl, &x509, &pkey); + if (ret < 0) { + ssl->rwstate = SSL_X509_LOOKUP; + return -1; + } - CBS_init(&certificate_status, ssl->init_msg, n); - if (!CBS_get_u8(&certificate_status, &status_type) || - status_type != TLSEXT_STATUSTYPE_ocsp || - !CBS_get_u24_length_prefixed(&certificate_status, &ocsp_response) || - CBS_len(&ocsp_response) == 0 || - CBS_len(&certificate_status) != 0) { - al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); - goto f_err; - } + int setup_error = ret == 1 && (!SSL_use_certificate(ssl, x509) || + !SSL_use_PrivateKey(ssl, pkey)); + X509_free(x509); + EVP_PKEY_free(pkey); + if (setup_error) { + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return -1; + } - if (!CBS_stow(&ocsp_response, &ssl->session->ocsp_response, - &ssl->session->ocsp_response_length)) { - al = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto f_err; + ssl->state = SSL3_ST_CW_CERT_C; } - return 1; -f_err: - ssl3_send_alert(ssl, SSL3_AL_FATAL, al); - return -1; -} - -static int ssl3_get_server_done(SSL *ssl) { - int ok; - long n; - - n = ssl->method->ssl_get_message(ssl, SSL3_MT_SERVER_DONE, ssl_hash_message, - &ok); + if (ssl->state == SSL3_ST_CW_CERT_C) { + if (!ssl3_has_client_certificate(ssl)) { + /* Without a client certificate, the handshake buffer may be released. */ + ssl3_free_handshake_buffer(ssl); - if (!ok) { - return n; - } + if (ssl->version == SSL3_VERSION) { + /* In SSL 3.0, send no certificate by skipping both messages. */ + ssl->s3->tmp.cert_req = 0; + ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE); + return 1; + } - if (n > 0) { - /* should contain no data */ - ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH); - return -1; + /* In TLS, send an empty Certificate message. */ + ssl->s3->tmp.cert_req = 2; + uint8_t *p = ssl_handshake_start(ssl); + l2n3(0, p); + if (!ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE, 3)) { + return -1; + } + } else if (!ssl3_output_cert_chain(ssl)) { + return -1; + } + ssl->state = SSL3_ST_CW_CERT_D; } - return 1; + assert(ssl->state == SSL3_ST_CW_CERT_D); + return ssl_do_write(ssl); } OPENSSL_COMPILE_ASSERT(sizeof(size_t) >= sizeof(unsigned), @@ -1887,85 +1921,6 @@ err: return -1; } -/* ssl3_has_client_certificate returns true if a client certificate is - * configured. */ -static int ssl3_has_client_certificate(SSL *ssl) { - return ssl->cert && ssl->cert->x509 && ssl_has_private_key(ssl); -} - -static int ssl3_send_client_certificate(SSL *ssl) { - if (ssl->state == SSL3_ST_CW_CERT_A) { - /* Call cert_cb to update the certificate. */ - if (ssl->cert->cert_cb) { - int ret = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg); - if (ret < 0) { - ssl->rwstate = SSL_X509_LOOKUP; - return -1; - } - if (ret == 0) { - ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - return -1; - } - } - - if (ssl3_has_client_certificate(ssl)) { - ssl->state = SSL3_ST_CW_CERT_C; - } else { - ssl->state = SSL3_ST_CW_CERT_B; - } - } - - if (ssl->state == SSL3_ST_CW_CERT_B) { - /* Call client_cert_cb to update the certificate. */ - X509 *x509 = NULL; - EVP_PKEY *pkey = NULL; - int ret = ssl_do_client_cert_cb(ssl, &x509, &pkey); - if (ret < 0) { - ssl->rwstate = SSL_X509_LOOKUP; - return -1; - } - - int setup_error = ret == 1 && (!SSL_use_certificate(ssl, x509) || - !SSL_use_PrivateKey(ssl, pkey)); - X509_free(x509); - EVP_PKEY_free(pkey); - if (setup_error) { - ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - return -1; - } - - ssl->state = SSL3_ST_CW_CERT_C; - } - - if (ssl->state == SSL3_ST_CW_CERT_C) { - if (!ssl3_has_client_certificate(ssl)) { - /* Without a client certificate, the handshake buffer may be released. */ - ssl3_free_handshake_buffer(ssl); - - if (ssl->version == SSL3_VERSION) { - /* In SSL 3.0, send no certificate by skipping both messages. */ - ssl->s3->tmp.cert_req = 0; - ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE); - return 1; - } - - /* In TLS, send an empty Certificate message. */ - ssl->s3->tmp.cert_req = 2; - uint8_t *p = ssl_handshake_start(ssl); - l2n3(0, p); - if (!ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE, 3)) { - return -1; - } - } else if (!ssl3_output_cert_chain(ssl)) { - return -1; - } - ssl->state = SSL3_ST_CW_CERT_D; - } - - assert(ssl->state == SSL3_ST_CW_CERT_D); - return ssl_do_write(ssl); -} - static int ssl3_send_next_proto(SSL *ssl) { if (ssl->state == SSL3_ST_CW_NEXT_PROTO_B) { return ssl_do_write(ssl); @@ -2078,32 +2033,75 @@ err: return ret; } -static int ssl_do_client_cert_cb(SSL *ssl, X509 **out_x509, - EVP_PKEY **out_pkey) { - if (ssl->ctx->client_cert_cb == NULL) { - return 0; +static int ssl3_get_new_session_ticket(SSL *ssl) { + int ok, al; + long n = ssl->method->ssl_get_message(ssl, SSL3_MT_NEW_SESSION_TICKET, + ssl_hash_message, &ok); + + if (!ok) { + return n; } - int ret = ssl->ctx->client_cert_cb(ssl, out_x509, out_pkey); - if (ret <= 0) { - return ret; + CBS new_session_ticket, ticket; + uint32_t ticket_lifetime_hint; + CBS_init(&new_session_ticket, ssl->init_msg, n); + if (!CBS_get_u32(&new_session_ticket, &ticket_lifetime_hint) || + !CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) || + CBS_len(&new_session_ticket) != 0) { + al = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + goto f_err; } - assert(*out_x509 != NULL); - assert(*out_pkey != NULL); - return 1; -} + if (CBS_len(&ticket) == 0) { + /* RFC 5077 allows a server to change its mind and send no ticket after + * negotiating the extension. The value of |tlsext_ticket_expected| is + * checked in |ssl_update_cache| so is cleared here to avoid an unnecessary + * update. */ + ssl->tlsext_ticket_expected = 0; + return 1; + } -static int ssl3_verify_server_cert(SSL *ssl) { - int ret = ssl_verify_cert_chain(ssl, ssl->session->cert_chain); - if (ssl->verify_mode != SSL_VERIFY_NONE && ret <= 0) { - int al = ssl_verify_alarm_type(ssl->verify_result); - ssl3_send_alert(ssl, SSL3_AL_FATAL, al); - OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED); - } else { - ret = 1; - ERR_clear_error(); /* but we keep ssl->verify_result */ + if (ssl->hit) { + /* The server is sending a new ticket for an existing session. Sessions are + * immutable once established, so duplicate all but the ticket of the + * existing session. */ + uint8_t *bytes; + size_t bytes_len; + if (!SSL_SESSION_to_bytes_for_ticket(ssl->session, &bytes, &bytes_len)) { + goto err; + } + SSL_SESSION *new_session = SSL_SESSION_from_bytes(bytes, bytes_len); + OPENSSL_free(bytes); + if (new_session == NULL) { + /* This should never happen. */ + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + goto err; + } + + SSL_SESSION_free(ssl->session); + ssl->session = new_session; } - return ret; + if (!CBS_stow(&ticket, &ssl->session->tlsext_tick, + &ssl->session->tlsext_ticklen)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + ssl->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint; + + /* Generate a session ID for this session based on the session ticket. We use + * the session ID mechanism for detecting ticket resumption. This also fits in + * with assumptions elsewhere in OpenSSL.*/ + if (!EVP_Digest(CBS_data(&ticket), CBS_len(&ticket), ssl->session->session_id, + &ssl->session->session_id_length, EVP_sha256(), NULL)) { + goto err; + } + + return 1; + +f_err: + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); +err: + return -1; } diff --git a/ssl/s3_meth.c b/ssl/s3_meth.c index 2241b239..8370f23f 100644 --- a/ssl/s3_meth.c +++ b/ssl/s3_meth.c @@ -63,8 +63,6 @@ static const SSL_PROTOCOL_METHOD TLS_protocol_method = { 0 /* is_dtls */, ssl3_new, ssl3_free, - ssl3_accept, - ssl3_connect, ssl3_get_message, ssl3_read_app_data, ssl3_read_change_cipher_spec, diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 481b3b65..0158c793 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -177,17 +177,17 @@ static int ssl3_get_initial_bytes(SSL *ssl); static int ssl3_get_v2_client_hello(SSL *ssl); static int ssl3_get_client_hello(SSL *ssl); static int ssl3_send_server_hello(SSL *ssl); +static int ssl3_send_server_certificate(SSL *ssl); static int ssl3_send_certificate_status(SSL *ssl); -static int ssl3_send_server_done(SSL *ssl); static int ssl3_send_server_key_exchange(SSL *ssl); static int ssl3_send_certificate_request(SSL *ssl); +static int ssl3_send_server_done(SSL *ssl); +static int ssl3_get_client_certificate(SSL *ssl); static int ssl3_get_client_key_exchange(SSL *ssl); static int ssl3_get_cert_verify(SSL *ssl); -static int ssl3_get_client_certificate(SSL *ssl); -static int ssl3_send_server_certificate(SSL *ssl); -static int ssl3_send_new_session_ticket(SSL *ssl); static int ssl3_get_next_proto(SSL *ssl); static int ssl3_get_channel_id(SSL *ssl); +static int ssl3_send_new_session_ticket(SSL *ssl); int ssl3_accept(SSL *ssl) { BUF_MEM *buf = NULL; @@ -352,19 +352,6 @@ int ssl3_accept(SSL *ssl) { ssl->state = SSL3_ST_SW_FLUSH; break; - case SSL3_ST_SW_FLUSH: - if (BIO_flush(ssl->wbio) <= 0) { - ssl->rwstate = SSL_WRITING; - ret = -1; - goto end; - } - - ssl->state = ssl->s3->tmp.next_state; - if (ssl->state != SSL_ST_OK) { - ssl->method->expect_flight(ssl); - } - break; - case SSL3_ST_SR_CERT_A: if (ssl->s3->tmp.cert_request) { ret = ssl3_get_client_certificate(ssl); @@ -498,6 +485,19 @@ int ssl3_accept(SSL *ssl) { } break; + case SSL3_ST_SW_FLUSH: + if (BIO_flush(ssl->wbio) <= 0) { + ssl->rwstate = SSL_WRITING; + ret = -1; + goto end; + } + + ssl->state = ssl->s3->tmp.next_state; + if (ssl->state != SSL_ST_OK) { + ssl->method->expect_flight(ssl); + } + break; + case SSL_ST_OK: /* clean a few things up */ ssl3_cleanup_key_block(ssl); @@ -1121,6 +1121,18 @@ static int ssl3_send_server_hello(SSL *ssl) { return ssl_do_write(ssl); } +static int ssl3_send_server_certificate(SSL *ssl) { + if (ssl->state == SSL3_ST_SW_CERT_A) { + if (!ssl3_output_cert_chain(ssl)) { + return 0; + } + ssl->state = SSL3_ST_SW_CERT_B; + } + + /* SSL3_ST_SW_CERT_B */ + return ssl_do_write(ssl); +} + static int ssl3_send_certificate_status(SSL *ssl) { if (ssl->state == SSL3_ST_SW_CERT_STATUS_A) { CBB out, ocsp_response; @@ -1147,18 +1159,6 @@ static int ssl3_send_certificate_status(SSL *ssl) { return ssl_do_write(ssl); } -static int ssl3_send_server_done(SSL *ssl) { - if (ssl->state == SSL3_ST_SW_SRVR_DONE_A) { - if (!ssl_set_handshake_header(ssl, SSL3_MT_SERVER_DONE, 0)) { - return -1; - } - ssl->state = SSL3_ST_SW_SRVR_DONE_B; - } - - /* SSL3_ST_SW_SRVR_DONE_B */ - return ssl_do_write(ssl); -} - static int ssl3_send_server_key_exchange(SSL *ssl) { if (ssl->state == SSL3_ST_SW_KEY_EXCH_C) { return ssl_do_write(ssl); @@ -1415,6 +1415,157 @@ err: return -1; } +static int ssl3_send_server_done(SSL *ssl) { + if (ssl->state == SSL3_ST_SW_SRVR_DONE_A) { + if (!ssl_set_handshake_header(ssl, SSL3_MT_SERVER_DONE, 0)) { + return -1; + } + ssl->state = SSL3_ST_SW_SRVR_DONE_B; + } + + /* SSL3_ST_SW_SRVR_DONE_B */ + return ssl_do_write(ssl); +} + +static int ssl3_get_client_certificate(SSL *ssl) { + int ok, al, ret = -1; + X509 *x = NULL; + unsigned long n; + STACK_OF(X509) *sk = NULL; + SHA256_CTX sha256; + CBS certificate_msg, certificate_list; + int is_first_certificate = 1; + + assert(ssl->s3->tmp.cert_request); + n = ssl->method->ssl_get_message(ssl, -1, ssl_hash_message, &ok); + + if (!ok) { + return n; + } + + if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { + if (ssl->version == SSL3_VERSION && + ssl->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) { + /* In SSL 3.0, the Certificate message is omitted to signal no certificate. */ + if ((ssl->verify_mode & SSL_VERIFY_PEER) && + (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } + + ssl->s3->tmp.reuse_message = 1; + return 1; + } + + al = SSL_AD_UNEXPECTED_MESSAGE; + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + + CBS_init(&certificate_msg, ssl->init_msg, n); + + sk = sk_X509_new_null(); + if (sk == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!CBS_get_u24_length_prefixed(&certificate_msg, &certificate_list) || + CBS_len(&certificate_msg) != 0) { + al = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + goto f_err; + } + + while (CBS_len(&certificate_list) > 0) { + CBS certificate; + const uint8_t *data; + + if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate)) { + al = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + goto f_err; + } + + if (is_first_certificate && ssl->ctx->retain_only_sha256_of_client_certs) { + /* If this is the first certificate, and we don't want to keep peer + * certificates in memory, then we hash it right away. */ + SHA256_Init(&sha256); + SHA256_Update(&sha256, CBS_data(&certificate), CBS_len(&certificate)); + SHA256_Final(ssl->session->peer_sha256, &sha256); + ssl->session->peer_sha256_valid = 1; + } + is_first_certificate = 0; + + /* A u24 length cannot overflow a long. */ + data = CBS_data(&certificate); + x = d2i_X509(NULL, &data, (long)CBS_len(&certificate)); + if (x == NULL) { + al = SSL_AD_BAD_CERTIFICATE; + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + goto f_err; + } + if (data != CBS_data(&certificate) + CBS_len(&certificate)) { + al = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + if (!sk_X509_push(sk, x)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + x = NULL; + } + + if (sk_X509_num(sk) <= 0) { + /* No client certificate so the handshake buffer may be discarded. */ + ssl3_free_handshake_buffer(ssl); + + /* TLS does not mind 0 certs returned */ + if (ssl->version == SSL3_VERSION) { + al = SSL_AD_HANDSHAKE_FAILURE; + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED); + goto f_err; + } else if ((ssl->verify_mode & SSL_VERIFY_PEER) && + (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + /* Fail for TLS only if we required a certificate */ + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } + } else { + if (ssl_verify_cert_chain(ssl, sk) <= 0) { + al = ssl_verify_alarm_type(ssl->verify_result); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED); + goto f_err; + } + } + + X509_free(ssl->session->peer); + ssl->session->peer = sk_X509_shift(sk); + ssl->session->verify_result = ssl->verify_result; + + sk_X509_pop_free(ssl->session->cert_chain, X509_free); + ssl->session->cert_chain = sk; + /* Inconsistency alert: cert_chain does *not* include the peer's own + * certificate, while we do include it in s3_clnt.c */ + + sk = NULL; + + ret = 1; + + if (0) { + f_err: + ssl3_send_alert(ssl, SSL3_AL_FATAL, al); + } + +err: + X509_free(x); + sk_X509_pop_free(sk, X509_free); + return ret; +} + static int ssl3_get_client_key_exchange(SSL *ssl) { int al; CBS client_key_exchange; @@ -1790,155 +1941,155 @@ err: return ret; } -static int ssl3_get_client_certificate(SSL *ssl) { - int ok, al, ret = -1; - X509 *x = NULL; - unsigned long n; - STACK_OF(X509) *sk = NULL; - SHA256_CTX sha256; - CBS certificate_msg, certificate_list; - int is_first_certificate = 1; - - assert(ssl->s3->tmp.cert_request); - n = ssl->method->ssl_get_message(ssl, -1, ssl_hash_message, &ok); +/* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It + * sets the next_proto member in s if found */ +static int ssl3_get_next_proto(SSL *ssl) { + int ok; + long n; + CBS next_protocol, selected_protocol, padding; - if (!ok) { - return n; + /* Clients cannot send a NextProtocol message if we didn't see the extension + * in their ClientHello */ + if (!ssl->s3->next_proto_neg_seen) { + OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); + return -1; } - if (ssl->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { - if (ssl->version == SSL3_VERSION && - ssl->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) { - /* In SSL 3.0, the Certificate message is omitted to signal no certificate. */ - if ((ssl->verify_mode & SSL_VERIFY_PEER) && - (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { - OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - al = SSL_AD_HANDSHAKE_FAILURE; - goto f_err; - } - - ssl->s3->tmp.reuse_message = 1; - return 1; - } + n = ssl->method->ssl_get_message(ssl, SSL3_MT_NEXT_PROTO, ssl_hash_message, + &ok); - al = SSL_AD_UNEXPECTED_MESSAGE; - OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; + if (!ok) { + return n; } - CBS_init(&certificate_msg, ssl->init_msg, n); + CBS_init(&next_protocol, ssl->init_msg, n); - sk = sk_X509_new_null(); - if (sk == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!CBS_get_u24_length_prefixed(&certificate_msg, &certificate_list) || - CBS_len(&certificate_msg) != 0) { - al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); - goto f_err; + /* The payload looks like: + * uint8 proto_len; + * uint8 proto[proto_len]; + * uint8 padding_len; + * uint8 padding[padding_len]; */ + if (!CBS_get_u8_length_prefixed(&next_protocol, &selected_protocol) || + !CBS_get_u8_length_prefixed(&next_protocol, &padding) || + CBS_len(&next_protocol) != 0 || + !CBS_stow(&selected_protocol, &ssl->s3->next_proto_negotiated, + &ssl->s3->next_proto_negotiated_len)) { + return 0; } - while (CBS_len(&certificate_list) > 0) { - CBS certificate; - const uint8_t *data; + return 1; +} - if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate)) { - al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); - goto f_err; - } +/* ssl3_get_channel_id reads and verifies a ClientID handshake message. */ +static int ssl3_get_channel_id(SSL *ssl) { + int ret = -1, ok; + long n; + uint8_t channel_id_hash[EVP_MAX_MD_SIZE]; + size_t channel_id_hash_len; + const uint8_t *p; + uint16_t extension_type; + EC_GROUP *p256 = NULL; + EC_KEY *key = NULL; + EC_POINT *point = NULL; + ECDSA_SIG sig; + BIGNUM x, y; + CBS encrypted_extensions, extension; - if (is_first_certificate && ssl->ctx->retain_only_sha256_of_client_certs) { - /* If this is the first certificate, and we don't want to keep peer - * certificates in memory, then we hash it right away. */ - SHA256_Init(&sha256); - SHA256_Update(&sha256, CBS_data(&certificate), CBS_len(&certificate)); - SHA256_Final(ssl->session->peer_sha256, &sha256); - ssl->session->peer_sha256_valid = 1; - } - is_first_certificate = 0; + n = ssl->method->ssl_get_message(ssl, SSL3_MT_CHANNEL_ID_ENCRYPTED_EXTENSIONS, + ssl_dont_hash_message, &ok); - /* A u24 length cannot overflow a long. */ - data = CBS_data(&certificate); - x = d2i_X509(NULL, &data, (long)CBS_len(&certificate)); - if (x == NULL) { - al = SSL_AD_BAD_CERTIFICATE; - OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); - goto f_err; - } - if (data != CBS_data(&certificate) + CBS_len(&certificate)) { - al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - if (!sk_X509_push(sk, x)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - goto err; - } - x = NULL; + if (!ok) { + return n; } - if (sk_X509_num(sk) <= 0) { - /* No client certificate so the handshake buffer may be discarded. */ - ssl3_free_handshake_buffer(ssl); + /* Before incorporating the EncryptedExtensions message to the handshake + * hash, compute the hash that should have been signed. */ + if (!tls1_channel_id_hash(ssl, channel_id_hash, &channel_id_hash_len)) { + return -1; + } + assert(channel_id_hash_len == SHA256_DIGEST_LENGTH); - /* TLS does not mind 0 certs returned */ - if (ssl->version == SSL3_VERSION) { - al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED); - goto f_err; - } else if ((ssl->verify_mode & SSL_VERIFY_PEER) && - (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { - /* Fail for TLS only if we required a certificate */ - OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - al = SSL_AD_HANDSHAKE_FAILURE; - goto f_err; - } - } else { - if (ssl_verify_cert_chain(ssl, sk) <= 0) { - al = ssl_verify_alarm_type(ssl->verify_result); - OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED); - goto f_err; - } + if (!ssl3_hash_current_message(ssl)) { + return -1; } - X509_free(ssl->session->peer); - ssl->session->peer = sk_X509_shift(sk); - ssl->session->verify_result = ssl->verify_result; + CBS_init(&encrypted_extensions, ssl->init_msg, n); - sk_X509_pop_free(ssl->session->cert_chain, X509_free); - ssl->session->cert_chain = sk; - /* Inconsistency alert: cert_chain does *not* include the peer's own - * certificate, while we do include it in s3_clnt.c */ + /* EncryptedExtensions could include multiple extensions, but the only + * extension that could be negotiated is ChannelID, so there can only be one + * entry. + * + * The payload looks like: + * uint16 extension_type + * uint16 extension_len; + * uint8 x[32]; + * uint8 y[32]; + * uint8 r[32]; + * uint8 s[32]; */ - sk = NULL; + if (!CBS_get_u16(&encrypted_extensions, &extension_type) || + !CBS_get_u16_length_prefixed(&encrypted_extensions, &extension) || + CBS_len(&encrypted_extensions) != 0 || + extension_type != TLSEXT_TYPE_channel_id || + CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_MESSAGE); + return -1; + } - ret = 1; + p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); + if (!p256) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT); + return -1; + } - if (0) { - f_err: - ssl3_send_alert(ssl, SSL3_AL_FATAL, al); + BN_init(&x); + BN_init(&y); + sig.r = BN_new(); + sig.s = BN_new(); + if (sig.r == NULL || sig.s == NULL) { + goto err; } -err: - X509_free(x); - sk_X509_pop_free(sk, X509_free); - return ret; -} + p = CBS_data(&extension); + if (BN_bin2bn(p + 0, 32, &x) == NULL || + BN_bin2bn(p + 32, 32, &y) == NULL || + BN_bin2bn(p + 64, 32, sig.r) == NULL || + BN_bin2bn(p + 96, 32, sig.s) == NULL) { + goto err; + } -static int ssl3_send_server_certificate(SSL *ssl) { - if (ssl->state == SSL3_ST_SW_CERT_A) { - if (!ssl3_output_cert_chain(ssl)) { - return 0; - } - ssl->state = SSL3_ST_SW_CERT_B; + point = EC_POINT_new(p256); + if (!point || + !EC_POINT_set_affine_coordinates_GFp(p256, point, &x, &y, NULL)) { + goto err; } - /* SSL3_ST_SW_CERT_B */ - return ssl_do_write(ssl); + key = EC_KEY_new(); + if (!key || !EC_KEY_set_group(key, p256) || + !EC_KEY_set_public_key(key, point)) { + goto err; + } + + /* We stored the handshake hash in |tlsext_channel_id| the first time that we + * were called. */ + if (!ECDSA_do_verify(channel_id_hash, channel_id_hash_len, &sig, key)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID); + ssl->s3->tlsext_channel_id_valid = 0; + goto err; + } + + memcpy(ssl->s3->tlsext_channel_id, p, 64); + ret = 1; + +err: + BN_free(&x); + BN_free(&y); + BN_free(sig.r); + BN_free(sig.s); + EC_KEY_free(key); + EC_POINT_free(point); + EC_GROUP_free(p256); + return ret; } /* send a new session ticket (not necessarily for a new session) */ @@ -2072,154 +2223,3 @@ err: HMAC_CTX_cleanup(&hctx); return ret; } - -/* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It - * sets the next_proto member in s if found */ -static int ssl3_get_next_proto(SSL *ssl) { - int ok; - long n; - CBS next_protocol, selected_protocol, padding; - - /* Clients cannot send a NextProtocol message if we didn't see the extension - * in their ClientHello */ - if (!ssl->s3->next_proto_neg_seen) { - OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); - return -1; - } - - n = ssl->method->ssl_get_message(ssl, SSL3_MT_NEXT_PROTO, ssl_hash_message, - &ok); - - if (!ok) { - return n; - } - - CBS_init(&next_protocol, ssl->init_msg, n); - - /* The payload looks like: - * uint8 proto_len; - * uint8 proto[proto_len]; - * uint8 padding_len; - * uint8 padding[padding_len]; */ - if (!CBS_get_u8_length_prefixed(&next_protocol, &selected_protocol) || - !CBS_get_u8_length_prefixed(&next_protocol, &padding) || - CBS_len(&next_protocol) != 0 || - !CBS_stow(&selected_protocol, &ssl->s3->next_proto_negotiated, - &ssl->s3->next_proto_negotiated_len)) { - return 0; - } - - return 1; -} - -/* ssl3_get_channel_id reads and verifies a ClientID handshake message. */ -static int ssl3_get_channel_id(SSL *ssl) { - int ret = -1, ok; - long n; - uint8_t channel_id_hash[EVP_MAX_MD_SIZE]; - size_t channel_id_hash_len; - const uint8_t *p; - uint16_t extension_type; - EC_GROUP *p256 = NULL; - EC_KEY *key = NULL; - EC_POINT *point = NULL; - ECDSA_SIG sig; - BIGNUM x, y; - CBS encrypted_extensions, extension; - - n = ssl->method->ssl_get_message(ssl, SSL3_MT_CHANNEL_ID_ENCRYPTED_EXTENSIONS, - ssl_dont_hash_message, &ok); - - if (!ok) { - return n; - } - - /* Before incorporating the EncryptedExtensions message to the handshake - * hash, compute the hash that should have been signed. */ - if (!tls1_channel_id_hash(ssl, channel_id_hash, &channel_id_hash_len)) { - return -1; - } - assert(channel_id_hash_len == SHA256_DIGEST_LENGTH); - - if (!ssl3_hash_current_message(ssl)) { - return -1; - } - - CBS_init(&encrypted_extensions, ssl->init_msg, n); - - /* EncryptedExtensions could include multiple extensions, but the only - * extension that could be negotiated is ChannelID, so there can only be one - * entry. - * - * The payload looks like: - * uint16 extension_type - * uint16 extension_len; - * uint8 x[32]; - * uint8 y[32]; - * uint8 r[32]; - * uint8 s[32]; */ - - if (!CBS_get_u16(&encrypted_extensions, &extension_type) || - !CBS_get_u16_length_prefixed(&encrypted_extensions, &extension) || - CBS_len(&encrypted_extensions) != 0 || - extension_type != TLSEXT_TYPE_channel_id || - CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) { - OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_MESSAGE); - return -1; - } - - p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); - if (!p256) { - OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT); - return -1; - } - - BN_init(&x); - BN_init(&y); - sig.r = BN_new(); - sig.s = BN_new(); - if (sig.r == NULL || sig.s == NULL) { - goto err; - } - - p = CBS_data(&extension); - if (BN_bin2bn(p + 0, 32, &x) == NULL || - BN_bin2bn(p + 32, 32, &y) == NULL || - BN_bin2bn(p + 64, 32, sig.r) == NULL || - BN_bin2bn(p + 96, 32, sig.s) == NULL) { - goto err; - } - - point = EC_POINT_new(p256); - if (!point || - !EC_POINT_set_affine_coordinates_GFp(p256, point, &x, &y, NULL)) { - goto err; - } - - key = EC_KEY_new(); - if (!key || !EC_KEY_set_group(key, p256) || - !EC_KEY_set_public_key(key, point)) { - goto err; - } - - /* We stored the handshake hash in |tlsext_channel_id| the first time that we - * were called. */ - if (!ECDSA_do_verify(channel_id_hash, channel_id_hash_len, &sig, key)) { - OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID); - ssl->s3->tlsext_channel_id_valid = 0; - goto err; - } - - memcpy(ssl->s3->tlsext_channel_id, p, 64); - ret = 1; - -err: - BN_free(&x); - BN_free(&y); - BN_free(sig.r); - BN_free(sig.s); - EC_KEY_free(key); - EC_POINT_free(point); - EC_GROUP_free(p256); - return ret; -} diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 9c8e723a..b72cacbd 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -514,13 +514,13 @@ void SSL_free(SSL *ssl) { void SSL_set_connect_state(SSL *ssl) { ssl->server = 0; ssl->state = SSL_ST_CONNECT; - ssl->handshake_func = ssl->method->ssl_connect; + ssl->handshake_func = ssl3_connect; } void SSL_set_accept_state(SSL *ssl) { ssl->server = 1; ssl->state = SSL_ST_ACCEPT; - ssl->handshake_func = ssl->method->ssl_accept; + ssl->handshake_func = ssl3_accept; } void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) { @@ -579,8 +579,6 @@ int SSL_connect(SSL *ssl) { SSL_set_connect_state(ssl); } - assert(ssl->handshake_func == ssl->method->ssl_connect); - return SSL_do_handshake(ssl); } @@ -590,8 +588,6 @@ int SSL_accept(SSL *ssl) { SSL_set_accept_state(ssl); } - assert(ssl->handshake_func == ssl->method->ssl_accept); - return SSL_do_handshake(ssl); }