file_store_any2obj.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*
  2. * Copyright 2020-2023 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. * This is a decoder that's completely internal to the 'file:' store
  11. * implementation. Only code in file_store.c know about this one. Because
  12. * of this close relationship, we can cut certain corners, such as making
  13. * assumptions about the "provider context", which is currently simply the
  14. * provider context that the file_store.c code operates within.
  15. *
  16. * All this does is to read known binary encodings (currently: DER, MSBLOB,
  17. * PVK) from the input if it can, and passes it on to the data callback as
  18. * an object abstraction, leaving it to the callback to figure out what it
  19. * actually is.
  20. *
  21. * This MUST be made the last decoder in a chain, leaving it to other more
  22. * specialized decoders to recognise and process their stuff first.
  23. */
  24. #include <openssl/core_dispatch.h>
  25. #include <openssl/core_names.h>
  26. #include <openssl/core_object.h>
  27. #include <openssl/bio.h>
  28. #include <openssl/buffer.h>
  29. #include <openssl/err.h>
  30. #include <openssl/asn1err.h>
  31. #include <openssl/params.h>
  32. #include "internal/asn1.h"
  33. #include "crypto/pem.h" /* For internal PVK and "blob" headers */
  34. #include "prov/bio.h"
  35. #include "file_store_local.h"
  36. /*
  37. * newctx and freectx are not strictly necessary. However, the method creator,
  38. * ossl_decoder_from_algorithm(), demands that they exist, so we make sure to
  39. * oblige.
  40. */
  41. static OSSL_FUNC_decoder_newctx_fn any2obj_newctx;
  42. static OSSL_FUNC_decoder_freectx_fn any2obj_freectx;
  43. static void *any2obj_newctx(void *provctx)
  44. {
  45. return provctx;
  46. }
  47. static void any2obj_freectx(void *vctx)
  48. {
  49. }
  50. static int any2obj_decode_final(void *provctx, int objtype, BUF_MEM *mem,
  51. OSSL_CALLBACK *data_cb, void *data_cbarg)
  52. {
  53. /*
  54. * 1 indicates that we successfully decoded something, or not at all.
  55. * Ending up "empty handed" is not an error.
  56. */
  57. int ok = 1;
  58. if (mem != NULL) {
  59. OSSL_PARAM params[3];
  60. params[0] =
  61. OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &objtype);
  62. params[1] =
  63. OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA,
  64. mem->data, mem->length);
  65. params[2] = OSSL_PARAM_construct_end();
  66. ok = data_cb(params, data_cbarg);
  67. BUF_MEM_free(mem);
  68. }
  69. return ok;
  70. }
  71. static OSSL_FUNC_decoder_decode_fn der2obj_decode;
  72. static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
  73. OSSL_CALLBACK *data_cb, void *data_cbarg,
  74. OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
  75. {
  76. BIO *in = ossl_bio_new_from_core_bio(provctx, cin);
  77. BUF_MEM *mem = NULL;
  78. int ok;
  79. if (in == NULL)
  80. return 0;
  81. ERR_set_mark();
  82. ok = (asn1_d2i_read_bio(in, &mem) >= 0);
  83. ERR_pop_to_mark();
  84. if (!ok && mem != NULL) {
  85. BUF_MEM_free(mem);
  86. mem = NULL;
  87. }
  88. BIO_free(in);
  89. /* any2obj_decode_final() frees |mem| for us */
  90. return any2obj_decode_final(provctx, OSSL_OBJECT_UNKNOWN, mem,
  91. data_cb, data_cbarg);
  92. }
  93. static OSSL_FUNC_decoder_decode_fn msblob2obj_decode;
  94. static int msblob2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
  95. OSSL_CALLBACK *data_cb, void *data_cbarg,
  96. OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
  97. {
  98. BIO *in = ossl_bio_new_from_core_bio(provctx, cin);
  99. BUF_MEM *mem = NULL;
  100. size_t mem_len = 0, mem_want;
  101. const unsigned char *p;
  102. unsigned int bitlen, magic;
  103. int isdss = -1;
  104. int ispub = -1;
  105. int ok = 0;
  106. if (in == NULL)
  107. goto err;
  108. mem_want = 16; /* The size of the MSBLOB header */
  109. if ((mem = BUF_MEM_new()) == NULL
  110. || !BUF_MEM_grow(mem, mem_want)) {
  111. ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB);
  112. goto err;
  113. }
  114. ERR_set_mark();
  115. ok = BIO_read(in, &mem->data[0], mem_want) == (int)mem_want;
  116. mem_len += mem_want;
  117. ERR_pop_to_mark();
  118. if (!ok)
  119. goto next;
  120. ERR_set_mark();
  121. p = (unsigned char *)&mem->data[0];
  122. ok = ossl_do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) > 0;
  123. ERR_pop_to_mark();
  124. if (!ok)
  125. goto next;
  126. ok = 0;
  127. mem_want = ossl_blob_length(bitlen, isdss, ispub);
  128. if (!BUF_MEM_grow(mem, mem_len + mem_want)) {
  129. ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB);
  130. goto err;
  131. }
  132. ERR_set_mark();
  133. ok = BIO_read(in, &mem->data[mem_len], mem_want) == (int)mem_want;
  134. mem_len += mem_want;
  135. ERR_pop_to_mark();
  136. next:
  137. /* Free resources we no longer need. */
  138. BIO_free(in);
  139. if (!ok && mem != NULL) {
  140. BUF_MEM_free(mem);
  141. mem = NULL;
  142. }
  143. /* any2obj_decode_final() frees |mem| for us */
  144. return any2obj_decode_final(provctx, OSSL_OBJECT_PKEY, mem,
  145. data_cb, data_cbarg);
  146. err:
  147. BIO_free(in);
  148. BUF_MEM_free(mem);
  149. return 0;
  150. }
  151. static OSSL_FUNC_decoder_decode_fn pvk2obj_decode;
  152. static int pvk2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
  153. OSSL_CALLBACK *data_cb, void *data_cbarg,
  154. OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
  155. {
  156. BIO *in = ossl_bio_new_from_core_bio(provctx, cin);
  157. BUF_MEM *mem = NULL;
  158. size_t mem_len = 0, mem_want;
  159. const unsigned char *p;
  160. unsigned int saltlen, keylen;
  161. int ok = 0;
  162. if (in == NULL)
  163. goto err;
  164. mem_want = 24; /* The size of the PVK header */
  165. if ((mem = BUF_MEM_new()) == NULL
  166. || !BUF_MEM_grow(mem, mem_want)) {
  167. ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB);
  168. goto err;
  169. }
  170. ERR_set_mark();
  171. ok = BIO_read(in, &mem->data[0], mem_want) == (int)mem_want;
  172. mem_len += mem_want;
  173. ERR_pop_to_mark();
  174. if (!ok)
  175. goto next;
  176. ERR_set_mark();
  177. p = (unsigned char *)&mem->data[0];
  178. ok = ossl_do_PVK_header(&p, 24, 0, &saltlen, &keylen) > 0;
  179. ERR_pop_to_mark();
  180. if (!ok)
  181. goto next;
  182. ok = 0;
  183. mem_want = saltlen + keylen;
  184. if (!BUF_MEM_grow(mem, mem_len + mem_want)) {
  185. ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB);
  186. goto err;
  187. }
  188. ERR_set_mark();
  189. ok = BIO_read(in, &mem->data[mem_len], mem_want) == (int)mem_want;
  190. mem_len += mem_want;
  191. ERR_pop_to_mark();
  192. next:
  193. /* Free resources we no longer need. */
  194. BIO_free(in);
  195. if (!ok && mem != NULL) {
  196. BUF_MEM_free(mem);
  197. mem = NULL;
  198. }
  199. /* any2obj_decode_final() frees |mem| for us */
  200. return any2obj_decode_final(provctx, OSSL_OBJECT_PKEY, mem,
  201. data_cb, data_cbarg);
  202. err:
  203. BIO_free(in);
  204. BUF_MEM_free(mem);
  205. return 0;
  206. }
  207. #define MAKE_DECODER(fromtype, objtype) \
  208. static const OSSL_DISPATCH fromtype##_to_obj_decoder_functions[] = { \
  209. { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))any2obj_newctx }, \
  210. { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))any2obj_freectx }, \
  211. { OSSL_FUNC_DECODER_DECODE, (void (*)(void))fromtype##2obj_decode }, \
  212. OSSL_DISPATCH_END \
  213. }
  214. MAKE_DECODER(der, OSSL_OBJECT_UNKNOWN);
  215. MAKE_DECODER(msblob, OSSL_OBJECT_PKEY);
  216. MAKE_DECODER(pvk, OSSL_OBJECT_PKEY);
  217. const OSSL_ALGORITHM ossl_any_to_obj_algorithm[] = {
  218. { "obj", "input=DER", der_to_obj_decoder_functions },
  219. { "obj", "input=MSBLOB", msblob_to_obj_decoder_functions },
  220. { "obj", "input=PVK", pvk_to_obj_decoder_functions },
  221. { NULL, }
  222. };