params_conversion_test.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /*
  2. * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
  3. * Copyright (c) 2019, 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. #include <string.h>
  11. #include <openssl/params.h>
  12. #include "testutil.h"
  13. /* On machines that dont support <inttypes.h> just disable the tests */
  14. #if !defined(OPENSSL_NO_INTTYPES_H)
  15. # ifdef OPENSSL_SYS_WINDOWS
  16. # define strcasecmp _stricmp
  17. # endif
  18. # ifdef OPENSSL_SYS_VMS
  19. # define strtoumax strtoull
  20. # define strtoimax strtoll
  21. # endif
  22. typedef struct {
  23. OSSL_PARAM *param;
  24. int32_t i32;
  25. int64_t i64;
  26. uint32_t u32;
  27. uint64_t u64;
  28. double d;
  29. int valid_i32, valid_i64, valid_u32, valid_u64, valid_d;
  30. void *ref, *datum;
  31. size_t size;
  32. } PARAM_CONVERSION;
  33. static int param_conversion_load_stanza(PARAM_CONVERSION *pc, const STANZA *s)
  34. {
  35. static int32_t datum_i32, ref_i32;
  36. static int64_t datum_i64, ref_i64;
  37. static uint32_t datum_u32, ref_u32;
  38. static uint64_t datum_u64, ref_u64;
  39. static double datum_d, ref_d;
  40. static OSSL_PARAM params[] = {
  41. OSSL_PARAM_int32("int32", &datum_i32),
  42. OSSL_PARAM_int64("int64", &datum_i64),
  43. OSSL_PARAM_uint32("uint32", &datum_u32),
  44. OSSL_PARAM_uint64("uint64", &datum_u64),
  45. OSSL_PARAM_double("double", &datum_d),
  46. OSSL_PARAM_END
  47. };
  48. int def_i32 = 0, def_i64 = 0, def_u32 = 0, def_u64 = 0, def_d = 0;
  49. const PAIR *pp = s->pairs;
  50. const char *type = NULL;
  51. char *p;
  52. int i;
  53. memset(pc, 0, sizeof(*pc));
  54. for (i = 0; i < s->numpairs; i++, pp++) {
  55. p = "";
  56. if (strcasecmp(pp->key, "type") == 0) {
  57. if (type != NULL) {
  58. TEST_info("Line %d: multiple type lines", s->curr);
  59. return 0;
  60. }
  61. pc->param = OSSL_PARAM_locate(params, type = pp->value);
  62. if (pc->param == NULL) {
  63. TEST_info("Line %d: unknown type line", s->curr);
  64. return 0;
  65. }
  66. } else if (strcasecmp(pp->key, "int32") == 0) {
  67. if (def_i32++) {
  68. TEST_info("Line %d: multiple int32 lines", s->curr);
  69. return 0;
  70. }
  71. if (strcasecmp(pp->value, "invalid") != 0) {
  72. pc->valid_i32 = 1;
  73. pc->i32 = (int32_t)strtoimax(pp->value, &p, 10);
  74. }
  75. } else if (strcasecmp(pp->key, "int64") == 0) {
  76. if (def_i64++) {
  77. TEST_info("Line %d: multiple int64 lines", s->curr);
  78. return 0;
  79. }
  80. if (strcasecmp(pp->value, "invalid") != 0) {
  81. pc->valid_i64 = 1;
  82. pc->i64 = (int64_t)strtoimax(pp->value, &p, 10);
  83. }
  84. } else if (strcasecmp(pp->key, "uint32") == 0) {
  85. if (def_u32++) {
  86. TEST_info("Line %d: multiple uint32 lines", s->curr);
  87. return 0;
  88. }
  89. if (strcasecmp(pp->value, "invalid") != 0) {
  90. pc->valid_u32 = 1;
  91. pc->u32 = (uint32_t)strtoumax(pp->value, &p, 10);
  92. }
  93. } else if (strcasecmp(pp->key, "uint64") == 0) {
  94. if (def_u64++) {
  95. TEST_info("Line %d: multiple uint64 lines", s->curr);
  96. return 0;
  97. }
  98. if (strcasecmp(pp->value, "invalid") != 0) {
  99. pc->valid_u64 = 1;
  100. pc->u64 = (uint64_t)strtoumax(pp->value, &p, 10);
  101. }
  102. } else if (strcasecmp(pp->key, "double") == 0) {
  103. if (def_d++) {
  104. TEST_info("Line %d: multiple double lines", s->curr);
  105. return 0;
  106. }
  107. if (strcasecmp(pp->value, "invalid") != 0) {
  108. pc->valid_d = 1;
  109. pc->d = strtod(pp->value, &p);
  110. }
  111. } else {
  112. TEST_info("Line %d: unknown keyword %s", s->curr, pp->key);
  113. return 0;
  114. }
  115. if (*p != '\0') {
  116. TEST_info("Line %d: extra characters at end '%s' for %s",
  117. s->curr, p, pp->key);
  118. return 0;
  119. }
  120. }
  121. if (!TEST_ptr(type)) {
  122. TEST_info("Line %d: type not found", s->curr);
  123. return 0;
  124. }
  125. if (strcasecmp(type, "int32") == 0) {
  126. if (!TEST_true(def_i32) || !TEST_true(pc->valid_i32)) {
  127. TEST_note("errant int32 on line %d", s->curr);
  128. return 0;
  129. }
  130. datum_i32 = ref_i32 = pc->i32;
  131. pc->datum = &datum_i32;
  132. pc->ref = &ref_i32;
  133. pc->size = sizeof(ref_i32);
  134. } else if (strcasecmp(type, "int64") == 0) {
  135. if (!TEST_true(def_i64) || !TEST_true(pc->valid_i64)) {
  136. TEST_note("errant int64 on line %d", s->curr);
  137. return 0;
  138. }
  139. datum_i64 = ref_i64 = pc->i64;
  140. pc->datum = &datum_i64;
  141. pc->ref = &ref_i64;
  142. pc->size = sizeof(ref_i64);
  143. } else if (strcasecmp(type, "uint32") == 0) {
  144. if (!TEST_true(def_u32) || !TEST_true(pc->valid_u32)) {
  145. TEST_note("errant uint32 on line %d", s->curr);
  146. return 0;
  147. }
  148. datum_u32 = ref_u32 = pc->u32;
  149. pc->datum = &datum_u32;
  150. pc->ref = &ref_u32;
  151. pc->size = sizeof(ref_u32);
  152. } else if (strcasecmp(type, "uint64") == 0) {
  153. if (!TEST_true(def_u64) || !TEST_true(pc->valid_u64)) {
  154. TEST_note("errant uint64 on line %d", s->curr);
  155. return 0;
  156. }
  157. datum_u64 = ref_u64 = pc->u64;
  158. pc->datum = &datum_u64;
  159. pc->ref = &ref_u64;
  160. pc->size = sizeof(ref_u64);
  161. } else if (strcasecmp(type, "double") == 0) {
  162. if (!TEST_true(def_d) || !TEST_true(pc->valid_d)) {
  163. TEST_note("errant double on line %d", s->curr);
  164. return 0;
  165. }
  166. datum_d = ref_d = pc->d;
  167. pc->datum = &datum_d;
  168. pc->ref = &ref_d;
  169. pc->size = sizeof(ref_d);
  170. } else {
  171. TEST_error("type unknown at line %d", s->curr);
  172. return 0;
  173. }
  174. return 1;
  175. }
  176. static int param_conversion_test(const PARAM_CONVERSION *pc, int line)
  177. {
  178. int32_t i32;
  179. int64_t i64;
  180. uint32_t u32;
  181. uint64_t u64;
  182. double d;
  183. if (!pc->valid_i32) {
  184. if (!TEST_false(OSSL_PARAM_get_int32(pc->param, &i32))) {
  185. TEST_note("unexpected valid conversion to int32 on line %d", line);
  186. return 0;
  187. }
  188. } else {
  189. if (!TEST_true(OSSL_PARAM_get_int32(pc->param, &i32))
  190. || !TEST_true(i32 == pc->i32)) {
  191. TEST_note("unexpected conversion to int32 on line %d", line);
  192. return 0;
  193. }
  194. memset(pc->datum, 44, pc->size);
  195. if (!TEST_true(OSSL_PARAM_set_int32(pc->param, i32))
  196. || !TEST_mem_eq(pc->datum, pc->size, pc->ref, pc->size)) {
  197. TEST_note("unexpected valid conversion from int32 on line %d",
  198. line);
  199. return 0;
  200. }
  201. }
  202. if (!pc->valid_i64) {
  203. if (!TEST_false(OSSL_PARAM_get_int64(pc->param, &i64))) {
  204. TEST_note("unexpected valid conversion to int64 on line %d", line);
  205. return 0;
  206. }
  207. } else {
  208. if (!TEST_true(OSSL_PARAM_get_int64(pc->param, &i64))
  209. || !TEST_true(i64 == pc->i64)) {
  210. TEST_note("unexpected conversion to int64 on line %d", line);
  211. return 0;
  212. }
  213. memset(pc->datum, 44, pc->size);
  214. if (!TEST_true(OSSL_PARAM_set_int64(pc->param, i64))
  215. || !TEST_mem_eq(pc->datum, pc->size, pc->ref, pc->size)) {
  216. TEST_note("unexpected valid conversion from int64 on line %d",
  217. line);
  218. return 0;
  219. }
  220. }
  221. if (!pc->valid_u32) {
  222. if (!TEST_false(OSSL_PARAM_get_uint32(pc->param, &u32))) {
  223. TEST_note("unexpected valid conversion to uint32 on line %d", line);
  224. return 0;
  225. }
  226. } else {
  227. if (!TEST_true(OSSL_PARAM_get_uint32(pc->param, &u32))
  228. || !TEST_true(u32 == pc->u32)) {
  229. TEST_note("unexpected conversion to uint32 on line %d", line);
  230. return 0;
  231. }
  232. memset(pc->datum, 44, pc->size);
  233. if (!TEST_true(OSSL_PARAM_set_uint32(pc->param, u32))
  234. || !TEST_mem_eq(pc->datum, pc->size, pc->ref, pc->size)) {
  235. TEST_note("unexpected valid conversion from uint32 on line %d",
  236. line);
  237. return 0;
  238. }
  239. }
  240. if (!pc->valid_u64) {
  241. if (!TEST_false(OSSL_PARAM_get_uint64(pc->param, &u64))) {
  242. TEST_note("unexpected valid conversion to uint64 on line %d", line);
  243. return 0;
  244. }
  245. } else {
  246. if (!TEST_true(OSSL_PARAM_get_uint64(pc->param, &u64))
  247. || !TEST_true(u64 == pc->u64)) {
  248. TEST_note("unexpected conversion to uint64 on line %d", line);
  249. return 0;
  250. }
  251. memset(pc->datum, 44, pc->size);
  252. if (!TEST_true(OSSL_PARAM_set_uint64(pc->param, u64))
  253. || !TEST_mem_eq(pc->datum, pc->size, pc->ref, pc->size)) {
  254. TEST_note("unexpected valid conversion from uint64 on line %d",
  255. line);
  256. return 0;
  257. }
  258. }
  259. if (!pc->valid_d) {
  260. if (!TEST_false(OSSL_PARAM_get_double(pc->param, &d))) {
  261. TEST_note("unexpected valid conversion to double on line %d", line);
  262. return 0;
  263. }
  264. } else {
  265. if (!TEST_true(OSSL_PARAM_get_double(pc->param, &d))
  266. || !TEST_true(d == pc->d)) {
  267. TEST_note("unexpected conversion to double on line %d", line);
  268. return 0;
  269. }
  270. memset(pc->datum, 44, pc->size);
  271. if (!TEST_true(OSSL_PARAM_set_double(pc->param, d))
  272. || !TEST_mem_eq(pc->datum, pc->size, pc->ref, pc->size)) {
  273. TEST_note("unexpected valid conversion from double on line %d",
  274. line);
  275. return 0;
  276. }
  277. }
  278. return 1;
  279. }
  280. static int run_param_file_tests(int i)
  281. {
  282. STANZA *s;
  283. PARAM_CONVERSION pc;
  284. const char *testfile = test_get_argument(i);
  285. int res = 1;
  286. if (!TEST_ptr(s = OPENSSL_zalloc(sizeof(*s))))
  287. return 0;
  288. if (!test_start_file(s, testfile)) {
  289. OPENSSL_free(s);
  290. return 0;
  291. }
  292. while (!BIO_eof(s->fp)) {
  293. if (!test_readstanza(s)) {
  294. res = 0;
  295. goto end;
  296. }
  297. if (s->numpairs != 0)
  298. if (!param_conversion_load_stanza(&pc, s)
  299. || !param_conversion_test(&pc, s->curr))
  300. res = 0;
  301. test_clearstanza(s);
  302. }
  303. end:
  304. test_end_file(s);
  305. OPENSSL_free(s);
  306. return res;
  307. }
  308. #endif /* OPENSSL_NO_INTTYPES_H */
  309. OPT_TEST_DECLARE_USAGE("file...\n")
  310. int setup_tests(void)
  311. {
  312. size_t n;
  313. if (!test_skip_common_options()) {
  314. TEST_error("Error parsing test options\n");
  315. return 0;
  316. }
  317. n = test_get_argument_count();
  318. if (n == 0)
  319. return 0;
  320. #if !defined(OPENSSL_NO_INTTYPES_H)
  321. ADD_ALL_TESTS(run_param_file_tests, n);
  322. #endif /* OPENSSL_NO_INTTYPES_H */
  323. return 1;
  324. }