/*
- * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
#include <openssl/opensslv.h>
#include <openssl/ssl.h>
#include <openssl/ossl_typ.h>
+#include "internal/dso_conf.h"
#include "testutil.h"
-#if !defined(DSO_DLFCN) && !defined(DSO_WIN32)
-int main(void)
-{
- TEST_info("Not implemented on this platform\n");
- return 0;
-}
-
-#else
+typedef void DSO;
typedef const SSL_METHOD * (*TLS_method_t)(void);
typedef SSL_CTX * (*SSL_CTX_new_t)(const SSL_METHOD *meth);
typedef void (*SSL_CTX_free_t)(SSL_CTX *);
typedef unsigned long (*ERR_get_error_t)(void);
typedef unsigned long (*OpenSSL_version_num_t)(void);
+typedef DSO * (*DSO_dsobyaddr_t)(void (*addr)(void), int flags);
+typedef int (*DSO_free_t)(DSO *dso);
+
+typedef enum test_types_en {
+ CRYPTO_FIRST,
+ SSL_FIRST,
+ JUST_CRYPTO,
+ DSO_REFTEST
+} TEST_TYPE;
+
+static TEST_TYPE test_type;
+static const char *path_crypto;
+static const char *path_ssl;
#ifdef DSO_DLFCN
# include <dlfcn.h>
+# define SHLIB_INIT NULL
+
typedef void *SHLIB;
typedef void *SHLIB_SYM;
-# define SHLIB_INIT NULL
static int shlib_load(const char *filename, SHLIB *lib)
{
# include <windows.h>
+# define SHLIB_INIT 0
+
typedef HINSTANCE SHLIB;
typedef void *SHLIB_SYM;
-# define SHLIB_INIT 0
static int shlib_load(const char *filename, SHLIB *lib)
{
}
#endif
-typedef enum test_types_en {
- CRYPTO_FIRST,
- SSL_FIRST,
- JUST_CRYPTO
-} TEST_TYPE;
-static TEST_TYPE test_type;
-static const char *path_crypto;
-static const char *path_ssl;
+#if defined(DSO_DLFCN) || defined(DSO_WIN32)
static int test_lib(void)
{
if (!TEST_true(shlib_load(path_crypto, &cryptolib))
|| !TEST_true(shlib_load(path_ssl, &ssllib)))
goto end;
+ break;
case SSL_FIRST:
if (!TEST_true(shlib_load(path_ssl, &ssllib))
|| !TEST_true(shlib_load(path_crypto, &cryptolib)))
goto end;
break;
+ case DSO_REFTEST:
+ if (!TEST_true(shlib_load(path_crypto, &cryptolib)))
+ goto end;
+ break;
}
- if (test_type != JUST_CRYPTO) {
+ if (test_type != JUST_CRYPTO && test_type != DSO_REFTEST) {
if (!TEST_true(shlib_sym(ssllib, "TLS_method", &symbols[0].sym))
|| !TEST_true(shlib_sym(ssllib, "SSL_CTX_new", &symbols[1].sym))
|| !TEST_true(shlib_sym(ssllib, "SSL_CTX_free", &symbols[2].sym)))
myERR_get_error = (ERR_get_error_t)symbols[0].func;
if (!TEST_int_eq(myERR_get_error(), 0))
goto end;
+
+ /*
+ * The bits that COMPATIBILITY_MASK lets through MUST be the same in
+ * the library and in the application.
+ * The bits that are masked away MUST be a larger or equal number in
+ * the library compared to the application.
+ */
+# define COMPATIBILITY_MASK 0xfff00000L
myOpenSSL_version_num = (OpenSSL_version_num_t)symbols[1].func;
- if (!TEST_int_eq(myOpenSSL_version_num(), OPENSSL_VERSION_NUMBER))
+ if (!TEST_int_eq(myOpenSSL_version_num() & COMPATIBILITY_MASK,
+ OPENSSL_VERSION_NUMBER & COMPATIBILITY_MASK))
+ goto end;
+ if (!TEST_int_ge(myOpenSSL_version_num() & ~COMPATIBILITY_MASK,
+ OPENSSL_VERSION_NUMBER & ~COMPATIBILITY_MASK))
goto end;
+ if (test_type == DSO_REFTEST) {
+# ifdef DSO_DLFCN
+ DSO_dsobyaddr_t myDSO_dsobyaddr;
+ DSO_free_t myDSO_free;
+
+ /*
+ * This is resembling the code used in ossl_init_base() and
+ * OPENSSL_atexit() to block unloading the library after dlclose().
+ * We are not testing this on Windows, because it is done there in a
+ * completely different way. Especially as a call to DSO_dsobyaddr()
+ * will always return an error, because DSO_pathbyaddr() is not
+ * implemented there.
+ */
+ if (!TEST_true(shlib_sym(cryptolib, "DSO_dsobyaddr", &symbols[0].sym))
+ || !TEST_true(shlib_sym(cryptolib, "DSO_free",
+ &symbols[1].sym)))
+ goto end;
+
+ myDSO_dsobyaddr = (DSO_dsobyaddr_t)symbols[0].func;
+ myDSO_free = (DSO_free_t)symbols[1].func;
+
+ {
+ DSO *hndl;
+ /* use known symbol from crypto module */
+ if (!TEST_ptr(hndl = myDSO_dsobyaddr((void (*)(void))ERR_get_error, 0)))
+ goto end;
+ myDSO_free(hndl);
+ }
+# endif /* DSO_DLFCN */
+ }
+
switch (test_type) {
case JUST_CRYPTO:
if (!TEST_true(shlib_close(cryptolib)))
if (!TEST_true(shlib_close(cryptolib))
|| !TEST_true(shlib_close(ssllib)))
goto end;
+ break;
case SSL_FIRST:
if (!TEST_true(shlib_close(ssllib))
|| !TEST_true(shlib_close(cryptolib)))
goto end;
break;
+ case DSO_REFTEST:
+ if (!TEST_true(shlib_close(cryptolib)))
+ goto end;
+ break;
}
result = 1;
end:
return result;
}
+#endif
-int test_main(int argc, char **argv)
+
+int setup_tests(void)
{
- if (argc != 4) {
- TEST_error("Unexpected number of arguments");
- return EXIT_FAILURE;
- }
+ const char *p = test_get_argument(0);
- if (strcmp(argv[1], "-crypto_first") == 0) {
+ if (strcmp(p, "-crypto_first") == 0) {
test_type = CRYPTO_FIRST;
- } else if (strcmp(argv[1], "-ssl_first") == 0) {
+ } else if (strcmp(p, "-ssl_first") == 0) {
test_type = SSL_FIRST;
- } else if (strcmp(argv[1], "-just_crypto") == 0) {
+ } else if (strcmp(p, "-just_crypto") == 0) {
+ test_type = JUST_CRYPTO;
+ } else if (strcmp(p, "-dso_ref") == 0) {
test_type = JUST_CRYPTO;
} else {
TEST_error("Unrecognised argument");
- return EXIT_FAILURE;
+ return 0;
}
- path_crypto = argv[2];
- path_ssl = argv[3];
+ if (!TEST_ptr(path_crypto = test_get_argument(1))
+ || !TEST_ptr(path_ssl = test_get_argument(2)))
+ return 0;
+#if defined(DSO_DLFCN) || defined(DSO_WIN32)
ADD_TEST(test_lib);
- return run_tests(argv[0]);
-}
#endif
+ return 1;
+}