eng_list.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /*
  2. * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
  3. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  4. *
  5. * Licensed under the Apache License 2.0 (the "License"). You may not use
  6. * this file except in compliance with the License. You can obtain a copy
  7. * in the file LICENSE in the source distribution or at
  8. * https://www.openssl.org/source/license.html
  9. */
  10. /* We need to use some engine deprecated APIs */
  11. #define OPENSSL_SUPPRESS_DEPRECATED
  12. #include "eng_local.h"
  13. /*
  14. * The linked-list of pointers to engine types. engine_list_head incorporates
  15. * an implicit structural reference but engine_list_tail does not - the
  16. * latter is a computational optimization and only points to something that
  17. * is already pointed to by its predecessor in the list (or engine_list_head
  18. * itself). In the same way, the use of the "prev" pointer in each ENGINE is
  19. * to save excessive list iteration, it doesn't correspond to an extra
  20. * structural reference. Hence, engine_list_head, and each non-null "next"
  21. * pointer account for the list itself assuming exactly 1 structural
  22. * reference on each list member.
  23. */
  24. static ENGINE *engine_list_head = NULL;
  25. static ENGINE *engine_list_tail = NULL;
  26. /*
  27. * The linked list of currently loaded dynamic engines.
  28. */
  29. static ENGINE *engine_dyn_list_head = NULL;
  30. static ENGINE *engine_dyn_list_tail = NULL;
  31. /*
  32. * This cleanup function is only needed internally. If it should be called,
  33. * we register it with the "engine_cleanup_int()" stack to be called during
  34. * cleanup.
  35. */
  36. static void engine_list_cleanup(void)
  37. {
  38. ENGINE *iterator = engine_list_head;
  39. while (iterator != NULL) {
  40. ENGINE_remove(iterator);
  41. iterator = engine_list_head;
  42. }
  43. return;
  44. }
  45. /*
  46. * These static functions starting with a lower case "engine_" always take
  47. * place when global_engine_lock has been locked up.
  48. */
  49. static int engine_list_add(ENGINE *e)
  50. {
  51. int conflict = 0;
  52. ENGINE *iterator = NULL;
  53. if (e == NULL) {
  54. ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
  55. return 0;
  56. }
  57. iterator = engine_list_head;
  58. while (iterator && !conflict) {
  59. conflict = (strcmp(iterator->id, e->id) == 0);
  60. iterator = iterator->next;
  61. }
  62. if (conflict) {
  63. ERR_raise(ERR_LIB_ENGINE, ENGINE_R_CONFLICTING_ENGINE_ID);
  64. return 0;
  65. }
  66. if (engine_list_head == NULL) {
  67. /* We are adding to an empty list. */
  68. if (engine_list_tail) {
  69. ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR);
  70. return 0;
  71. }
  72. engine_list_head = e;
  73. e->prev = NULL;
  74. /*
  75. * The first time the list allocates, we should register the cleanup.
  76. */
  77. engine_cleanup_add_last(engine_list_cleanup);
  78. } else {
  79. /* We are adding to the tail of an existing list. */
  80. if ((engine_list_tail == NULL) || (engine_list_tail->next != NULL)) {
  81. ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR);
  82. return 0;
  83. }
  84. engine_list_tail->next = e;
  85. e->prev = engine_list_tail;
  86. }
  87. /*
  88. * Having the engine in the list assumes a structural reference.
  89. */
  90. e->struct_ref++;
  91. ENGINE_REF_PRINT(e, 0, 1);
  92. /* However it came to be, e is the last item in the list. */
  93. engine_list_tail = e;
  94. e->next = NULL;
  95. return 1;
  96. }
  97. static int engine_list_remove(ENGINE *e)
  98. {
  99. ENGINE *iterator;
  100. if (e == NULL) {
  101. ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
  102. return 0;
  103. }
  104. /* We need to check that e is in our linked list! */
  105. iterator = engine_list_head;
  106. while (iterator && (iterator != e))
  107. iterator = iterator->next;
  108. if (iterator == NULL) {
  109. ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ENGINE_IS_NOT_IN_LIST);
  110. return 0;
  111. }
  112. /* un-link e from the chain. */
  113. if (e->next)
  114. e->next->prev = e->prev;
  115. if (e->prev)
  116. e->prev->next = e->next;
  117. /* Correct our head/tail if necessary. */
  118. if (engine_list_head == e)
  119. engine_list_head = e->next;
  120. if (engine_list_tail == e)
  121. engine_list_tail = e->prev;
  122. engine_free_util(e, 0);
  123. return 1;
  124. }
  125. /* Add engine to dynamic engine list. */
  126. int engine_add_dynamic_id(ENGINE *e, ENGINE_DYNAMIC_ID dynamic_id,
  127. int not_locked)
  128. {
  129. int result = 0;
  130. ENGINE *iterator = NULL;
  131. if (e == NULL)
  132. return 0;
  133. if (e->dynamic_id == NULL && dynamic_id == NULL)
  134. return 0;
  135. if (not_locked && !CRYPTO_THREAD_write_lock(global_engine_lock))
  136. return 0;
  137. if (dynamic_id != NULL) {
  138. iterator = engine_dyn_list_head;
  139. while (iterator != NULL) {
  140. if (iterator->dynamic_id == dynamic_id)
  141. goto err;
  142. iterator = iterator->next;
  143. }
  144. if (e->dynamic_id != NULL)
  145. goto err;
  146. e->dynamic_id = dynamic_id;
  147. }
  148. if (engine_dyn_list_head == NULL) {
  149. /* We are adding to an empty list. */
  150. if (engine_dyn_list_tail != NULL)
  151. goto err;
  152. engine_dyn_list_head = e;
  153. e->prev_dyn = NULL;
  154. } else {
  155. /* We are adding to the tail of an existing list. */
  156. if (engine_dyn_list_tail == NULL
  157. || engine_dyn_list_tail->next_dyn != NULL)
  158. goto err;
  159. engine_dyn_list_tail->next_dyn = e;
  160. e->prev_dyn = engine_dyn_list_tail;
  161. }
  162. engine_dyn_list_tail = e;
  163. e->next_dyn = NULL;
  164. result = 1;
  165. err:
  166. if (not_locked)
  167. CRYPTO_THREAD_unlock(global_engine_lock);
  168. return result;
  169. }
  170. /* Remove engine from dynamic engine list. */
  171. void engine_remove_dynamic_id(ENGINE *e, int not_locked)
  172. {
  173. if (e == NULL || e->dynamic_id == NULL)
  174. return;
  175. if (not_locked && !CRYPTO_THREAD_write_lock(global_engine_lock))
  176. return;
  177. e->dynamic_id = NULL;
  178. /* un-link e from the chain. */
  179. if (e->next_dyn != NULL)
  180. e->next_dyn->prev_dyn = e->prev_dyn;
  181. if (e->prev_dyn != NULL)
  182. e->prev_dyn->next_dyn = e->next_dyn;
  183. /* Correct our head/tail if necessary. */
  184. if (engine_dyn_list_head == e)
  185. engine_dyn_list_head = e->next_dyn;
  186. if (engine_dyn_list_tail == e)
  187. engine_dyn_list_tail = e->prev_dyn;
  188. if (not_locked)
  189. CRYPTO_THREAD_unlock(global_engine_lock);
  190. }
  191. /* Get the first/last "ENGINE" type available. */
  192. ENGINE *ENGINE_get_first(void)
  193. {
  194. ENGINE *ret;
  195. if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
  196. ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE);
  197. return NULL;
  198. }
  199. if (!CRYPTO_THREAD_write_lock(global_engine_lock))
  200. return NULL;
  201. ret = engine_list_head;
  202. if (ret) {
  203. ret->struct_ref++;
  204. ENGINE_REF_PRINT(ret, 0, 1);
  205. }
  206. CRYPTO_THREAD_unlock(global_engine_lock);
  207. return ret;
  208. }
  209. ENGINE *ENGINE_get_last(void)
  210. {
  211. ENGINE *ret;
  212. if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
  213. ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE);
  214. return NULL;
  215. }
  216. if (!CRYPTO_THREAD_write_lock(global_engine_lock))
  217. return NULL;
  218. ret = engine_list_tail;
  219. if (ret) {
  220. ret->struct_ref++;
  221. ENGINE_REF_PRINT(ret, 0, 1);
  222. }
  223. CRYPTO_THREAD_unlock(global_engine_lock);
  224. return ret;
  225. }
  226. /* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
  227. ENGINE *ENGINE_get_next(ENGINE *e)
  228. {
  229. ENGINE *ret = NULL;
  230. if (e == NULL) {
  231. ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
  232. return NULL;
  233. }
  234. if (!CRYPTO_THREAD_write_lock(global_engine_lock))
  235. return NULL;
  236. ret = e->next;
  237. if (ret) {
  238. /* Return a valid structural reference to the next ENGINE */
  239. ret->struct_ref++;
  240. ENGINE_REF_PRINT(ret, 0, 1);
  241. }
  242. CRYPTO_THREAD_unlock(global_engine_lock);
  243. /* Release the structural reference to the previous ENGINE */
  244. ENGINE_free(e);
  245. return ret;
  246. }
  247. ENGINE *ENGINE_get_prev(ENGINE *e)
  248. {
  249. ENGINE *ret = NULL;
  250. if (e == NULL) {
  251. ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
  252. return NULL;
  253. }
  254. if (!CRYPTO_THREAD_write_lock(global_engine_lock))
  255. return NULL;
  256. ret = e->prev;
  257. if (ret) {
  258. /* Return a valid structural reference to the next ENGINE */
  259. ret->struct_ref++;
  260. ENGINE_REF_PRINT(ret, 0, 1);
  261. }
  262. CRYPTO_THREAD_unlock(global_engine_lock);
  263. /* Release the structural reference to the previous ENGINE */
  264. ENGINE_free(e);
  265. return ret;
  266. }
  267. /* Add another "ENGINE" type into the list. */
  268. int ENGINE_add(ENGINE *e)
  269. {
  270. int to_return = 1;
  271. if (e == NULL) {
  272. ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
  273. return 0;
  274. }
  275. if ((e->id == NULL) || (e->name == NULL)) {
  276. ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ID_OR_NAME_MISSING);
  277. return 0;
  278. }
  279. if (!CRYPTO_THREAD_write_lock(global_engine_lock))
  280. return 0;
  281. if (!engine_list_add(e)) {
  282. ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR);
  283. to_return = 0;
  284. }
  285. CRYPTO_THREAD_unlock(global_engine_lock);
  286. return to_return;
  287. }
  288. /* Remove an existing "ENGINE" type from the array. */
  289. int ENGINE_remove(ENGINE *e)
  290. {
  291. int to_return = 1;
  292. if (e == NULL) {
  293. ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
  294. return 0;
  295. }
  296. if (!CRYPTO_THREAD_write_lock(global_engine_lock))
  297. return 0;
  298. if (!engine_list_remove(e)) {
  299. ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR);
  300. to_return = 0;
  301. }
  302. CRYPTO_THREAD_unlock(global_engine_lock);
  303. return to_return;
  304. }
  305. static void engine_cpy(ENGINE *dest, const ENGINE *src)
  306. {
  307. dest->id = src->id;
  308. dest->name = src->name;
  309. dest->rsa_meth = src->rsa_meth;
  310. #ifndef OPENSSL_NO_DSA
  311. dest->dsa_meth = src->dsa_meth;
  312. #endif
  313. #ifndef OPENSSL_NO_DH
  314. dest->dh_meth = src->dh_meth;
  315. #endif
  316. #ifndef OPENSSL_NO_EC
  317. dest->ec_meth = src->ec_meth;
  318. #endif
  319. dest->rand_meth = src->rand_meth;
  320. dest->ciphers = src->ciphers;
  321. dest->digests = src->digests;
  322. dest->pkey_meths = src->pkey_meths;
  323. dest->destroy = src->destroy;
  324. dest->init = src->init;
  325. dest->finish = src->finish;
  326. dest->ctrl = src->ctrl;
  327. dest->load_privkey = src->load_privkey;
  328. dest->load_pubkey = src->load_pubkey;
  329. dest->cmd_defns = src->cmd_defns;
  330. dest->flags = src->flags;
  331. dest->dynamic_id = src->dynamic_id;
  332. engine_add_dynamic_id(dest, NULL, 0);
  333. }
  334. ENGINE *ENGINE_by_id(const char *id)
  335. {
  336. ENGINE *iterator;
  337. char *load_dir = NULL;
  338. if (id == NULL) {
  339. ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
  340. return NULL;
  341. }
  342. ENGINE_load_builtin_engines();
  343. if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
  344. ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE);
  345. return NULL;
  346. }
  347. if (!CRYPTO_THREAD_write_lock(global_engine_lock))
  348. return NULL;
  349. iterator = engine_list_head;
  350. while (iterator && (strcmp(id, iterator->id) != 0))
  351. iterator = iterator->next;
  352. if (iterator != NULL) {
  353. /*
  354. * We need to return a structural reference. If this is an ENGINE
  355. * type that returns copies, make a duplicate - otherwise increment
  356. * the existing ENGINE's reference count.
  357. */
  358. if (iterator->flags & ENGINE_FLAGS_BY_ID_COPY) {
  359. ENGINE *cp = ENGINE_new();
  360. if (cp == NULL)
  361. iterator = NULL;
  362. else {
  363. engine_cpy(cp, iterator);
  364. iterator = cp;
  365. }
  366. } else {
  367. iterator->struct_ref++;
  368. ENGINE_REF_PRINT(iterator, 0, 1);
  369. }
  370. }
  371. CRYPTO_THREAD_unlock(global_engine_lock);
  372. if (iterator != NULL)
  373. return iterator;
  374. /*
  375. * Prevent infinite recursion if we're looking for the dynamic engine.
  376. */
  377. if (strcmp(id, "dynamic")) {
  378. if ((load_dir = ossl_safe_getenv("OPENSSL_ENGINES")) == NULL)
  379. load_dir = ENGINESDIR;
  380. iterator = ENGINE_by_id("dynamic");
  381. if (!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
  382. !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
  383. !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
  384. load_dir, 0) ||
  385. !ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) ||
  386. !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
  387. goto notfound;
  388. return iterator;
  389. }
  390. notfound:
  391. ENGINE_free(iterator);
  392. ERR_raise_data(ERR_LIB_ENGINE, ENGINE_R_NO_SUCH_ENGINE, "id=%s", id);
  393. return NULL;
  394. /* EEK! Experimental code ends */
  395. }
  396. int ENGINE_up_ref(ENGINE *e)
  397. {
  398. int i;
  399. if (e == NULL) {
  400. ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
  401. return 0;
  402. }
  403. CRYPTO_UP_REF(&e->struct_ref, &i, global_engine_lock);
  404. return 1;
  405. }