engine_loader.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright 2018 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. /*
  10. * Here is an STORE loader for ENGINE backed keys. It relies on deprecated
  11. * functions, and therefore need to have deprecation warnings suppressed.
  12. * This file is not compiled at all in a '--api=3 no-deprecated' configuration.
  13. */
  14. #define OPENSSL_SUPPRESS_DEPRECATED
  15. #include "apps.h"
  16. #ifndef OPENSSL_NO_ENGINE
  17. # include <stdarg.h>
  18. # include <string.h>
  19. # include <openssl/engine.h>
  20. # include <openssl/store.h>
  21. /*
  22. * Support for legacy private engine keys via the 'org.openssl.engine:' scheme
  23. *
  24. * org.openssl.engine:{engineid}:{keyid}
  25. *
  26. * Note: we ONLY support ENGINE_load_private_key() and ENGINE_load_public_key()
  27. * Note 2: This scheme has a precedent in code in PKIX-SSH. for exactly
  28. * this sort of purpose.
  29. */
  30. /* Local definition of OSSL_STORE_LOADER_CTX */
  31. struct ossl_store_loader_ctx_st {
  32. ENGINE *e; /* Structural reference */
  33. char *keyid;
  34. int expected;
  35. int loaded; /* 0 = key not loaded yet, 1 = key loaded */
  36. };
  37. static OSSL_STORE_LOADER_CTX *OSSL_STORE_LOADER_CTX_new(ENGINE *e, char *keyid)
  38. {
  39. OSSL_STORE_LOADER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
  40. if (ctx != NULL) {
  41. ctx->e = e;
  42. ctx->keyid = keyid;
  43. }
  44. return ctx;
  45. }
  46. static void OSSL_STORE_LOADER_CTX_free(OSSL_STORE_LOADER_CTX *ctx)
  47. {
  48. if (ctx != NULL) {
  49. ENGINE_free(ctx->e);
  50. OPENSSL_free(ctx->keyid);
  51. OPENSSL_free(ctx);
  52. }
  53. }
  54. static OSSL_STORE_LOADER_CTX *engine_open(const OSSL_STORE_LOADER *loader,
  55. const char *uri,
  56. const UI_METHOD *ui_method,
  57. void *ui_data)
  58. {
  59. const char *p = uri, *q;
  60. ENGINE *e = NULL;
  61. char *keyid = NULL;
  62. OSSL_STORE_LOADER_CTX *ctx = NULL;
  63. if (strncasecmp(p, ENGINE_SCHEME_COLON, sizeof(ENGINE_SCHEME_COLON) - 1)
  64. != 0)
  65. return NULL;
  66. p += sizeof(ENGINE_SCHEME_COLON) - 1;
  67. /* Look for engine ID */
  68. q = strchr(p, ':');
  69. if (q != NULL /* There is both an engine ID and a key ID */
  70. && p[0] != ':' /* The engine ID is at least one character */
  71. && q[1] != '\0') { /* The key ID is at least one character */
  72. char engineid[256];
  73. size_t engineid_l = q - p;
  74. strncpy(engineid, p, engineid_l);
  75. engineid[engineid_l] = '\0';
  76. e = ENGINE_by_id(engineid);
  77. keyid = OPENSSL_strdup(q + 1);
  78. }
  79. if (e != NULL)
  80. ctx = OSSL_STORE_LOADER_CTX_new(e, keyid);
  81. if (ctx == NULL) {
  82. OPENSSL_free(keyid);
  83. ENGINE_free(e);
  84. }
  85. return ctx;
  86. }
  87. static int engine_expect(OSSL_STORE_LOADER_CTX *ctx, int expected)
  88. {
  89. if (expected == 0
  90. || expected == OSSL_STORE_INFO_PUBKEY
  91. || expected == OSSL_STORE_INFO_PKEY) {
  92. ctx->expected = expected;
  93. return 1;
  94. }
  95. return 0;
  96. }
  97. static OSSL_STORE_INFO *engine_load(OSSL_STORE_LOADER_CTX *ctx,
  98. const UI_METHOD *ui_method, void *ui_data)
  99. {
  100. EVP_PKEY *pkey = NULL, *pubkey = NULL;
  101. OSSL_STORE_INFO *info = NULL;
  102. if (ctx->loaded == 0) {
  103. if (ENGINE_init(ctx->e)) {
  104. if (ctx->expected == 0
  105. || ctx->expected == OSSL_STORE_INFO_PKEY)
  106. pkey =
  107. ENGINE_load_private_key(ctx->e, ctx->keyid,
  108. (UI_METHOD *)ui_method, ui_data);
  109. if ((pkey == NULL && ctx->expected == 0)
  110. || ctx->expected == OSSL_STORE_INFO_PUBKEY)
  111. pubkey =
  112. ENGINE_load_public_key(ctx->e, ctx->keyid,
  113. (UI_METHOD *)ui_method, ui_data);
  114. ENGINE_finish(ctx->e);
  115. }
  116. }
  117. ctx->loaded = 1;
  118. if (pubkey != NULL)
  119. info = OSSL_STORE_INFO_new_PUBKEY(pubkey);
  120. else if (pkey != NULL)
  121. info = OSSL_STORE_INFO_new_PKEY(pkey);
  122. if (info == NULL) {
  123. EVP_PKEY_free(pkey);
  124. EVP_PKEY_free(pubkey);
  125. }
  126. return info;
  127. }
  128. static int engine_eof(OSSL_STORE_LOADER_CTX *ctx)
  129. {
  130. return ctx->loaded != 0;
  131. }
  132. static int engine_error(OSSL_STORE_LOADER_CTX *ctx)
  133. {
  134. return 0;
  135. }
  136. static int engine_close(OSSL_STORE_LOADER_CTX *ctx)
  137. {
  138. OSSL_STORE_LOADER_CTX_free(ctx);
  139. return 1;
  140. }
  141. int setup_engine_loader(void)
  142. {
  143. OSSL_STORE_LOADER *loader = NULL;
  144. if ((loader = OSSL_STORE_LOADER_new(NULL, ENGINE_SCHEME)) == NULL
  145. || !OSSL_STORE_LOADER_set_open(loader, engine_open)
  146. || !OSSL_STORE_LOADER_set_expect(loader, engine_expect)
  147. || !OSSL_STORE_LOADER_set_load(loader, engine_load)
  148. || !OSSL_STORE_LOADER_set_eof(loader, engine_eof)
  149. || !OSSL_STORE_LOADER_set_error(loader, engine_error)
  150. || !OSSL_STORE_LOADER_set_close(loader, engine_close)
  151. || !OSSL_STORE_register_loader(loader)) {
  152. OSSL_STORE_LOADER_free(loader);
  153. loader = NULL;
  154. }
  155. return loader != NULL;
  156. }
  157. void destroy_engine_loader(void)
  158. {
  159. OSSL_STORE_LOADER *loader = OSSL_STORE_unregister_loader(ENGINE_SCHEME);
  160. OSSL_STORE_LOADER_free(loader);
  161. }
  162. #else /* !OPENSSL_NO_ENGINE */
  163. int setup_engine_loader(void)
  164. {
  165. return 0;
  166. }
  167. void destroy_engine_loader(void)
  168. {
  169. }
  170. #endif