provider.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /*
  2. * Copyright 2018-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. #include "../testutil.h"
  10. #include <ctype.h>
  11. #include <openssl/provider.h>
  12. #include <openssl/core_names.h>
  13. #include <string.h>
  14. int test_get_libctx(OSSL_LIB_CTX **libctx, OSSL_PROVIDER **default_null_prov,
  15. const char *config_file,
  16. OSSL_PROVIDER **provider, const char *module_name)
  17. {
  18. OSSL_LIB_CTX *new_libctx = NULL;
  19. if (libctx != NULL) {
  20. if ((new_libctx = *libctx = OSSL_LIB_CTX_new()) == NULL) {
  21. opt_printf_stderr("Failed to create libctx\n");
  22. goto err;
  23. }
  24. }
  25. if (default_null_prov != NULL
  26. && (*default_null_prov = OSSL_PROVIDER_load(NULL, "null")) == NULL) {
  27. opt_printf_stderr("Failed to load null provider into default libctx\n");
  28. goto err;
  29. }
  30. if (config_file != NULL
  31. && !OSSL_LIB_CTX_load_config(new_libctx, config_file)) {
  32. opt_printf_stderr("Error loading config from file %s\n", config_file);
  33. goto err;
  34. }
  35. if (provider != NULL && module_name != NULL
  36. && (*provider = OSSL_PROVIDER_load(new_libctx, module_name)) == NULL) {
  37. opt_printf_stderr("Failed to load provider %s\n", module_name);
  38. goto err;
  39. }
  40. return 1;
  41. err:
  42. ERR_print_errors_fp(stderr);
  43. return 0;
  44. }
  45. int test_arg_libctx(OSSL_LIB_CTX **libctx, OSSL_PROVIDER **default_null_prov,
  46. OSSL_PROVIDER **provider, int argn, const char *usage)
  47. {
  48. const char *module_name;
  49. if (!TEST_ptr(module_name = test_get_argument(argn))) {
  50. TEST_error("usage: <prog> %s", usage);
  51. return 0;
  52. }
  53. if (strcmp(module_name, "none") == 0)
  54. return 1;
  55. return test_get_libctx(libctx, default_null_prov,
  56. test_get_argument(argn + 1), provider, module_name);
  57. }
  58. typedef struct {
  59. int major, minor, patch;
  60. } FIPS_VERSION;
  61. /*
  62. * Query the FIPS provider to determine it's version number.
  63. * Returns 1 if the version is retrieved correctly, 0 if the FIPS provider isn't
  64. * loaded and -1 on error.
  65. */
  66. static int fips_provider_version(OSSL_LIB_CTX *libctx, FIPS_VERSION *vers)
  67. {
  68. OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
  69. OSSL_PROVIDER *fips_prov;
  70. char *vs;
  71. if (!OSSL_PROVIDER_available(libctx, "fips"))
  72. return 0;
  73. *params = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION, &vs, 0);
  74. if ((fips_prov = OSSL_PROVIDER_load(libctx, "fips")) == NULL)
  75. return -1;
  76. if (!OSSL_PROVIDER_get_params(fips_prov, params)
  77. || sscanf(vs, "%d.%d.%d", &vers->major, &vers->minor, &vers->patch) != 3)
  78. goto err;
  79. if (!OSSL_PROVIDER_unload(fips_prov))
  80. return -1;
  81. return 1;
  82. err:
  83. OSSL_PROVIDER_unload(fips_prov);
  84. return -1;
  85. }
  86. int fips_provider_version_eq(OSSL_LIB_CTX *libctx, int major, int minor, int patch)
  87. {
  88. FIPS_VERSION prov;
  89. int res;
  90. if ((res = fips_provider_version(libctx, &prov)) <= 0)
  91. return res == 0;
  92. return major == prov.major && minor == prov.minor && patch == prov.patch;
  93. }
  94. int fips_provider_version_ne(OSSL_LIB_CTX *libctx, int major, int minor, int patch)
  95. {
  96. FIPS_VERSION prov;
  97. int res;
  98. if ((res = fips_provider_version(libctx, &prov)) <= 0)
  99. return res == 0;
  100. return major != prov.major || minor != prov.minor || patch != prov.patch;
  101. }
  102. int fips_provider_version_le(OSSL_LIB_CTX *libctx, int major, int minor, int patch)
  103. {
  104. FIPS_VERSION prov;
  105. int res;
  106. if ((res = fips_provider_version(libctx, &prov)) <= 0)
  107. return res == 0;
  108. return prov.major < major
  109. || (prov.major == major
  110. && (prov.minor < minor
  111. || (prov.minor == minor && prov.patch <= patch)));
  112. }
  113. int fips_provider_version_lt(OSSL_LIB_CTX *libctx, int major, int minor, int patch)
  114. {
  115. FIPS_VERSION prov;
  116. int res;
  117. if ((res = fips_provider_version(libctx, &prov)) <= 0)
  118. return res == 0;
  119. return prov.major < major
  120. || (prov.major == major
  121. && (prov.minor < minor
  122. || (prov.minor == minor && prov.patch < patch)));
  123. }
  124. int fips_provider_version_gt(OSSL_LIB_CTX *libctx, int major, int minor, int patch)
  125. {
  126. FIPS_VERSION prov;
  127. int res;
  128. if ((res = fips_provider_version(libctx, &prov)) <= 0)
  129. return res == 0;
  130. return prov.major > major
  131. || (prov.major == major
  132. && (prov.minor > minor
  133. || (prov.minor == minor && prov.patch > patch)));
  134. }
  135. int fips_provider_version_ge(OSSL_LIB_CTX *libctx, int major, int minor, int patch)
  136. {
  137. FIPS_VERSION prov;
  138. int res;
  139. if ((res = fips_provider_version(libctx, &prov)) <= 0)
  140. return res == 0;
  141. return prov.major > major
  142. || (prov.major == major
  143. && (prov.minor > minor
  144. || (prov.minor == minor && prov.patch >= patch)));
  145. }
  146. int fips_provider_version_match(OSSL_LIB_CTX *libctx, const char *versions)
  147. {
  148. const char *p;
  149. int major, minor, patch, r;
  150. enum {
  151. MODE_EQ, MODE_NE, MODE_LE, MODE_LT, MODE_GT, MODE_GE
  152. } mode;
  153. while (*versions != '\0') {
  154. for (; isspace((unsigned char)(*versions)); versions++)
  155. continue;
  156. if (*versions == '\0')
  157. break;
  158. for (p = versions; *versions != '\0' && !isspace((unsigned char)(*versions)); versions++)
  159. continue;
  160. if (*p == '!') {
  161. mode = MODE_NE;
  162. p++;
  163. } else if (*p == '=') {
  164. mode = MODE_EQ;
  165. p++;
  166. } else if (*p == '<' && p[1] == '=') {
  167. mode = MODE_LE;
  168. p += 2;
  169. } else if (*p == '>' && p[1] == '=') {
  170. mode = MODE_GE;
  171. p += 2;
  172. } else if (*p == '<') {
  173. mode = MODE_LT;
  174. p++;
  175. } else if (*p == '>') {
  176. mode = MODE_GT;
  177. p++;
  178. } else if (isdigit((unsigned char)*p)) {
  179. mode = MODE_EQ;
  180. } else {
  181. TEST_info("Error matching FIPS version: mode %s\n", p);
  182. return -1;
  183. }
  184. if (sscanf(p, "%d.%d.%d", &major, &minor, &patch) != 3) {
  185. TEST_info("Error matching FIPS version: version %s\n", p);
  186. return -1;
  187. }
  188. switch (mode) {
  189. case MODE_EQ:
  190. r = fips_provider_version_eq(libctx, major, minor, patch);
  191. break;
  192. case MODE_NE:
  193. r = fips_provider_version_ne(libctx, major, minor, patch);
  194. break;
  195. case MODE_LE:
  196. r = fips_provider_version_le(libctx, major, minor, patch);
  197. break;
  198. case MODE_LT:
  199. r = fips_provider_version_lt(libctx, major, minor, patch);
  200. break;
  201. case MODE_GT:
  202. r = fips_provider_version_gt(libctx, major, minor, patch);
  203. break;
  204. case MODE_GE:
  205. r = fips_provider_version_ge(libctx, major, minor, patch);
  206. break;
  207. }
  208. if (r < 0) {
  209. TEST_info("Error matching FIPS version: internal error\n");
  210. return -1;
  211. }
  212. if (r == 0)
  213. return 0;
  214. }
  215. return 1;
  216. }