enginetest.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. /*
  2. * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /* We need to use some deprecated APIs */
  10. #define OPENSSL_SUPPRESS_DEPRECATED
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <openssl/e_os2.h>
  15. # include "testutil.h"
  16. #ifndef OPENSSL_NO_ENGINE
  17. # include <openssl/buffer.h>
  18. # include <openssl/crypto.h>
  19. # include <openssl/engine.h>
  20. # include <openssl/rsa.h>
  21. # include <openssl/err.h>
  22. # include <openssl/x509.h>
  23. # include <openssl/pem.h>
  24. static void display_engine_list(void)
  25. {
  26. ENGINE *h;
  27. int loop;
  28. loop = 0;
  29. for (h = ENGINE_get_first(); h != NULL; h = ENGINE_get_next(h)) {
  30. TEST_info("#%d: id = \"%s\", name = \"%s\"",
  31. loop++, ENGINE_get_id(h), ENGINE_get_name(h));
  32. }
  33. /*
  34. * ENGINE_get_first() increases the struct_ref counter, so we must call
  35. * ENGINE_free() to decrease it again
  36. */
  37. ENGINE_free(h);
  38. }
  39. #define NUMTOADD 512
  40. static int test_engines(void)
  41. {
  42. ENGINE *block[NUMTOADD];
  43. char *eid[NUMTOADD];
  44. char *ename[NUMTOADD];
  45. char buf[256];
  46. ENGINE *ptr;
  47. int loop;
  48. int to_return = 0;
  49. ENGINE *new_h1 = NULL;
  50. ENGINE *new_h2 = NULL;
  51. ENGINE *new_h3 = NULL;
  52. ENGINE *new_h4 = NULL;
  53. memset(block, 0, sizeof(block));
  54. if (!TEST_ptr(new_h1 = ENGINE_new())
  55. || !TEST_true(ENGINE_set_id(new_h1, "test_id0"))
  56. || !TEST_true(ENGINE_set_name(new_h1, "First test item"))
  57. || !TEST_ptr(new_h2 = ENGINE_new())
  58. || !TEST_true(ENGINE_set_id(new_h2, "test_id1"))
  59. || !TEST_true(ENGINE_set_name(new_h2, "Second test item"))
  60. || !TEST_ptr(new_h3 = ENGINE_new())
  61. || !TEST_true(ENGINE_set_id(new_h3, "test_id2"))
  62. || !TEST_true(ENGINE_set_name(new_h3, "Third test item"))
  63. || !TEST_ptr(new_h4 = ENGINE_new())
  64. || !TEST_true(ENGINE_set_id(new_h4, "test_id3"))
  65. || !TEST_true(ENGINE_set_name(new_h4, "Fourth test item")))
  66. goto end;
  67. TEST_info("Engines:");
  68. display_engine_list();
  69. if (!TEST_true(ENGINE_add(new_h1)))
  70. goto end;
  71. TEST_info("Engines:");
  72. display_engine_list();
  73. ptr = ENGINE_get_first();
  74. if (!TEST_true(ENGINE_remove(ptr)))
  75. goto end;
  76. ENGINE_free(ptr);
  77. TEST_info("Engines:");
  78. display_engine_list();
  79. if (!TEST_true(ENGINE_add(new_h3))
  80. || !TEST_true(ENGINE_add(new_h2)))
  81. goto end;
  82. TEST_info("Engines:");
  83. display_engine_list();
  84. if (!TEST_true(ENGINE_remove(new_h2)))
  85. goto end;
  86. TEST_info("Engines:");
  87. display_engine_list();
  88. if (!TEST_true(ENGINE_add(new_h4)))
  89. goto end;
  90. TEST_info("Engines:");
  91. display_engine_list();
  92. /* Should fail. */
  93. if (!TEST_false(ENGINE_add(new_h3)))
  94. goto end;
  95. ERR_clear_error();
  96. /* Should fail. */
  97. if (!TEST_false(ENGINE_remove(new_h2)))
  98. goto end;
  99. ERR_clear_error();
  100. if (!TEST_true(ENGINE_remove(new_h3)))
  101. goto end;
  102. TEST_info("Engines:");
  103. display_engine_list();
  104. if (!TEST_true(ENGINE_remove(new_h4)))
  105. goto end;
  106. TEST_info("Engines:");
  107. display_engine_list();
  108. /*
  109. * At this point, we should have an empty list, unless some hardware
  110. * support engine got added. However, since we don't allow the config
  111. * file to be loaded and don't otherwise load any built in engines,
  112. * that is unlikely. Still, we check, if for nothing else, then to
  113. * notify that something is a little off (and might mean that |new_h1|
  114. * wasn't unloaded when it should have)
  115. */
  116. if ((ptr = ENGINE_get_first()) != NULL) {
  117. if (!ENGINE_remove(ptr))
  118. TEST_info("Remove failed - probably no hardware support present");
  119. }
  120. ENGINE_free(ptr);
  121. TEST_info("Engines:");
  122. display_engine_list();
  123. if (!TEST_true(ENGINE_add(new_h1))
  124. || !TEST_true(ENGINE_remove(new_h1)))
  125. goto end;
  126. TEST_info("About to beef up the engine-type list");
  127. for (loop = 0; loop < NUMTOADD; loop++) {
  128. sprintf(buf, "id%d", loop);
  129. eid[loop] = OPENSSL_strdup(buf);
  130. sprintf(buf, "Fake engine type %d", loop);
  131. ename[loop] = OPENSSL_strdup(buf);
  132. if (!TEST_ptr(block[loop] = ENGINE_new())
  133. || !TEST_true(ENGINE_set_id(block[loop], eid[loop]))
  134. || !TEST_true(ENGINE_set_name(block[loop], ename[loop])))
  135. goto end;
  136. }
  137. for (loop = 0; loop < NUMTOADD; loop++) {
  138. if (!TEST_true(ENGINE_add(block[loop]))) {
  139. test_note("Adding stopped at %d, (%s,%s)",
  140. loop, ENGINE_get_id(block[loop]),
  141. ENGINE_get_name(block[loop]));
  142. goto cleanup_loop;
  143. }
  144. }
  145. cleanup_loop:
  146. TEST_info("About to empty the engine-type list");
  147. while ((ptr = ENGINE_get_first()) != NULL) {
  148. if (!TEST_true(ENGINE_remove(ptr)))
  149. goto end;
  150. ENGINE_free(ptr);
  151. }
  152. for (loop = 0; loop < NUMTOADD; loop++) {
  153. OPENSSL_free(eid[loop]);
  154. OPENSSL_free(ename[loop]);
  155. }
  156. to_return = 1;
  157. end:
  158. ENGINE_free(new_h1);
  159. ENGINE_free(new_h2);
  160. ENGINE_free(new_h3);
  161. ENGINE_free(new_h4);
  162. for (loop = 0; loop < NUMTOADD; loop++)
  163. ENGINE_free(block[loop]);
  164. return to_return;
  165. }
  166. /* Test EVP_PKEY method */
  167. static EVP_PKEY_METHOD *test_rsa = NULL;
  168. static int called_encrypt = 0;
  169. /* Test function to check operation has been redirected */
  170. static int test_encrypt(EVP_PKEY_CTX *ctx, unsigned char *sig,
  171. size_t *siglen, const unsigned char *tbs, size_t tbslen)
  172. {
  173. called_encrypt = 1;
  174. return 1;
  175. }
  176. static int test_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
  177. const int **pnids, int nid)
  178. {
  179. static const int rnid = EVP_PKEY_RSA;
  180. if (pmeth == NULL) {
  181. *pnids = &rnid;
  182. return 1;
  183. }
  184. if (nid == EVP_PKEY_RSA) {
  185. *pmeth = test_rsa;
  186. return 1;
  187. }
  188. *pmeth = NULL;
  189. return 0;
  190. }
  191. /* Return a test EVP_PKEY value */
  192. static EVP_PKEY *get_test_pkey(void)
  193. {
  194. static unsigned char n[] =
  195. "\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
  196. "\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
  197. "\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
  198. "\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
  199. "\xF5";
  200. static unsigned char e[] = "\x11";
  201. RSA *rsa = RSA_new();
  202. EVP_PKEY *pk = EVP_PKEY_new();
  203. if (rsa == NULL || pk == NULL || !EVP_PKEY_assign_RSA(pk, rsa)) {
  204. RSA_free(rsa);
  205. EVP_PKEY_free(pk);
  206. return NULL;
  207. }
  208. if (!RSA_set0_key(rsa, BN_bin2bn(n, sizeof(n)-1, NULL),
  209. BN_bin2bn(e, sizeof(e)-1, NULL), NULL)) {
  210. EVP_PKEY_free(pk);
  211. return NULL;
  212. }
  213. return pk;
  214. }
  215. static int test_redirect(void)
  216. {
  217. const unsigned char pt[] = "Hello World\n";
  218. unsigned char *tmp = NULL;
  219. size_t len;
  220. EVP_PKEY_CTX *ctx = NULL;
  221. ENGINE *e = NULL;
  222. EVP_PKEY *pkey = NULL;
  223. int to_return = 0;
  224. if (!TEST_ptr(pkey = get_test_pkey()))
  225. goto err;
  226. len = EVP_PKEY_get_size(pkey);
  227. if (!TEST_ptr(tmp = OPENSSL_malloc(len)))
  228. goto err;
  229. if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL)))
  230. goto err;
  231. TEST_info("EVP_PKEY_encrypt test: no redirection");
  232. /* Encrypt some data: should succeed but not be redirected */
  233. if (!TEST_int_gt(EVP_PKEY_encrypt_init(ctx), 0)
  234. || !TEST_int_gt(EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)), 0)
  235. || !TEST_false(called_encrypt))
  236. goto err;
  237. EVP_PKEY_CTX_free(ctx);
  238. ctx = NULL;
  239. /* Create a test ENGINE */
  240. if (!TEST_ptr(e = ENGINE_new())
  241. || !TEST_true(ENGINE_set_id(e, "Test redirect engine"))
  242. || !TEST_true(ENGINE_set_name(e, "Test redirect engine")))
  243. goto err;
  244. /*
  245. * Try to create a context for this engine and test key.
  246. * Try setting test key engine. Both should fail because the
  247. * engine has no public key methods.
  248. */
  249. if (!TEST_ptr_null(ctx = EVP_PKEY_CTX_new(pkey, e))
  250. || !TEST_int_le(EVP_PKEY_set1_engine(pkey, e), 0))
  251. goto err;
  252. /* Setup an empty test EVP_PKEY_METHOD and set callback to return it */
  253. if (!TEST_ptr(test_rsa = EVP_PKEY_meth_new(EVP_PKEY_RSA, 0)))
  254. goto err;
  255. ENGINE_set_pkey_meths(e, test_pkey_meths);
  256. /* Getting a context for test ENGINE should now succeed */
  257. if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, e)))
  258. goto err;
  259. /* Encrypt should fail because operation is not supported */
  260. if (!TEST_int_le(EVP_PKEY_encrypt_init(ctx), 0))
  261. goto err;
  262. EVP_PKEY_CTX_free(ctx);
  263. ctx = NULL;
  264. /* Add test encrypt operation to method */
  265. EVP_PKEY_meth_set_encrypt(test_rsa, 0, test_encrypt);
  266. TEST_info("EVP_PKEY_encrypt test: redirection via EVP_PKEY_CTX_new()");
  267. if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, e)))
  268. goto err;
  269. /* Encrypt some data: should succeed and be redirected */
  270. if (!TEST_int_gt(EVP_PKEY_encrypt_init(ctx), 0)
  271. || !TEST_int_gt(EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)), 0)
  272. || !TEST_true(called_encrypt))
  273. goto err;
  274. EVP_PKEY_CTX_free(ctx);
  275. ctx = NULL;
  276. called_encrypt = 0;
  277. /* Create context with default engine: should not be redirected */
  278. if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL))
  279. || !TEST_int_gt(EVP_PKEY_encrypt_init(ctx), 0)
  280. || !TEST_int_gt(EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)), 0)
  281. || !TEST_false(called_encrypt))
  282. goto err;
  283. EVP_PKEY_CTX_free(ctx);
  284. ctx = NULL;
  285. /* Set engine explicitly for test key */
  286. if (!TEST_true(EVP_PKEY_set1_engine(pkey, e)))
  287. goto err;
  288. TEST_info("EVP_PKEY_encrypt test: redirection via EVP_PKEY_set1_engine()");
  289. /* Create context with default engine: should be redirected now */
  290. if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL))
  291. || !TEST_int_gt(EVP_PKEY_encrypt_init(ctx), 0)
  292. || !TEST_int_gt(EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)), 0)
  293. || !TEST_true(called_encrypt))
  294. goto err;
  295. to_return = 1;
  296. err:
  297. EVP_PKEY_CTX_free(ctx);
  298. EVP_PKEY_free(pkey);
  299. ENGINE_free(e);
  300. OPENSSL_free(tmp);
  301. return to_return;
  302. }
  303. static int test_x509_dup_w_engine(void)
  304. {
  305. ENGINE *e = NULL;
  306. X509 *cert = NULL, *dupcert = NULL;
  307. X509_PUBKEY *pubkey, *duppubkey = NULL;
  308. int ret = 0;
  309. BIO *b = NULL;
  310. RSA_METHOD *rsameth = NULL;
  311. if (!TEST_ptr(b = BIO_new_file(test_get_argument(0), "r"))
  312. || !TEST_ptr(cert = PEM_read_bio_X509(b, NULL, NULL, NULL)))
  313. goto err;
  314. /* Dup without an engine */
  315. if (!TEST_ptr(dupcert = X509_dup(cert)))
  316. goto err;
  317. X509_free(dupcert);
  318. dupcert = NULL;
  319. if (!TEST_ptr(pubkey = X509_get_X509_PUBKEY(cert))
  320. || !TEST_ptr(duppubkey = X509_PUBKEY_dup(pubkey))
  321. || !TEST_ptr_ne(duppubkey, pubkey)
  322. || !TEST_ptr_ne(X509_PUBKEY_get0(duppubkey), X509_PUBKEY_get0(pubkey)))
  323. goto err;
  324. X509_PUBKEY_free(duppubkey);
  325. duppubkey = NULL;
  326. X509_free(cert);
  327. cert = NULL;
  328. /* Create a test ENGINE */
  329. if (!TEST_ptr(e = ENGINE_new())
  330. || !TEST_true(ENGINE_set_id(e, "Test dummy engine"))
  331. || !TEST_true(ENGINE_set_name(e, "Test dummy engine")))
  332. goto err;
  333. if (!TEST_ptr(rsameth = RSA_meth_dup(RSA_get_default_method())))
  334. goto err;
  335. ENGINE_set_RSA(e, rsameth);
  336. if (!TEST_true(ENGINE_set_default_RSA(e)))
  337. goto err;
  338. if (!TEST_int_ge(BIO_seek(b, 0), 0)
  339. || !TEST_ptr(cert = PEM_read_bio_X509(b, NULL, NULL, NULL)))
  340. goto err;
  341. /* Dup with an engine set on the key */
  342. if (!TEST_ptr(dupcert = X509_dup(cert)))
  343. goto err;
  344. if (!TEST_ptr(pubkey = X509_get_X509_PUBKEY(cert))
  345. || !TEST_ptr(duppubkey = X509_PUBKEY_dup(pubkey))
  346. || !TEST_ptr_ne(duppubkey, pubkey)
  347. || !TEST_ptr_ne(X509_PUBKEY_get0(duppubkey), X509_PUBKEY_get0(pubkey)))
  348. goto err;
  349. ret = 1;
  350. err:
  351. X509_free(cert);
  352. X509_free(dupcert);
  353. X509_PUBKEY_free(duppubkey);
  354. if (e != NULL) {
  355. ENGINE_unregister_RSA(e);
  356. ENGINE_free(e);
  357. }
  358. RSA_meth_free(rsameth);
  359. BIO_free(b);
  360. return ret;
  361. }
  362. #endif
  363. int global_init(void)
  364. {
  365. /*
  366. * If the config file gets loaded, the dynamic engine will be loaded,
  367. * and that interferes with our test above.
  368. */
  369. return OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG, NULL);
  370. }
  371. OPT_TEST_DECLARE_USAGE("certfile\n")
  372. int setup_tests(void)
  373. {
  374. #ifdef OPENSSL_NO_ENGINE
  375. TEST_note("No ENGINE support");
  376. #else
  377. int n;
  378. if (!test_skip_common_options()) {
  379. TEST_error("Error parsing test options\n");
  380. return 0;
  381. }
  382. n = test_get_argument_count();
  383. if (n == 0)
  384. return 0;
  385. ADD_TEST(test_engines);
  386. ADD_TEST(test_redirect);
  387. ADD_TEST(test_x509_dup_w_engine);
  388. #endif
  389. return 1;
  390. }