Enable the cookie callbacks to work even in TLS in the apps
authorMatt Caswell <matt@openssl.org>
Tue, 12 Sep 2017 15:19:09 +0000 (16:19 +0100)
committerMatt Caswell <matt@openssl.org>
Wed, 24 Jan 2018 18:02:36 +0000 (18:02 +0000)
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
(Merged from https://github.com/openssl/openssl/pull/4435)

apps/apps.h
apps/s_cb.c
apps/s_socket.c

index 6d0d7015f886e61b1196ffac1af52bfd7f0498eb..601797b1b6669dee4cbf462271e7ec914274ea44 100644 (file)
@@ -46,6 +46,8 @@ extern BIO *bio_out;
 extern BIO *bio_err;
 extern const unsigned char tls13_aes128gcmsha256_id[];
 extern const unsigned char tls13_aes256gcmsha384_id[];
+extern BIO_ADDR *ourpeer;
+
 BIO *dup_bio_in(int format);
 BIO *dup_bio_out(int format);
 BIO *dup_bio_err(int format);
index c7c9ecb170302ca73579eee5ad775b71ac3aa4f6..575fb048c093e2056b2a35433f1f2f7e2013c352 100644 (file)
@@ -686,9 +686,9 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
                              unsigned int *cookie_len)
 {
     unsigned char *buffer;
-    size_t length;
+    size_t length = 0;
     unsigned short port;
-    BIO_ADDR *peer = NULL;
+    BIO_ADDR *lpeer = NULL, *peer = NULL;
 
     /* Initialize a random secret */
     if (!cookie_initialized) {
@@ -699,17 +699,24 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
         cookie_initialized = 1;
     }
 
-    peer = BIO_ADDR_new();
-    if (peer == NULL) {
-        BIO_printf(bio_err, "memory full\n");
-        return 0;
-    }
+    if (SSL_is_dtls(ssl)) {
+        lpeer = peer = BIO_ADDR_new();
+        if (peer == NULL) {
+            BIO_printf(bio_err, "memory full\n");
+            return 0;
+        }
 
-    /* Read peer information */
-    (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), peer);
+        /* Read peer information */
+        (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), peer);
+    } else {
+        peer = ourpeer;
+    }
 
     /* Create buffer with peer's address and port */
-    BIO_ADDR_rawaddress(peer, NULL, &length);
+    if (!BIO_ADDR_rawaddress(peer, NULL, &length)) {
+        BIO_printf(bio_err, "Failed getting peer address\n");
+        return 0;
+    }
     OPENSSL_assert(length != 0);
     port = BIO_ADDR_rawport(peer);
     length += sizeof(port);
@@ -723,7 +730,7 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
          buffer, length, cookie, cookie_len);
 
     OPENSSL_free(buffer);
-    BIO_ADDR_free(peer);
+    BIO_ADDR_free(lpeer);
 
     return 1;
 }
index 74cf8d28e2cc368ce53b98eb6ef75b1c820de9f5..a9e46f9949a8a12e0532a0f13b6ac5bb6cd7dd3f 100644 (file)
@@ -35,6 +35,9 @@ typedef unsigned int u_int;
 # include <openssl/bio.h>
 # include <openssl/err.h>
 
+/* Keep track of our peer's address for the cookie callback */
+BIO_ADDR *ourpeer = NULL;
+
 /*
  * init_client - helper routine to set up socket communication
  * @sock: pointer to storage of resulting socket.
@@ -212,8 +215,15 @@ int do_server(int *accept_sock, const char *host, const char *port,
         *accept_sock = asock;
     for (;;) {
         if (type == SOCK_STREAM) {
+            BIO_ADDR_free(ourpeer);
+            ourpeer = BIO_ADDR_new();
+            if (ourpeer == NULL) {
+                BIO_closesocket(asock);
+                ERR_print_errors(bio_err);
+                goto end;
+            }
             do {
-                sock = BIO_accept_ex(asock, NULL, 0);
+                sock = BIO_accept_ex(asock, ourpeer, 0);
             } while (sock < 0 && BIO_sock_should_retry(sock));
             if (sock < 0) {
                 ERR_print_errors(bio_err);
@@ -264,6 +274,8 @@ int do_server(int *accept_sock, const char *host, const char *port,
     if (family == AF_UNIX)
         unlink(host);
 # endif
+    BIO_ADDR_free(ourpeer);
+    ourpeer = NULL;
     return ret;
 }