Fix declarations and constification for inline stack.
[openssl.git] / test / ssltest.c
index 6455af3fbf4dfcc8de1db349f927b2aebd0da2a3..44d001965e83955274d5abd1d12ad6784496519b 100644 (file)
 #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 {
@@ -257,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 */
@@ -371,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
@@ -780,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
@@ -822,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)
@@ -946,13 +953,58 @@ 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 =
@@ -997,7 +1049,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;
@@ -1140,6 +1192,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;
@@ -1229,6 +1286,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];
@@ -1287,8 +1364,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);
     }
@@ -1305,10 +1382,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);
     }
@@ -1382,6 +1459,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)
@@ -1475,7 +1554,6 @@ int main(int argc, char *argv[])
             goto end;
         }
 
-        SSL_CTX_set_ecdh_auto(s_ctx, 1);
         SSL_CTX_set_tmp_ecdh(s_ctx, ecdh);
         SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE);
         EC_KEY_free(ecdh);
@@ -1484,10 +1562,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)) ||
@@ -1668,6 +1742,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) {
@@ -1683,6 +1766,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, "");
     }
@@ -1705,6 +1805,7 @@ int main(int argc, char *argv[])
 #endif
     }
 
+ err:
     SSL_free(s_ssl);
     SSL_free(c_ssl);
 
@@ -1717,12 +1818,10 @@ 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);
@@ -1739,6 +1838,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 */
 
@@ -1831,6 +1932,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;
                     }
                     /*
@@ -1856,6 +1958,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;
                     }
                     /*
@@ -1908,6 +2011,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". */
@@ -1928,6 +2032,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 */
@@ -2095,6 +2200,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;
 }
 
@@ -2120,6 +2230,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;
 
@@ -2212,6 +2324,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;
                     }
@@ -2240,6 +2353,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;
                     }
@@ -2276,6 +2390,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;
                     }
@@ -2311,6 +2426,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;
                     }
@@ -2381,6 +2497,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);
 }
 
@@ -2835,39 +2956,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: