Fix build break; restore missing target
[openssl.git] / test / ssltest.c
index 4959aed3ab0b5272121ebcee3b137a6931b0e185..d6b6618cbd73335d8735355de93b9f7a433f43c7 100644 (file)
 
 /* Or gethostname won't be declared properly on Linux and GNU platforms. */
 #define _BSD_SOURCE 1
+#define _DEFAULT_SOURCE 1
 
 #include <assert.h>
 #include <errno.h>
 #define COMP_ZLIB       1
 
 static int verify_callback(int ok, X509_STORE_CTX *ctx);
-#ifndef OPENSSL_NO_RSA
-static RSA *tmp_rsa_cb(SSL *s, int is_export, int keylength);
-static void free_tmp_rsa(void);
-#endif
 static int app_verify_callback(X509_STORE_CTX *ctx, void *arg);
 #define APP_CALLBACK_STRING "Test Callback Argument"
 struct app_verify_arg {
@@ -256,7 +253,7 @@ typedef struct srp_client_arg_st {
 static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
 {
     SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg;
-    return BUF_strdup((char *)srp_client_arg->srppassin);
+    return OPENSSL_strdup((char *)srp_client_arg->srppassin);
 }
 
 /* SRP server */
@@ -288,9 +285,9 @@ static BIO *bio_stdout = NULL;
 #ifndef OPENSSL_NO_NEXTPROTONEG
 /* Note that this code assumes that this is only a one element list: */
 static const char NEXT_PROTO_STRING[] = "\x09testproto";
-int npn_client = 0;
-int npn_server = 0;
-int npn_server_reject = 0;
+static int npn_client = 0;
+static int npn_server = 0;
+static int npn_server_reject = 0;
 
 static int cb_client_npn(SSL *s, unsigned char **out, unsigned char *outlen,
                          const unsigned char *in, unsigned int inlen,
@@ -370,6 +367,11 @@ static const char *alpn_client;
 static const char *alpn_server;
 static const char *alpn_expected;
 static unsigned char *alpn_selected;
+static const char *server_min_proto;
+static const char *server_max_proto;
+static const char *client_min_proto;
+static const char *client_max_proto;
+static const char *should_negotiate;
 
 /*-
  * next_protos_parse parses a comma separated list of strings into a string
@@ -454,7 +456,12 @@ static int verify_alpn(SSL *client, SSL *server)
     OPENSSL_free(alpn_selected);
     alpn_selected = NULL;
 
-    if (client_proto_len != server_proto_len ||
+    if (client_proto_len != server_proto_len) {
+        BIO_printf(bio_stdout, "ALPN selected protocols differ!\n");
+        goto err;
+    }
+
+    if (client_proto != NULL &&
         memcmp(client_proto, server_proto, client_proto_len) != 0) {
         BIO_printf(bio_stdout, "ALPN selected protocols differ!\n");
         goto err;
@@ -500,24 +507,24 @@ static int verify_alpn(SSL *client, SSL *server)
 #define CUSTOM_EXT_TYPE_2 1002
 #define CUSTOM_EXT_TYPE_3 1003
 
-const char custom_ext_cli_string[] = "abc";
-const char custom_ext_srv_string[] = "defg";
+static const char custom_ext_cli_string[] = "abc";
+static const char custom_ext_srv_string[] = "defg";
 
 /* These set from cmdline */
-char *serverinfo_file = NULL;
-int serverinfo_sct = 0;
-int serverinfo_tack = 0;
+static char *serverinfo_file = NULL;
+static int serverinfo_sct = 0;
+static int serverinfo_tack = 0;
 
 /* These set based on extension callbacks */
-int serverinfo_sct_seen = 0;
-int serverinfo_tack_seen = 0;
-int serverinfo_other_seen = 0;
+static int serverinfo_sct_seen = 0;
+static int serverinfo_tack_seen = 0;
+static int serverinfo_other_seen = 0;
 
 /* This set from cmdline */
-int custom_ext = 0;
+static int custom_ext = 0;
 
 /* This set based on extension callbacks */
-int custom_ext_error = 0;
+static int custom_ext_error = 0;
 
 static int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type,
                                    const unsigned char *in, size_t inlen,
@@ -774,6 +781,7 @@ static void sv_usage(void)
 #endif
     fprintf(stderr, " -tls1         - use TLSv1\n");
 #ifndef OPENSSL_NO_DTLS
+    fprintf(stderr, " -dtls        - use DTLS\n");
     fprintf(stderr, " -dtls1        - use DTLSv1\n");
     fprintf(stderr, " -dtls12       - use DTLSv1.2\n");
 #endif
@@ -816,6 +824,11 @@ static void sv_usage(void)
     fprintf(stderr, " -alpn_server <string> - have server side offer ALPN\n");
     fprintf(stderr,
             " -alpn_expected <string> - the ALPN protocol that should be negotiated\n");
+    fprintf(stderr, " -server_min_proto <string> - Minimum version the server should support\n");
+    fprintf(stderr, " -server_max_proto <string> - Maximum version the server should support\n");
+    fprintf(stderr, " -client_min_proto <string> - Minimum version the client should support\n");
+    fprintf(stderr, " -client_max_proto <string> - Maximum version the client should support\n");
+    fprintf(stderr, " -should_negotiate <string> - The version that should be negotiated, fail-client or fail-server\n");
 }
 
 static void print_key_details(BIO *out, EVP_PKEY *key)
@@ -940,17 +953,63 @@ static void lock_dbg_cb(int mode, int type, const char *file, int line)
     }
 }
 
+/*
+ * protocol_from_string - converts a protocol version string to a number
+ *
+ * Returns -1 on failure or the version on success
+ */
+static int protocol_from_string(const char *value)
+{
+    struct protocol_versions {
+        const char *name;
+        int version;
+    };
+    static const struct protocol_versions versions[] = {
+        {"ssl3", SSL3_VERSION},
+        {"tls1", TLS1_VERSION},
+        {"tls1.1", TLS1_1_VERSION},
+        {"tls1.2", TLS1_2_VERSION},
+        {"dtls1", DTLS1_VERSION},
+        {"dtls1.2", DTLS1_2_VERSION}};
+    size_t i;
+    size_t n = OSSL_NELEM(versions);
+
+    for (i = 0; i < n; i++)
+        if (strcmp(versions[i].name, value) == 0)
+            return versions[i].version;
+    return -1;
+}
+
+/*
+ * set_protocol_version - Sets protocol version minimum or maximum
+ *
+ * Returns 0 on failure and 1 on success
+ */
+static int set_protocol_version(const char *version, SSL *ssl, int setting)
+{
+    if (version != NULL) {
+        int ver = protocol_from_string(version);
+        if (ver < 0) {
+            BIO_printf(bio_err, "Error parsing: %s\n", version);
+            return 0;
+        }
+        return SSL_ctrl(ssl, setting, ver, NULL);
+    }
+    return 1;
+}
+
 int main(int argc, char *argv[])
 {
     char *CApath = NULL, *CAfile = NULL;
     int badop = 0;
     int bio_pair = 0;
     int force = 0;
-    int dtls1 = 0, dtls12 = 0, tls1 = 0, ssl3 = 0, ret = 1;
+    int dtls1 = 0, dtls12 = 0, dtls = 0, tls1 = 0, ssl3 = 0, ret = 1;
     int client_auth = 0;
     int server_auth = 0, i;
     struct app_verify_arg app_verify_arg =
         { APP_CALLBACK_STRING, 0, 0, NULL, NULL };
+    char *p;
 #ifndef OPENSSL_NO_EC
     char *named_curve = NULL;
 #endif
@@ -991,7 +1050,7 @@ int main(int argc, char *argv[])
 
     SSL_CONF_CTX *s_cctx = NULL, *c_cctx = NULL;
     STACK_OF(OPENSSL_STRING) *conf_args = NULL;
-    const char *arg = NULL, *argn = NULL;
+    char *arg = NULL, *argn = NULL;
 
     verbose = 0;
     debug = 0;
@@ -1001,15 +1060,9 @@ int main(int argc, char *argv[])
 
     CRYPTO_set_locking_callback(lock_dbg_cb);
 
-    /* enable memory leak checking unless explicitly disabled */
-    if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL)
-          && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) {
-        CRYPTO_malloc_debug_init();
-        CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
-    } else {
-        /* OPENSSL_DEBUG_MEMORY=off */
-        CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
-    }
+    p = getenv("OPENSSL_DEBUG_MEMORY");
+    if (p != NULL && strcmp(p, "on") == 0)
+        CRYPTO_set_mem_debug(1);
     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
 
     RAND_seed(rnd_seed, sizeof rnd_seed);
@@ -1134,6 +1187,11 @@ int main(int argc, char *argv[])
             no_protocol = 1;
 #endif
             dtls12 = 1;
+        } else if (strcmp(*argv, "-dtls") == 0) {
+#ifdef OPENSSL_NO_DTLS
+            no_protocol = 1;
+#endif
+            dtls = 1;
         } else if (strncmp(*argv, "-num", 4) == 0) {
             if (--argc < 1)
                 goto bad;
@@ -1223,6 +1281,26 @@ int main(int argc, char *argv[])
             if (--argc < 1)
                 goto bad;
             alpn_expected = *(++argv);
+        } else if (strcmp(*argv, "-server_min_proto") == 0) {
+            if (--argc < 1)
+                goto bad;
+            server_min_proto = *(++argv);
+        } else if (strcmp(*argv, "-server_max_proto") == 0) {
+            if (--argc < 1)
+                goto bad;
+            server_max_proto = *(++argv);
+        } else if (strcmp(*argv, "-client_min_proto") == 0) {
+            if (--argc < 1)
+                goto bad;
+            client_min_proto = *(++argv);
+        } else if (strcmp(*argv, "-client_max_proto") == 0) {
+            if (--argc < 1)
+                goto bad;
+            client_max_proto = *(++argv);
+        } else if (strcmp(*argv, "-should_negotiate") == 0) {
+            if (--argc < 1)
+                goto bad;
+            should_negotiate = *(++argv);
         } else {
             int rv;
             arg = argv[0];
@@ -1281,8 +1359,8 @@ int main(int argc, char *argv[])
         goto end;
     }
 
-    if (ssl3 + tls1 + dtls1 + dtls12 > 1) {
-        fprintf(stderr, "At most one of -ssl3, -tls1, -dtls1 or -dtls12 should "
+    if (ssl3 + tls1 + dtls + dtls1 + dtls12 > 1) {
+        fprintf(stderr, "At most one of -ssl3, -tls1, -dtls, -dtls1 or -dtls12 should "
                 "be requested.\n");
         EXIT(1);
     }
@@ -1299,10 +1377,10 @@ int main(int argc, char *argv[])
         goto end;
     }
 
-    if (!ssl3 && !tls1 && !dtls1 && !dtls12 && number > 1 && !reuse && !force) {
+    if (!ssl3 && !tls1 && !dtls && !dtls1 && !dtls12 && number > 1 && !reuse && !force) {
         fprintf(stderr, "This case cannot work.  Use -f to perform "
                 "the test anyway (and\n-d to see what happens), "
-                "or add one of -ssl3, -tls1, -dtls1, -dtls12, -reuse\n"
+                "or add one of -ssl3, -tls1, -dtls, -dtls1, -dtls12, -reuse\n"
                 "to avoid protocol mismatch.\n");
         EXIT(1);
     }
@@ -1376,6 +1454,8 @@ int main(int argc, char *argv[])
         meth = DTLSv1_method();
     else if (dtls12)
         meth = DTLSv1_2_method();
+    else if (dtls)
+        meth = DTLS_method();
     else
 #endif
     if (tls1)
@@ -1477,10 +1557,6 @@ int main(int argc, char *argv[])
     (void)no_ecdhe;
 #endif
 
-#ifndef OPENSSL_NO_RSA
-    SSL_CTX_set_tmp_rsa_callback(s_ctx, tmp_rsa_cb);
-#endif
-
     if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) ||
         (!SSL_CTX_set_default_verify_paths(s_ctx)) ||
         (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) ||
@@ -1661,6 +1737,15 @@ int main(int argc, char *argv[])
     c_ssl = SSL_new(c_ctx);
     s_ssl = SSL_new(s_ctx);
 
+    if (!set_protocol_version(server_min_proto, s_ssl, SSL_CTRL_SET_MIN_PROTO_VERSION))
+        goto end;
+    if (!set_protocol_version(server_max_proto, s_ssl, SSL_CTRL_SET_MAX_PROTO_VERSION))
+        goto end;
+    if (!set_protocol_version(client_min_proto, c_ssl, SSL_CTRL_SET_MIN_PROTO_VERSION))
+        goto end;
+    if (!set_protocol_version(client_max_proto, c_ssl, SSL_CTRL_SET_MAX_PROTO_VERSION))
+        goto end;
+
     BIO_printf(bio_stdout, "Doing handshakes=%d bytes=%ld\n", number, bytes);
     for (i = 0; i < number; i++) {
         if (!reuse) {
@@ -1676,6 +1761,23 @@ int main(int argc, char *argv[])
        if (ret)  break;
     }
 
+    if (should_negotiate && ret == 0 &&
+        strcmp(should_negotiate, "fail-server") != 0 &&
+        strcmp(should_negotiate, "fail-client") != 0) {
+        int version = protocol_from_string(should_negotiate);
+        if (version < 0) {
+            BIO_printf(bio_err, "Error parsing: %s\n", should_negotiate);
+            ret = 1;
+            goto err;
+        }
+        if (SSL_version(c_ssl) != version) {
+            BIO_printf(bio_err, "Unxpected version negotiated. "
+                "Expected: %s, got %s\n", should_negotiate, SSL_get_version(c_ssl));
+            ret = 1;
+            goto err;
+        }
+    }
+
     if (!verbose) {
         print_details(c_ssl, "");
     }
@@ -1698,6 +1800,7 @@ int main(int argc, char *argv[])
 #endif
     }
 
+ err:
     SSL_free(s_ssl);
     SSL_free(c_ssl);
 
@@ -1710,17 +1813,17 @@ int main(int argc, char *argv[])
 
     BIO_free(bio_stdout);
 
-#ifndef OPENSSL_NO_RSA
-    free_tmp_rsa();
-#endif
 #ifndef OPENSSL_NO_ENGINE
     ENGINE_cleanup();
 #endif
+    CONF_modules_unload(1);
     CRYPTO_cleanup_all_ex_data();
     ERR_free_strings();
     ERR_remove_thread_state(NULL);
     EVP_cleanup();
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
     CRYPTO_mem_leaks(bio_err);
+#endif
     BIO_free(bio_err);
     EXIT(ret);
 }
@@ -1732,6 +1835,8 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
     BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL;
     BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL;
     int ret = 1;
+    int err_in_client = 0;
+    int err_in_server = 0;
 
     size_t bufsiz = 256;        /* small buffer for testing */
 
@@ -1824,6 +1929,7 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
                 if (r < 0) {
                     if (!BIO_should_retry(c_ssl_bio)) {
                         fprintf(stderr, "ERROR in CLIENT\n");
+                        err_in_client = 1;
                         goto err;
                     }
                     /*
@@ -1849,6 +1955,7 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
                 if (r < 0) {
                     if (!BIO_should_retry(c_ssl_bio)) {
                         fprintf(stderr, "ERROR in CLIENT\n");
+                        err_in_client = 1;
                         goto err;
                     }
                     /*
@@ -1901,6 +2008,7 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
                 if (r < 0) {
                     if (!BIO_should_retry(s_ssl_bio)) {
                         fprintf(stderr, "ERROR in SERVER\n");
+                        err_in_server = 1;
                         goto err;
                     }
                     /* Ignore "BIO_should_retry". */
@@ -1921,6 +2029,7 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
                 if (r < 0) {
                     if (!BIO_should_retry(s_ssl_bio)) {
                         fprintf(stderr, "ERROR in SERVER\n");
+                        err_in_server = 1;
                         goto err;
                     }
                     /* blah, blah */
@@ -2088,6 +2197,11 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
     BIO_free(s_ssl_bio);
     BIO_free(c_ssl_bio);
 
+    if (should_negotiate != NULL && strcmp(should_negotiate, "fail-client") == 0)
+        ret = (err_in_client != 0) ? 0 : 1;
+    else if (should_negotiate != NULL && strcmp(should_negotiate, "fail-server") == 0)
+        ret = (err_in_server != 0) ? 0 : 1;
+
     return ret;
 }
 
@@ -2113,6 +2227,8 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
     int c_write, s_write;
     int do_server = 0, do_client = 0;
     int max_frag = 5 * 1024;
+    int err_in_client = 0;
+    int err_in_server = 0;
 
     bufsiz = count > 40 * 1024 ? 40 * 1024 : count;
 
@@ -2205,6 +2321,7 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
                             c_w = 1;
                     } else {
                         fprintf(stderr, "ERROR in CLIENT\n");
+                        err_in_client = 1;
                         ERR_print_errors(bio_err);
                         goto err;
                     }
@@ -2233,6 +2350,7 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
                             c_w = 1;
                     } else {
                         fprintf(stderr, "ERROR in CLIENT\n");
+                        err_in_client = 1;
                         ERR_print_errors(bio_err);
                         goto err;
                     }
@@ -2269,6 +2387,7 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
                             s_w = 1;
                     } else {
                         fprintf(stderr, "ERROR in SERVER\n");
+                        err_in_server = 1;
                         ERR_print_errors(bio_err);
                         goto err;
                     }
@@ -2304,6 +2423,7 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
                             s_w = 1;
                     } else {
                         fprintf(stderr, "ERROR in SERVER\n");
+                        err_in_server = 1;
                         ERR_print_errors(bio_err);
                         goto err;
                     }
@@ -2374,6 +2494,11 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
     OPENSSL_free(cbuf);
     OPENSSL_free(sbuf);
 
+    if (should_negotiate != NULL && strcmp(should_negotiate, "fail-client") == 0)
+        ret = (err_in_client != 0) ? 0 : 1;
+    else if (should_negotiate != NULL && strcmp(should_negotiate, "fail-server") == 0)
+        ret = (err_in_server != 0) ? 0 : 1;
+
     return (ret);
 }
 
@@ -2828,39 +2953,6 @@ static int app_verify_callback(X509_STORE_CTX *ctx, void *arg)
     return (ok);
 }
 
-#ifndef OPENSSL_NO_RSA
-static RSA *rsa_tmp = NULL;
-
-static RSA *tmp_rsa_cb(SSL *s, int is_export, int keylength)
-{
-    BIGNUM *bn = NULL;
-    if (rsa_tmp == NULL) {
-        bn = BN_new();
-        rsa_tmp = RSA_new();
-        if (!bn || !rsa_tmp || !BN_set_word(bn, RSA_F4)) {
-            BIO_printf(bio_err, "Memory error...");
-            goto end;
-        }
-        printf("Generating temp (%d bit) RSA key...", keylength);
-        if (!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) {
-            BIO_printf(bio_err, "Error generating key.");
-            RSA_free(rsa_tmp);
-            rsa_tmp = NULL;
-        }
- end:
-        printf("\n");
-    }
-    BN_free(bn);
-    return (rsa_tmp);
-}
-
-static void free_tmp_rsa(void)
-{
-    RSA_free(rsa_tmp);
-    rsa_tmp = NULL;
-}
-#endif
-
 #ifndef OPENSSL_NO_DH
 /*-
  * These DH parameters have been generated as follows:
@@ -3082,7 +3174,7 @@ static int do_test_cipherlist(void)
         if (tci != NULL)
             if (ci->id >= tci->id) {
                 fprintf(stderr, "testing SSLv3 cipher list order: ");
-                fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
+                fprintf(stderr, "failed %x vs. %x\n", ci->id, tci->id);
                 return 0;
             }
         tci = ci;
@@ -3094,7 +3186,7 @@ static int do_test_cipherlist(void)
         if (tci != NULL)
             if (ci->id >= tci->id) {
                 fprintf(stderr, "testing TLSv1 cipher list order: ");
-                fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id);
+                fprintf(stderr, "failed %x vs. %x\n", ci->id, tci->id);
                 return 0;
             }
         tci = ci;