From 3edeb622ba9b01f8d4ac7b1a08ac0f0fa8a27c67 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 5 Feb 2016 10:59:42 +0000 Subject: [PATCH] Make DTLSv1_listen a first class function and change its type The DTLSv1_listen function exposed details of the underlying BIO abstraction and did not properly allow for IPv6. This commit changes the "peer" argument to be a BIO_ADDR and makes it a first class function (rather than a ctrl) to ensure proper type checking. Reviewed-by: Richard Levitte --- CHANGES | 3 +++ apps/s_server.c | 2 +- doc/ssl/DTLSv1_listen.pod | 17 ++++++------- include/openssl/ssl.h | 7 +++--- ssl/d1_lib.c | 50 ++++++++++++++++++--------------------- ssl/ssl_err.c | 2 +- util/ssleay.num | 1 + 7 files changed, 39 insertions(+), 43 deletions(-) diff --git a/CHANGES b/CHANGES index e8bc44225c..b2e5a71ad0 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,9 @@ Changes between 1.0.2f and 1.1.0 [xx XXX xxxx] + *) The arguments to the DTLSv1_listen function have changed. Specifically the + "peer" argument is now expected to be a BIO_ADDR object. + *) Rewrite of BIO networking library. The BIO library lacked consistent support of IPv6, and adding it required some more extensive modifications. This introduces the BIO_ADDR and BIO_ADDRINFO types, diff --git a/apps/s_server.c b/apps/s_server.c index 1a54f082f4..45e9227f07 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -2496,7 +2496,7 @@ static int init_ssl_connection(SSL *con) BIO_printf(bio_err, "ERROR - memory\n"); return 0; } - i = DTLSv1_listen(con, &client); + i = DTLSv1_listen(con, client); if (i > 0) { BIO *wbio; int fd = -1; diff --git a/doc/ssl/DTLSv1_listen.pod b/doc/ssl/DTLSv1_listen.pod index b3dd1ae155..62913de56d 100644 --- a/doc/ssl/DTLSv1_listen.pod +++ b/doc/ssl/DTLSv1_listen.pod @@ -8,7 +8,7 @@ DTLSv1_listen - listen for incoming DTLS connections. #include - int DTLSv1_listen(SSL *ssl, struct sockaddr *peer); + int DTLSv1_listen(SSL *ssl, BIO_ADDR *peer); =head1 DESCRIPTION @@ -43,14 +43,10 @@ messages from any peer. When a ClientHello is received that contains a cookie that has been verified, then DTLSv1_listen() will return with the B parameter updated into a state where the handshake can be continued by a call to (for example) SSL_accept(). -Additionally the B location pointed to by B will be -filled in with details of the peer that sent the ClientHello. It is the calling -code's responsibility to ensure that the B location is sufficiently large -to accommodate the addressing scheme in use. For example this might be done by -allocating space for a struct sockaddr_storage and casting the pointer to it to -a struct sockaddr * for the call to DTLSv1_listen(). Typically user code is -expected to "connect" the underlying socket to the peer and continue the -handshake in a connected state. +Additionally the B pointed to by B will be filled in with +details of the peer that sent the ClientHello. Typically user code is expected +to "connect" the underlying socket to the peer and continue the handshake in a +connected state. Prior to calling DTLSv1_listen() user code must ensure that cookie generation and verification callbacks have been set up using @@ -89,6 +85,7 @@ L, L =head1 HISTORY -DTLSv1_listen() return codes were clarified in OpenSSL 1.1.0. +DTLSv1_listen() return codes were clarified in OpenSSL 1.1.0. The type of "peer" +also changed in OpenSSL 1.1.0. =cut diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index e1f5fc6e89..8c80c91f71 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1184,7 +1184,6 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) # endif # define DTLS_CTRL_GET_TIMEOUT 73 # define DTLS_CTRL_HANDLE_TIMEOUT 74 -# define DTLS_CTRL_LISTEN 75 # define SSL_CTRL_GET_RI_SUPPORT 76 # define SSL_CTRL_CLEAR_MODE 78 # define SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB 79 @@ -1227,8 +1226,6 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) # define DTLSv1_handle_timeout(ssl) \ SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) -# define DTLSv1_listen(ssl, peer) \ - SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer) # define SSL_session_reused(ssl) \ SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL) # define SSL_num_renegotiations(ssl) \ @@ -1842,6 +1839,8 @@ void SSL_trace(int write_p, int version, int content_type, __owur const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c); # endif +int DTLSv1_listen(SSL *s, BIO_ADDR *client); + /* What the "other" parameter contains in security callback */ /* Mask for type */ # define SSL_SECOP_OTHER_TYPE 0xffff0000 @@ -1958,7 +1957,6 @@ void ERR_load_SSL_strings(void); # define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253 # define SSL_F_DTLS1_HANDLE_TIMEOUT 297 # define SSL_F_DTLS1_HEARTBEAT 305 -# define SSL_F_DTLS1_LISTEN 350 # define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 # define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 # define SSL_F_DTLS1_PROCESS_RECORD 257 @@ -1967,6 +1965,7 @@ void ERR_load_SSL_strings(void); # define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST 260 # define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST 264 # define SSL_F_DTLS1_WRITE_APP_DATA_BYTES 268 +# define SSL_F_DTLSV1_LISTEN 350 # define SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC 371 # define SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST 385 # define SSL_F_DTLS_GET_REASSEMBLED_MESSAGE 370 diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index 3fde524ba8..ae89a23d9e 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -75,7 +75,6 @@ static void get_current_time(struct timeval *t); static int dtls1_set_handshake_header(SSL *s, int type, unsigned long len); static int dtls1_handshake_write(SSL *s); -int dtls1_listen(SSL *s, BIO_ADDR *client); static unsigned int dtls1_link_min_mtu(void); /* XDTLS: figure out the right values */ @@ -252,9 +251,6 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) case DTLS_CTRL_HANDLE_TIMEOUT: ret = dtls1_handle_timeout(s); break; - case DTLS_CTRL_LISTEN: - ret = dtls1_listen(s, parg); - break; case DTLS_CTRL_SET_LINK_MTU: if (larg < (long)dtls1_link_min_mtu()) return 0; @@ -484,7 +480,7 @@ static void get_current_time(struct timeval *t) #define LISTEN_SEND_VERIFY_REQUEST 1 -int dtls1_listen(SSL *s, BIO_ADDR *client) +int DTLSv1_listen(SSL *s, BIO_ADDR *client) { int next, n, ret = 0, clearpkt = 0; unsigned char cookie[DTLS1_COOKIE_LENGTH]; @@ -508,7 +504,7 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) wbio = SSL_get_wbio(s); if(!rbio || !wbio) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_BIO_NOT_SET); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_BIO_NOT_SET); return -1; } @@ -527,19 +523,19 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) * SSL_accept) */ if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_UNSUPPORTED_SSL_VERSION); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNSUPPORTED_SSL_VERSION); return -1; } if (s->init_buf == NULL) { if ((bufm = BUF_MEM_new()) == NULL) { - SSLerr(SSL_F_DTLS1_LISTEN, ERR_R_MALLOC_FAILURE); + SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE); return -1; } if (!BUF_MEM_grow(bufm, SSL3_RT_MAX_PLAIN_LENGTH)) { BUF_MEM_free(bufm); - SSLerr(SSL_F_DTLS1_LISTEN, ERR_R_MALLOC_FAILURE); + SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE); return -1; } s->init_buf = bufm; @@ -572,7 +568,7 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) clearpkt = 1; if (!PACKET_buf_init(&pkt, buf, n)) { - SSLerr(SSL_F_DTLS1_LISTEN, ERR_R_INTERNAL_ERROR); + SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR); return -1; } @@ -587,7 +583,7 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) /* this packet contained a partial record, dump it */ if (n < DTLS1_RT_HEADER_LENGTH) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_RECORD_TOO_SMALL); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_RECORD_TOO_SMALL); goto end; } @@ -598,12 +594,12 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) /* Get the record header */ if (!PACKET_get_1(&pkt, &rectype) || !PACKET_get_1(&pkt, &versmajor)) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_LENGTH_MISMATCH); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH); goto end; } if (rectype != SSL3_RT_HANDSHAKE) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE); goto end; } @@ -612,7 +608,7 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) * the same. */ if (versmajor != DTLS1_VERSION_MAJOR) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); goto end; } @@ -621,13 +617,13 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) || !PACKET_copy_bytes(&pkt, seq, SEQ_NUM_SIZE) || !PACKET_get_length_prefixed_2(&pkt, &msgpkt) || PACKET_remaining(&pkt) != 0) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_LENGTH_MISMATCH); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH); goto end; } /* This is an initial ClientHello so the epoch has to be 0 */ if (seq[0] != 0 || seq[1] != 0) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE); goto end; } @@ -642,24 +638,24 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) || !PACKET_get_net_3(&msgpkt, &fraglen) || !PACKET_get_sub_packet(&msgpkt, &msgpayload, msglen) || PACKET_remaining(&msgpkt) != 0) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_LENGTH_MISMATCH); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH); goto end; } if (msgtype != SSL3_MT_CLIENT_HELLO) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE); goto end; } /* Message sequence number can only be 0 or 1 */ if(msgseq > 2) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_INVALID_SEQUENCE_NUMBER); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_INVALID_SEQUENCE_NUMBER); goto end; } /* We don't support a fragmented ClientHello whilst listening */ if (fragoff != 0 || fraglen != msglen) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_FRAGMENTED_CLIENT_HELLO); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_FRAGMENTED_CLIENT_HELLO); goto end; } @@ -669,7 +665,7 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) s->msg_callback_arg); if (!PACKET_get_net_2(&msgpayload, &clientvers)) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_LENGTH_MISMATCH); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH); goto end; } @@ -678,14 +674,14 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) */ if (DTLS_VERSION_LT(clientvers, (unsigned int)s->method->version) && s->method->version != DTLS_ANY_VERSION) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_WRONG_VERSION_NUMBER); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_WRONG_VERSION_NUMBER); goto end; } if (!PACKET_forward(&msgpayload, SSL3_RANDOM_SIZE) || !PACKET_get_length_prefixed_1(&msgpayload, &session) || !PACKET_get_length_prefixed_1(&msgpayload, &cookiepkt)) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_LENGTH_MISMATCH); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH); goto end; } @@ -700,7 +696,7 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) * We have a cookie, so lets check it. */ if (s->ctx->app_verify_cookie_cb == NULL) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_NO_VERIFY_COOKIE_CALLBACK); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_NO_VERIFY_COOKIE_CALLBACK); /* This is fatal */ return -1; } @@ -737,7 +733,7 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) if (s->ctx->app_gen_cookie_cb == NULL || s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 || cookielen > 255) { - SSLerr(SSL_F_DTLS1_LISTEN, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); + SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); /* This is fatal */ return -1; } @@ -808,7 +804,7 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) if ((tmpclient = BIO_ADDR_new()) == NULL || BIO_dgram_get_peer(rbio, tmpclient) <= 0 || BIO_dgram_set_peer(wbio, tmpclient) <= 0) { - SSLerr(SSL_F_DTLS1_LISTEN, ERR_R_INTERNAL_ERROR); + SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR); goto end; } BIO_ADDR_free(tmpclient); @@ -859,7 +855,7 @@ int dtls1_listen(SSL *s, BIO_ADDR *client) ossl_statem_set_hello_verify_done(s); if(BIO_dgram_get_peer(rbio, client) <= 0) { - SSLerr(SSL_F_DTLS1_LISTEN, ERR_R_INTERNAL_ERROR); + SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR); return -1; } diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 18c64d997c..67966ab92c 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -84,7 +84,6 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT), "DTLS1_GET_MESSAGE_FRAGMENT"}, {ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT), "dtls1_handle_timeout"}, {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "dtls1_heartbeat"}, - {ERR_FUNC(SSL_F_DTLS1_LISTEN), "dtls1_listen"}, {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "dtls1_preprocess_fragment"}, {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, @@ -96,6 +95,7 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST), "DTLS1_SEND_HELLO_VERIFY_REQUEST"}, {ERR_FUNC(SSL_F_DTLS1_WRITE_APP_DATA_BYTES), "dtls1_write_app_data_bytes"}, + {ERR_FUNC(SSL_F_DTLSV1_LISTEN), "dtlsv1_listen"}, {ERR_FUNC(SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC), "dtls_construct_change_cipher_spec"}, {ERR_FUNC(SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST), diff --git a/util/ssleay.num b/util/ssleay.num index 89797c5a3d..f1bf0ce61f 100755 --- a/util/ssleay.num +++ b/util/ssleay.num @@ -435,3 +435,4 @@ SSL_set_options 469 1_1_0 EXIST::FUNCTION: SSL_get_options 470 1_1_0 EXIST::FUNCTION: SSL_up_ref 471 1_1_0 EXIST::FUNCTION: SSL_CTX_up_ref 472 1_1_0 EXIST::FUNCTION: +DTLSv1_listen 473 1_1_0 EXIST::FUNCTION: -- 2.25.1