Add support to test_ssl_new for testing with DTLS over SCTP
[openssl.git] / test / ssltestlib.c
index b0ea6c899db316d80bd5d4352e96534f79317567..6fce12e0fc72faa2d9f8fb77ccbd33c2a12570e3 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <string.h>
 
+#include "e_os.h"
 #include "ssltestlib.h"
 
 static int tls_dump_new(BIO *bi);
@@ -155,7 +156,7 @@ static void dump_data(const char *data, int len)
                 printf("*** Message Fragment len: %d\n", fraglen);
                 if (fragoff + fraglen > msglen)
                     printf("***---- HANDSHAKE MESSAGE FRAGMENT INVALID ----\n");
-                else if(reclen < fraglen)
+                else if (reclen < fraglen)
                     printf("**---- HANDSHAKE MESSAGE FRAGMENT TRUNCATED ----\n");
                 else
                     printf("**---- END OF HANDSHAKE MESSAGE FRAGMENT ----\n");
@@ -231,14 +232,12 @@ static int tls_dump_puts(BIO *bio, const char *str)
 }
 
 
-typedef struct mempacket_st {
+struct mempacket_st {
     unsigned char *data;
     int len;
     unsigned int num;
     unsigned int type;
-} MEMPACKET;
-
-DEFINE_STACK_OF(MEMPACKET)
+};
 
 static void mempacket_free(MEMPACKET *pkt)
 {
@@ -339,7 +338,7 @@ static int mempacket_test_read(BIO *bio, char *out, int outl)
         BIO_set_retry_read(bio);
         return -1;
     }
-    sk_MEMPACKET_shift(ctx->pkts);
+    (void)sk_MEMPACKET_shift(ctx->pkts);
     ctx->currpkt++;
 
     if (outl > thispkt->len)
@@ -444,7 +443,7 @@ int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum,
                 else
                     return inl;
             } while(1);
-        } else if(looppkt->num == thispkt->num) {
+        } else if (looppkt->num == thispkt->num) {
             if (!ctx->noinject) {
                 /* We injected two packets with the same packet number! */
                 return -1;
@@ -552,6 +551,10 @@ int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
         goto err;
     }
 
+#ifndef OPENSSL_NO_DH
+    SSL_CTX_set_dh_auto(serverctx, 1);
+#endif
+
     *sctx = serverctx;
     *cctx = clientctx;
 
@@ -562,16 +565,14 @@ int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
     return 0;
 }
 
-#define MAXLOOPS    100000
+#define MAXLOOPS    1000000
 
 /*
  * NOTE: Transfers control of the BIOs - this function will free them on error
  */
-int create_ssl_connection(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
+int create_ssl_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
                           SSL **cssl, BIO *s_to_c_fbio, BIO *c_to_s_fbio)
 {
-    int retc = -1, rets = -1, err, abortctr = 0;
-    int clienterr = 0, servererr = 0;
     SSL *serverssl, *clientssl;
     BIO *s_to_c_bio = NULL, *c_to_s_bio = NULL;
 
@@ -589,8 +590,13 @@ int create_ssl_connection(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
         goto error;
     }
 
-    s_to_c_bio = BIO_new(BIO_s_mem());
-    c_to_s_bio = BIO_new(BIO_s_mem());
+    if (SSL_is_dtls(clientssl)) {
+        s_to_c_bio = BIO_new(bio_s_mempacket_test());
+        c_to_s_bio = BIO_new(bio_s_mempacket_test());
+    } else {
+        s_to_c_bio = BIO_new(BIO_s_mem());
+        c_to_s_bio = BIO_new(BIO_s_mem());
+    }
     if (s_to_c_bio == NULL || c_to_s_bio == NULL) {
         printf("Failed to create mem BIOs\n");
         goto error;
@@ -620,6 +626,29 @@ int create_ssl_connection(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
     s_to_c_bio = c_to_s_bio = NULL;
     s_to_c_fbio = c_to_s_fbio = NULL;
 
+    *sssl = serverssl;
+    *cssl = clientssl;
+
+    return 1;
+
+ error:
+    SSL_free(serverssl);
+    SSL_free(clientssl);
+    BIO_free(s_to_c_bio);
+    BIO_free(c_to_s_bio);
+    BIO_free(s_to_c_fbio);
+    BIO_free(c_to_s_fbio);
+
+    return 0;
+}
+
+int create_ssl_connection(SSL *serverssl, SSL *clientssl, int want)
+{
+    int retc = -1, rets = -1, err, abortctr = 0;
+    int clienterr = 0, servererr = 0;
+    unsigned char buf;
+    size_t readbytes;
+
     do {
         err = SSL_ERROR_WANT_WRITE;
         while (!clienterr && retc <= 0 && err == SSL_ERROR_WANT_WRITE) {
@@ -632,6 +661,8 @@ int create_ssl_connection(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
             printf("SSL_connect() failed %d, %d\n", retc, err);
             clienterr = 1;
         }
+        if (want != SSL_ERROR_NONE && err == want)
+            return 0;
 
         err = SSL_ERROR_WANT_WRITE;
         while (!servererr && rets <= 0 && err == SSL_ERROR_WANT_WRITE) {
@@ -641,33 +672,33 @@ int create_ssl_connection(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
         }
 
         if (!servererr && rets <= 0 && err != SSL_ERROR_WANT_READ) {
-            printf("SSL_accept() failed %d, %d\n", retc, err);
+            printf("SSL_accept() failed %d, %d\n", rets, err);
             servererr = 1;
         }
+        if (want != SSL_ERROR_NONE && err == want)
+            return 0;
         if (clienterr && servererr)
-            goto error;
+            return 0;
         if (++abortctr == MAXLOOPS) {
             printf("No progress made\n");
-            goto error;
+            return 0;
         }
     } while (retc <=0 || rets <= 0);
 
-    *sssl = serverssl;
-    *cssl = clientssl;
-
-    return 1;
-
- error:
-    if (*sssl == NULL) {
-        SSL_free(serverssl);
-        BIO_free(s_to_c_bio);
-        BIO_free(s_to_c_fbio);
-    }
-    if (*cssl == NULL) {
-        SSL_free(clientssl);
-        BIO_free(c_to_s_bio);
-        BIO_free(c_to_s_fbio);
+    /*
+     * We attempt to read some data on the client side which we expect to fail.
+     * This will ensure we have received the NewSessionTicket in TLSv1.3 where
+     * appropriate.
+     */
+    if (SSL_read_ex(clientssl, &buf, sizeof(buf), &readbytes) > 0) {
+        if (readbytes != 0) {
+            printf("Unexpected success reading data %"OSSLzu"\n", readbytes);
+            return 0;
+        }
+    } else if (SSL_get_error(clientssl, 0) != SSL_ERROR_WANT_READ) {
+        printf("SSL_read_ex() failed\n");
+        return 0;
     }
 
-    return 0;
+    return 1;
 }