enginetest.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /*
  2. * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (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. #include <stdio.h>
  10. #include <string.h>
  11. #include <openssl/e_os2.h>
  12. #ifdef OPENSSL_NO_ENGINE
  13. int main(int argc, char *argv[])
  14. {
  15. printf("No ENGINE support\n");
  16. return (0);
  17. }
  18. #else
  19. # include <openssl/buffer.h>
  20. # include <openssl/crypto.h>
  21. # include <openssl/engine.h>
  22. # include <openssl/err.h>
  23. # include <openssl/rsa.h>
  24. # include <openssl/bn.h>
  25. static void display_engine_list(void)
  26. {
  27. ENGINE *h;
  28. int loop;
  29. h = ENGINE_get_first();
  30. loop = 0;
  31. printf("listing available engine types\n");
  32. while (h) {
  33. printf("engine %i, id = \"%s\", name = \"%s\"\n",
  34. loop++, ENGINE_get_id(h), ENGINE_get_name(h));
  35. h = ENGINE_get_next(h);
  36. }
  37. printf("end of list\n");
  38. /*
  39. * ENGINE_get_first() increases the struct_ref counter, so we must call
  40. * ENGINE_free() to decrease it again
  41. */
  42. ENGINE_free(h);
  43. }
  44. /* Test EVP_PKEY method */
  45. static EVP_PKEY_METHOD *test_rsa = NULL;
  46. static int called_encrypt = 0;
  47. /* Test function to check operation has been redirected */
  48. static int test_encrypt(EVP_PKEY_CTX *ctx, unsigned char *sig,
  49. size_t *siglen, const unsigned char *tbs, size_t tbslen)
  50. {
  51. called_encrypt = 1;
  52. return 1;
  53. }
  54. static int test_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
  55. const int **pnids, int nid)
  56. {
  57. static const int rnid = EVP_PKEY_RSA;
  58. if (pmeth == NULL) {
  59. *pnids = &rnid;
  60. return 1;
  61. }
  62. if (nid == EVP_PKEY_RSA) {
  63. *pmeth = test_rsa;
  64. return 1;
  65. }
  66. *pmeth = NULL;
  67. return 0;
  68. }
  69. /* Return a test EVP_PKEY value */
  70. static EVP_PKEY *get_test_pkey(void)
  71. {
  72. static unsigned char n[] =
  73. "\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
  74. "\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
  75. "\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
  76. "\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
  77. "\xF5";
  78. static unsigned char e[] = "\x11";
  79. RSA *rsa = RSA_new();
  80. EVP_PKEY *pk = EVP_PKEY_new();
  81. if (rsa == NULL || pk == NULL || !EVP_PKEY_assign_RSA(pk, rsa)) {
  82. RSA_free(rsa);
  83. EVP_PKEY_free(pk);
  84. return NULL;
  85. }
  86. if (!RSA_set0_key(rsa, BN_bin2bn(n, sizeof(n)-1, NULL),
  87. BN_bin2bn(e, sizeof(e)-1, NULL), NULL)) {
  88. EVP_PKEY_free(pk);
  89. return NULL;
  90. }
  91. return pk;
  92. }
  93. static int test_redirect(void)
  94. {
  95. const unsigned char pt[] = "Hello World\n";
  96. unsigned char *tmp = NULL;
  97. size_t len;
  98. EVP_PKEY_CTX *ctx = NULL;
  99. ENGINE *e = NULL;
  100. EVP_PKEY *pkey = NULL;
  101. int to_return = 0;
  102. printf("\nRedirection test\n");
  103. if ((pkey = get_test_pkey()) == NULL) {
  104. printf("Get test key failed\n");
  105. goto err;
  106. }
  107. len = EVP_PKEY_size(pkey);
  108. if ((tmp = OPENSSL_malloc(len)) == NULL) {
  109. printf("Buffer alloc failed\n");
  110. goto err;
  111. }
  112. if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) {
  113. printf("Key context allocation failure\n");
  114. goto err;
  115. }
  116. printf("EVP_PKEY_encrypt test: no redirection\n");
  117. /* Encrypt some data: should succeed but not be redirected */
  118. if (EVP_PKEY_encrypt_init(ctx) <= 0
  119. || EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)) <= 0
  120. || called_encrypt) {
  121. printf("Test encryption failure\n");
  122. goto err;
  123. }
  124. EVP_PKEY_CTX_free(ctx);
  125. ctx = NULL;
  126. /* Create a test ENGINE */
  127. if ((e = ENGINE_new()) == NULL
  128. || !ENGINE_set_id(e, "Test redirect engine")
  129. || !ENGINE_set_name(e, "Test redirect engine")) {
  130. printf("Redirection engine setup failure\n");
  131. goto err;
  132. }
  133. /*
  134. * Try to create a context for this engine and test key.
  135. * Try setting test key engine. Both should fail because the
  136. * engine has no public key methods.
  137. */
  138. if (EVP_PKEY_CTX_new(pkey, e) != NULL
  139. || EVP_PKEY_set1_engine(pkey, e) > 0) {
  140. printf("Unexpected redirection success\n");
  141. goto err;
  142. }
  143. /* Setup an empty test EVP_PKEY_METHOD and set callback to return it */
  144. if ((test_rsa = EVP_PKEY_meth_new(EVP_PKEY_RSA, 0)) == NULL) {
  145. printf("Test RSA algorithm setup failure\n");
  146. goto err;
  147. }
  148. ENGINE_set_pkey_meths(e, test_pkey_meths);
  149. /* Getting a context for test ENGINE should now succeed */
  150. if ((ctx = EVP_PKEY_CTX_new(pkey, e)) == NULL) {
  151. printf("Redirected context allocation failed\n");
  152. goto err;
  153. }
  154. /* Encrypt should fail because operation is not supported */
  155. if (EVP_PKEY_encrypt_init(ctx) > 0) {
  156. printf("Encryption redirect unexpected success\n");
  157. goto err;
  158. }
  159. EVP_PKEY_CTX_free(ctx);
  160. ctx = NULL;
  161. /* Add test encrypt operation to method */
  162. EVP_PKEY_meth_set_encrypt(test_rsa, 0, test_encrypt);
  163. printf("EVP_PKEY_encrypt test: redirection via EVP_PKEY_CTX_new()\n");
  164. if ((ctx = EVP_PKEY_CTX_new(pkey, e)) == NULL) {
  165. printf("Redirected context allocation failed\n");
  166. goto err;
  167. }
  168. /* Encrypt some data: should succeed and be redirected */
  169. if (EVP_PKEY_encrypt_init(ctx) <= 0
  170. || EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)) <= 0
  171. || !called_encrypt) {
  172. printf("Redirected key context encryption failed\n");
  173. goto err;
  174. }
  175. EVP_PKEY_CTX_free(ctx);
  176. ctx = NULL;
  177. called_encrypt = 0;
  178. printf("EVP_PKEY_encrypt test: check default operation not redirected\n");
  179. /* Create context with default engine: should not be redirected */
  180. if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL
  181. || EVP_PKEY_encrypt_init(ctx) <= 0
  182. || EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)) <= 0
  183. || called_encrypt) {
  184. printf("Unredirected key context encryption failed\n");
  185. goto err;
  186. }
  187. EVP_PKEY_CTX_free(ctx);
  188. ctx = NULL;
  189. /* Set engine explicitly for test key */
  190. if (!EVP_PKEY_set1_engine(pkey, e)) {
  191. printf("Key engine set failed\n");
  192. goto err;
  193. }
  194. printf("EVP_PKEY_encrypt test: redirection via EVP_PKEY_set1_engine()\n");
  195. /* Create context with default engine: should be redirected now */
  196. if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL
  197. || EVP_PKEY_encrypt_init(ctx) <= 0
  198. || EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)) <= 0
  199. || !called_encrypt) {
  200. printf("Key redirection failure\n");
  201. goto err;
  202. }
  203. to_return = 1;
  204. err:
  205. EVP_PKEY_CTX_free(ctx);
  206. EVP_PKEY_free(pkey);
  207. ENGINE_free(e);
  208. OPENSSL_free(tmp);
  209. return to_return;
  210. }
  211. int main(int argc, char *argv[])
  212. {
  213. ENGINE *block[512];
  214. char buf[256];
  215. const char *id, *name, *p;
  216. ENGINE *ptr;
  217. int loop;
  218. int to_return = 1;
  219. ENGINE *new_h1 = NULL;
  220. ENGINE *new_h2 = NULL;
  221. ENGINE *new_h3 = NULL;
  222. ENGINE *new_h4 = NULL;
  223. p = getenv("OPENSSL_DEBUG_MEMORY");
  224. if (p != NULL && strcmp(p, "on") == 0)
  225. CRYPTO_set_mem_debug(1);
  226. memset(block, 0, sizeof(block));
  227. if (((new_h1 = ENGINE_new()) == NULL) ||
  228. !ENGINE_set_id(new_h1, "test_id0") ||
  229. !ENGINE_set_name(new_h1, "First test item") ||
  230. ((new_h2 = ENGINE_new()) == NULL) ||
  231. !ENGINE_set_id(new_h2, "test_id1") ||
  232. !ENGINE_set_name(new_h2, "Second test item") ||
  233. ((new_h3 = ENGINE_new()) == NULL) ||
  234. !ENGINE_set_id(new_h3, "test_id2") ||
  235. !ENGINE_set_name(new_h3, "Third test item") ||
  236. ((new_h4 = ENGINE_new()) == NULL) ||
  237. !ENGINE_set_id(new_h4, "test_id3") ||
  238. !ENGINE_set_name(new_h4, "Fourth test item")) {
  239. printf("Couldn't set up test ENGINE structures\n");
  240. goto end;
  241. }
  242. printf("\nenginetest beginning\n\n");
  243. display_engine_list();
  244. if (!ENGINE_add(new_h1)) {
  245. printf("Add failed!\n");
  246. goto end;
  247. }
  248. display_engine_list();
  249. ptr = ENGINE_get_first();
  250. if (!ENGINE_remove(ptr)) {
  251. printf("Remove failed!\n");
  252. goto end;
  253. }
  254. ENGINE_free(ptr);
  255. display_engine_list();
  256. if (!ENGINE_add(new_h3) || !ENGINE_add(new_h2)) {
  257. printf("Add failed!\n");
  258. goto end;
  259. }
  260. display_engine_list();
  261. if (!ENGINE_remove(new_h2)) {
  262. printf("Remove failed!\n");
  263. goto end;
  264. }
  265. display_engine_list();
  266. if (!ENGINE_add(new_h4)) {
  267. printf("Add failed!\n");
  268. goto end;
  269. }
  270. display_engine_list();
  271. if (ENGINE_add(new_h3)) {
  272. printf("Add *should* have failed but didn't!\n");
  273. goto end;
  274. } else
  275. printf("Add that should fail did.\n");
  276. ERR_clear_error();
  277. if (ENGINE_remove(new_h2)) {
  278. printf("Remove *should* have failed but didn't!\n");
  279. goto end;
  280. } else
  281. printf("Remove that should fail did.\n");
  282. ERR_clear_error();
  283. if (!ENGINE_remove(new_h3)) {
  284. printf("Remove failed!\n");
  285. goto end;
  286. }
  287. display_engine_list();
  288. if (!ENGINE_remove(new_h4)) {
  289. printf("Remove failed!\n");
  290. goto end;
  291. }
  292. display_engine_list();
  293. /*
  294. * Depending on whether there's any hardware support compiled in, this
  295. * remove may be destined to fail.
  296. */
  297. ptr = ENGINE_get_first();
  298. if (ptr)
  299. if (!ENGINE_remove(ptr))
  300. printf("Remove failed!i - probably no hardware "
  301. "support present.\n");
  302. ENGINE_free(ptr);
  303. display_engine_list();
  304. if (!ENGINE_add(new_h1) || !ENGINE_remove(new_h1)) {
  305. printf("Couldn't add and remove to an empty list!\n");
  306. goto end;
  307. } else
  308. printf("Successfully added and removed to an empty list!\n");
  309. printf("About to beef up the engine-type list\n");
  310. for (loop = 0; loop < 512; loop++) {
  311. sprintf(buf, "id%i", loop);
  312. id = OPENSSL_strdup(buf);
  313. sprintf(buf, "Fake engine type %i", loop);
  314. name = OPENSSL_strdup(buf);
  315. if (((block[loop] = ENGINE_new()) == NULL) ||
  316. !ENGINE_set_id(block[loop], id) ||
  317. !ENGINE_set_name(block[loop], name)) {
  318. printf("Couldn't create block of ENGINE structures.\n"
  319. "I'll probably also core-dump now, damn.\n");
  320. goto end;
  321. }
  322. }
  323. for (loop = 0; loop < 512; loop++) {
  324. if (!ENGINE_add(block[loop])) {
  325. printf("\nAdding stopped at %i, (%s,%s)\n",
  326. loop, ENGINE_get_id(block[loop]),
  327. ENGINE_get_name(block[loop]));
  328. goto cleanup_loop;
  329. } else
  330. printf(".");
  331. fflush(stdout);
  332. }
  333. cleanup_loop:
  334. printf("\nAbout to empty the engine-type list\n");
  335. while ((ptr = ENGINE_get_first()) != NULL) {
  336. if (!ENGINE_remove(ptr)) {
  337. printf("\nRemove failed!\n");
  338. goto end;
  339. }
  340. ENGINE_free(ptr);
  341. printf(".");
  342. fflush(stdout);
  343. }
  344. for (loop = 0; loop < 512; loop++) {
  345. OPENSSL_free((void *)ENGINE_get_id(block[loop]));
  346. OPENSSL_free((void *)ENGINE_get_name(block[loop]));
  347. }
  348. if (!test_redirect())
  349. goto end;
  350. printf("\nTests completed happily\n");
  351. to_return = 0;
  352. end:
  353. if (to_return)
  354. ERR_print_errors_fp(stderr);
  355. ENGINE_free(new_h1);
  356. ENGINE_free(new_h2);
  357. ENGINE_free(new_h3);
  358. ENGINE_free(new_h4);
  359. for (loop = 0; loop < 512; loop++)
  360. ENGINE_free(block[loop]);
  361. #ifndef OPENSSL_NO_CRYPTO_MDEBUG
  362. if (CRYPTO_mem_leaks_fp(stderr) <= 0)
  363. to_return = 1;
  364. #endif
  365. return to_return;
  366. }
  367. #endif