Make DTLSv1_listen a first class function and change its type
authorMatt Caswell <matt@openssl.org>
Fri, 5 Feb 2016 10:59:42 +0000 (10:59 +0000)
committerMatt Caswell <matt@openssl.org>
Fri, 5 Feb 2016 19:12:18 +0000 (19:12 +0000)
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 <levitte@openssl.org>
CHANGES
apps/s_server.c
doc/ssl/DTLSv1_listen.pod
include/openssl/ssl.h
ssl/d1_lib.c
ssl/ssl_err.c
util/ssleay.num

diff --git a/CHANGES b/CHANGES
index e8bc44225c3417aa28efa2669e502b3cde538eed..b2e5a71ad0a9188c864f84e8860adac92b0e0f1f 100644 (file)
--- 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,
index 1a54f082f48e8cdc148c8f58f1359ec8d70b88cd..45e9227f07eae196ac99a1677b4b90d69c5076fd 100644 (file)
@@ -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;
index b3dd1ae155168c605e87a1e91773e297f6a51267..62913de56dc70d110aab6b407918aa60ff7bd569 100644 (file)
@@ -8,7 +8,7 @@ DTLSv1_listen - listen for incoming DTLS connections.
 
  #include <openssl/ssl.h>
 
- 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<ssl> parameter updated into a state
 where the handshake can be continued by a call to (for example) SSL_accept().
-Additionally the B<struct sockaddr> location pointed to by B<peer> 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<peer> 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<BIO_ADDR> pointed to by B<peer> 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<ssl(3)>, L<bio(3)>
 
 =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
index e1f5fc6e89433c9c97219f22bdd4efceb381bfc6..8c80c91f715d01858bf8a84a182edeec51f802b1 100644 (file)
@@ -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
index 3fde524ba88c22da6bae170d5924180d2b1f5776..ae89a23d9ed681d7edae6ca8d720241c2f5dd6d3 100644 (file)
@@ -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;
     }
 
index 18c64d997c72764b4c750f8ed03e701037c8bd59..67966ab92c3f61ca44cbd28ecf29d440cf27bb9d 100644 (file)
@@ -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),
index 89797c5a3d8f4ef5a2e8477477bd5f309089edf1..f1bf0ce61ff653b40be9ff48c61928a6641e5d5f 100755 (executable)
@@ -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: