engine.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Copyright 2020 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. /*
  10. * Here is a set of wrappers for the ENGINE API, which are no-ops when the
  11. * ENGINE API is disabled / removed.
  12. * We need to suppress deprecation warnings to make this work.
  13. */
  14. #define OPENSSL_SUPPRESS_DEPRECATED
  15. #include <string.h> /* strcmp */
  16. #include <openssl/types.h> /* Ensure we have the ENGINE type, regardless */
  17. #include <openssl/err.h>
  18. #ifndef OPENSSL_NO_ENGINE
  19. # include <openssl/engine.h>
  20. #endif
  21. #include "apps.h"
  22. #ifndef OPENSSL_NO_ENGINE
  23. /* Try to load an engine in a shareable library */
  24. static ENGINE *try_load_engine(const char *engine)
  25. {
  26. ENGINE *e = NULL;
  27. if ((e = ENGINE_by_id("dynamic")) != NULL) {
  28. if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
  29. || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
  30. ENGINE_free(e);
  31. e = NULL;
  32. }
  33. }
  34. return e;
  35. }
  36. #endif
  37. ENGINE *setup_engine_methods(const char *id, unsigned int methods, int debug)
  38. {
  39. ENGINE *e = NULL;
  40. #ifndef OPENSSL_NO_ENGINE
  41. if (id != NULL) {
  42. if (strcmp(id, "auto") == 0) {
  43. BIO_printf(bio_err, "Enabling auto ENGINE support\n");
  44. ENGINE_register_all_complete();
  45. return NULL;
  46. }
  47. if ((e = ENGINE_by_id(id)) == NULL
  48. && (e = try_load_engine(id)) == NULL) {
  49. BIO_printf(bio_err, "Invalid engine \"%s\"\n", id);
  50. ERR_print_errors(bio_err);
  51. return NULL;
  52. }
  53. if (debug)
  54. (void)ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0);
  55. if (!ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0,
  56. (void *)get_ui_method(), 0, 1)
  57. || !ENGINE_set_default(e, methods)) {
  58. BIO_printf(bio_err, "Cannot use engine \"%s\"\n", ENGINE_get_id(e));
  59. ERR_print_errors(bio_err);
  60. ENGINE_free(e);
  61. return NULL;
  62. }
  63. BIO_printf(bio_err, "Engine \"%s\" set.\n", ENGINE_get_id(e));
  64. }
  65. #endif
  66. return e;
  67. }
  68. void release_engine(ENGINE *e)
  69. {
  70. #ifndef OPENSSL_NO_ENGINE
  71. /* Free our "structural" reference. */
  72. ENGINE_free(e);
  73. #endif
  74. }
  75. int init_engine(ENGINE *e)
  76. {
  77. int rv = 1;
  78. #ifndef OPENSSL_NO_ENGINE
  79. rv = ENGINE_init(e);
  80. #endif
  81. return rv;
  82. }
  83. int finish_engine(ENGINE *e)
  84. {
  85. int rv = 1;
  86. #ifndef OPENSSL_NO_ENGINE
  87. rv = ENGINE_finish(e);
  88. #endif
  89. return rv;
  90. }
  91. char *make_engine_uri(ENGINE *e, const char *key_id, const char *desc)
  92. {
  93. char *new_uri = NULL;
  94. #ifndef OPENSSL_NO_ENGINE
  95. if (e == NULL) {
  96. BIO_printf(bio_err, "No engine specified for loading %s\n", desc);
  97. } else if (key_id == NULL) {
  98. BIO_printf(bio_err, "No engine key id specified for loading %s\n", desc);
  99. } else {
  100. const char *engineid = ENGINE_get_id(e);
  101. size_t uri_sz =
  102. sizeof(ENGINE_SCHEME_COLON) - 1
  103. + strlen(engineid)
  104. + 1 /* : */
  105. + strlen(key_id)
  106. + 1 /* \0 */
  107. ;
  108. new_uri = OPENSSL_malloc(uri_sz);
  109. if (new_uri != NULL) {
  110. OPENSSL_strlcpy(new_uri, ENGINE_SCHEME_COLON, uri_sz);
  111. OPENSSL_strlcat(new_uri, engineid, uri_sz);
  112. OPENSSL_strlcat(new_uri, ":", uri_sz);
  113. OPENSSL_strlcat(new_uri, key_id, uri_sz);
  114. }
  115. }
  116. #else
  117. BIO_printf(bio_err, "Engines not supported for loading %s\n", desc);
  118. #endif
  119. return new_uri;
  120. }
  121. int get_legacy_pkey_id(OSSL_LIB_CTX *libctx, const char *algname, ENGINE *e)
  122. {
  123. const EVP_PKEY_ASN1_METHOD *ameth;
  124. ENGINE *tmpeng = NULL;
  125. int pkey_id = NID_undef;
  126. ERR_set_mark();
  127. ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
  128. #if !defined(OPENSSL_NO_ENGINE)
  129. ENGINE_finish(tmpeng);
  130. if (ameth == NULL && e != NULL)
  131. ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1);
  132. else
  133. #endif
  134. /* We're only interested if it comes from an ENGINE */
  135. if (tmpeng == NULL)
  136. ameth = NULL;
  137. ERR_pop_to_mark();
  138. if (ameth == NULL)
  139. return NID_undef;
  140. EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
  141. return pkey_id;
  142. }
  143. const EVP_MD *get_digest_from_engine(const char *name)
  144. {
  145. #ifndef OPENSSL_NO_ENGINE
  146. ENGINE *eng;
  147. eng = ENGINE_get_digest_engine(OBJ_sn2nid(name));
  148. if (eng != NULL) {
  149. ENGINE_finish(eng);
  150. return EVP_get_digestbyname(name);
  151. }
  152. #endif
  153. return NULL;
  154. }
  155. const EVP_CIPHER *get_cipher_from_engine(const char *name)
  156. {
  157. #ifndef OPENSSL_NO_ENGINE
  158. ENGINE *eng;
  159. eng = ENGINE_get_cipher_engine(OBJ_sn2nid(name));
  160. if (eng != NULL) {
  161. ENGINE_finish(eng);
  162. return EVP_get_cipherbyname(name);
  163. }
  164. #endif
  165. return NULL;
  166. }