property_parse.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. /*
  2. * Copyright 2019 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 <stdio.h>
  12. #include <stdarg.h>
  13. #include <openssl/err.h>
  14. #include "internal/propertyerr.h"
  15. #include "internal/property.h"
  16. #include "crypto/ctype.h"
  17. #include "internal/nelem.h"
  18. #include "property_local.h"
  19. #include "e_os.h"
  20. typedef enum {
  21. PROPERTY_TYPE_STRING, PROPERTY_TYPE_NUMBER,
  22. PROPERTY_TYPE_VALUE_UNDEFINED
  23. } PROPERTY_TYPE;
  24. typedef enum {
  25. PROPERTY_OPER_EQ, PROPERTY_OPER_NE, PROPERTY_OVERRIDE
  26. } PROPERTY_OPER;
  27. typedef struct {
  28. OSSL_PROPERTY_IDX name_idx;
  29. PROPERTY_TYPE type;
  30. PROPERTY_OPER oper;
  31. unsigned int optional : 1;
  32. union {
  33. int64_t int_val; /* Signed integer */
  34. OSSL_PROPERTY_IDX str_val; /* String */
  35. } v;
  36. } PROPERTY_DEFINITION;
  37. struct ossl_property_list_st {
  38. int n;
  39. unsigned int has_optional : 1;
  40. PROPERTY_DEFINITION properties[1];
  41. };
  42. static OSSL_PROPERTY_IDX ossl_property_true, ossl_property_false;
  43. DEFINE_STACK_OF(PROPERTY_DEFINITION)
  44. static const char *skip_space(const char *s)
  45. {
  46. while (ossl_isspace(*s))
  47. s++;
  48. return s;
  49. }
  50. static int match_ch(const char *t[], char m)
  51. {
  52. const char *s = *t;
  53. if (*s == m) {
  54. *t = skip_space(s + 1);
  55. return 1;
  56. }
  57. return 0;
  58. }
  59. #define MATCH(s, m) match(s, m, sizeof(m) - 1)
  60. static int match(const char *t[], const char m[], size_t m_len)
  61. {
  62. const char *s = *t;
  63. if (strncasecmp(s, m, m_len) == 0) {
  64. *t = skip_space(s + m_len);
  65. return 1;
  66. }
  67. return 0;
  68. }
  69. static int parse_name(OPENSSL_CTX *ctx, const char *t[], int create,
  70. OSSL_PROPERTY_IDX *idx)
  71. {
  72. char name[100];
  73. int err = 0;
  74. size_t i = 0;
  75. const char *s = *t;
  76. int user_name = 0;
  77. for (;;) {
  78. if (!ossl_isalpha(*s)) {
  79. ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_IDENTIFIER,
  80. "HERE-->%s", *t);
  81. return 0;
  82. }
  83. do {
  84. if (i < sizeof(name) - 1)
  85. name[i++] = ossl_tolower(*s);
  86. else
  87. err = 1;
  88. } while (*++s == '_' || ossl_isalnum(*s));
  89. if (*s != '.')
  90. break;
  91. user_name = 1;
  92. if (i < sizeof(name) - 1)
  93. name[i++] = *s;
  94. else
  95. err = 1;
  96. s++;
  97. }
  98. name[i] = '\0';
  99. if (err) {
  100. ERR_raise_data(ERR_LIB_PROP, PROP_R_NAME_TOO_LONG, "HERE-->%s", *t);
  101. return 0;
  102. }
  103. *t = skip_space(s);
  104. *idx = ossl_property_name(ctx, name, user_name && create);
  105. return 1;
  106. }
  107. static int parse_number(const char *t[], PROPERTY_DEFINITION *res)
  108. {
  109. const char *s = *t;
  110. int64_t v = 0;
  111. if (!ossl_isdigit(*s))
  112. return 0;
  113. do {
  114. v = v * 10 + (*s++ - '0');
  115. } while (ossl_isdigit(*s));
  116. if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
  117. ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_A_DECIMAL_DIGIT,
  118. "HERE-->%s", *t);
  119. return 0;
  120. }
  121. *t = skip_space(s);
  122. res->type = PROPERTY_TYPE_NUMBER;
  123. res->v.int_val = v;
  124. return 1;
  125. }
  126. static int parse_hex(const char *t[], PROPERTY_DEFINITION *res)
  127. {
  128. const char *s = *t;
  129. int64_t v = 0;
  130. if (!ossl_isxdigit(*s))
  131. return 0;
  132. do {
  133. v <<= 4;
  134. if (ossl_isdigit(*s))
  135. v += *s - '0';
  136. else
  137. v += ossl_tolower(*s) - 'a';
  138. } while (ossl_isxdigit(*++s));
  139. if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
  140. ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_HEXADECIMAL_DIGIT,
  141. "HERE-->%s", *t);
  142. return 0;
  143. }
  144. *t = skip_space(s);
  145. res->type = PROPERTY_TYPE_NUMBER;
  146. res->v.int_val = v;
  147. return 1;
  148. }
  149. static int parse_oct(const char *t[], PROPERTY_DEFINITION *res)
  150. {
  151. const char *s = *t;
  152. int64_t v = 0;
  153. if (*s == '9' || *s == '8' || !ossl_isdigit(*s))
  154. return 0;
  155. do {
  156. v = (v << 3) + (*s - '0');
  157. } while (ossl_isdigit(*++s) && *s != '9' && *s != '8');
  158. if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
  159. ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_OCTAL_DIGIT,
  160. "HERE-->%s", *t);
  161. return 0;
  162. }
  163. *t = skip_space(s);
  164. res->type = PROPERTY_TYPE_NUMBER;
  165. res->v.int_val = v;
  166. return 1;
  167. }
  168. static int parse_string(OPENSSL_CTX *ctx, const char *t[], char delim,
  169. PROPERTY_DEFINITION *res, const int create)
  170. {
  171. char v[1000];
  172. const char *s = *t;
  173. size_t i = 0;
  174. int err = 0;
  175. while (*s != '\0' && *s != delim) {
  176. if (i < sizeof(v) - 1)
  177. v[i++] = *s;
  178. else
  179. err = 1;
  180. s++;
  181. }
  182. if (*s == '\0') {
  183. ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_MATCHING_STRING_DELIMETER,
  184. "HERE-->%c%s", delim, *t);
  185. return 0;
  186. }
  187. v[i] = '\0';
  188. if (err) {
  189. ERR_raise_data(ERR_LIB_PROP, PROP_R_STRING_TOO_LONG, "HERE-->%s", *t);
  190. } else {
  191. res->v.str_val = ossl_property_value(ctx, v, create);
  192. }
  193. *t = skip_space(s + 1);
  194. res->type = PROPERTY_TYPE_STRING;
  195. return !err;
  196. }
  197. static int parse_unquoted(OPENSSL_CTX *ctx, const char *t[],
  198. PROPERTY_DEFINITION *res, const int create)
  199. {
  200. char v[1000];
  201. const char *s = *t;
  202. size_t i = 0;
  203. int err = 0;
  204. if (*s == '\0' || *s == ',')
  205. return 0;
  206. while (ossl_isprint(*s) && !ossl_isspace(*s) && *s != ',') {
  207. if (i < sizeof(v) - 1)
  208. v[i++] = ossl_tolower(*s);
  209. else
  210. err = 1;
  211. s++;
  212. }
  213. if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
  214. ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_ASCII_CHARACTER,
  215. "HERE-->%s", s);
  216. return 0;
  217. }
  218. v[i] = 0;
  219. if (err) {
  220. ERR_raise_data(ERR_LIB_PROP, PROP_R_STRING_TOO_LONG, "HERE-->%s", *t);
  221. } else {
  222. res->v.str_val = ossl_property_value(ctx, v, create);
  223. }
  224. *t = skip_space(s);
  225. res->type = PROPERTY_TYPE_STRING;
  226. return !err;
  227. }
  228. static int parse_value(OPENSSL_CTX *ctx, const char *t[],
  229. PROPERTY_DEFINITION *res, int create)
  230. {
  231. const char *s = *t;
  232. int r = 0;
  233. if (*s == '"' || *s == '\'') {
  234. s++;
  235. r = parse_string(ctx, &s, s[-1], res, create);
  236. } else if (*s == '+') {
  237. s++;
  238. r = parse_number(&s, res);
  239. } else if (*s == '-') {
  240. s++;
  241. r = parse_number(&s, res);
  242. res->v.int_val = -res->v.int_val;
  243. } else if (*s == '0' && s[1] == 'x') {
  244. s += 2;
  245. r = parse_hex(&s, res);
  246. } else if (*s == '0' && ossl_isdigit(s[1])) {
  247. s++;
  248. r = parse_oct(&s, res);
  249. } else if (ossl_isdigit(*s)) {
  250. return parse_number(t, res);
  251. } else if (ossl_isalpha(*s))
  252. return parse_unquoted(ctx, t, res, create);
  253. if (r)
  254. *t = s;
  255. return r;
  256. }
  257. static int pd_compare(const PROPERTY_DEFINITION *const *p1,
  258. const PROPERTY_DEFINITION *const *p2)
  259. {
  260. const PROPERTY_DEFINITION *pd1 = *p1;
  261. const PROPERTY_DEFINITION *pd2 = *p2;
  262. if (pd1->name_idx < pd2->name_idx)
  263. return -1;
  264. if (pd1->name_idx > pd2->name_idx)
  265. return 1;
  266. return 0;
  267. }
  268. static void pd_free(PROPERTY_DEFINITION *pd)
  269. {
  270. OPENSSL_free(pd);
  271. }
  272. /*
  273. * Convert a stack of property definitions and queries into a fixed array.
  274. * The items are sorted for efficient query. The stack is not freed.
  275. */
  276. static OSSL_PROPERTY_LIST *stack_to_property_list(STACK_OF(PROPERTY_DEFINITION)
  277. *sk)
  278. {
  279. const int n = sk_PROPERTY_DEFINITION_num(sk);
  280. OSSL_PROPERTY_LIST *r;
  281. int i;
  282. r = OPENSSL_malloc(sizeof(*r)
  283. + (n <= 0 ? 0 : n - 1) * sizeof(r->properties[0]));
  284. if (r != NULL) {
  285. sk_PROPERTY_DEFINITION_sort(sk);
  286. r->has_optional = 0;
  287. for (i = 0; i < n; i++) {
  288. r->properties[i] = *sk_PROPERTY_DEFINITION_value(sk, i);
  289. r->has_optional |= r->properties[i].optional;
  290. }
  291. r->n = n;
  292. }
  293. return r;
  294. }
  295. OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn)
  296. {
  297. PROPERTY_DEFINITION *prop = NULL;
  298. OSSL_PROPERTY_LIST *res = NULL;
  299. STACK_OF(PROPERTY_DEFINITION) *sk;
  300. const char *s = defn;
  301. int done;
  302. if (s == NULL || (sk = sk_PROPERTY_DEFINITION_new(&pd_compare)) == NULL)
  303. return NULL;
  304. s = skip_space(s);
  305. done = *s == '\0';
  306. while (!done) {
  307. const char *start = s;
  308. prop = OPENSSL_malloc(sizeof(*prop));
  309. if (prop == NULL)
  310. goto err;
  311. memset(&prop->v, 0, sizeof(prop->v));
  312. prop->optional = 0;
  313. if (!parse_name(ctx, &s, 1, &prop->name_idx))
  314. goto err;
  315. prop->oper = PROPERTY_OPER_EQ;
  316. if (prop->name_idx == 0) {
  317. ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED,
  318. "Unknown name HERE-->%s", start);
  319. goto err;
  320. }
  321. if (match_ch(&s, '=')) {
  322. if (!parse_value(ctx, &s, prop, 1)) {
  323. ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_VALUE,
  324. "HERE-->%s", start);
  325. goto err;
  326. }
  327. } else {
  328. /* A name alone means a true Boolean */
  329. prop->type = PROPERTY_TYPE_STRING;
  330. prop->v.str_val = ossl_property_true;
  331. }
  332. if (!sk_PROPERTY_DEFINITION_push(sk, prop))
  333. goto err;
  334. prop = NULL;
  335. done = !match_ch(&s, ',');
  336. }
  337. if (*s != '\0') {
  338. ERR_raise_data(ERR_LIB_PROP, PROP_R_TRAILING_CHARACTERS,
  339. "HERE-->%s", s);
  340. goto err;
  341. }
  342. res = stack_to_property_list(sk);
  343. err:
  344. OPENSSL_free(prop);
  345. sk_PROPERTY_DEFINITION_pop_free(sk, &pd_free);
  346. return res;
  347. }
  348. OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s)
  349. {
  350. STACK_OF(PROPERTY_DEFINITION) *sk;
  351. OSSL_PROPERTY_LIST *res = NULL;
  352. PROPERTY_DEFINITION *prop = NULL;
  353. int done;
  354. if (s == NULL || (sk = sk_PROPERTY_DEFINITION_new(&pd_compare)) == NULL)
  355. return NULL;
  356. s = skip_space(s);
  357. done = *s == '\0';
  358. while (!done) {
  359. prop = OPENSSL_malloc(sizeof(*prop));
  360. if (prop == NULL)
  361. goto err;
  362. memset(&prop->v, 0, sizeof(prop->v));
  363. if (match_ch(&s, '-')) {
  364. prop->oper = PROPERTY_OVERRIDE;
  365. prop->optional = 0;
  366. if (!parse_name(ctx, &s, 0, &prop->name_idx))
  367. goto err;
  368. goto skip_value;
  369. }
  370. prop->optional = match_ch(&s, '?');
  371. if (!parse_name(ctx, &s, 0, &prop->name_idx))
  372. goto err;
  373. if (match_ch(&s, '=')) {
  374. prop->oper = PROPERTY_OPER_EQ;
  375. } else if (MATCH(&s, "!=")) {
  376. prop->oper = PROPERTY_OPER_NE;
  377. } else {
  378. /* A name alone is a Boolean comparison for true */
  379. prop->oper = PROPERTY_OPER_EQ;
  380. prop->type = PROPERTY_TYPE_STRING;
  381. prop->v.str_val = ossl_property_true;
  382. goto skip_value;
  383. }
  384. if (!parse_value(ctx, &s, prop, 0))
  385. prop->type = PROPERTY_TYPE_VALUE_UNDEFINED;
  386. skip_value:
  387. if (!sk_PROPERTY_DEFINITION_push(sk, prop))
  388. goto err;
  389. prop = NULL;
  390. done = !match_ch(&s, ',');
  391. }
  392. if (*s != '\0') {
  393. ERR_raise_data(ERR_LIB_PROP, PROP_R_TRAILING_CHARACTERS,
  394. "HERE-->%s", s);
  395. goto err;
  396. }
  397. res = stack_to_property_list(sk);
  398. err:
  399. OPENSSL_free(prop);
  400. sk_PROPERTY_DEFINITION_pop_free(sk, &pd_free);
  401. return res;
  402. }
  403. /* Does a property query have any optional clauses */
  404. int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query)
  405. {
  406. return query->has_optional ? 1 : 0;
  407. }
  408. /*
  409. * Compare a query against a definition.
  410. * Return the number of clauses matched or -1 if a mandatory clause is false.
  411. */
  412. int ossl_property_match_count(const OSSL_PROPERTY_LIST *query,
  413. const OSSL_PROPERTY_LIST *defn)
  414. {
  415. const PROPERTY_DEFINITION *const q = query->properties;
  416. const PROPERTY_DEFINITION *const d = defn->properties;
  417. int i = 0, j = 0, matches = 0;
  418. PROPERTY_OPER oper;
  419. while (i < query->n) {
  420. if ((oper = q[i].oper) == PROPERTY_OVERRIDE) {
  421. i++;
  422. continue;
  423. }
  424. if (j < defn->n) {
  425. if (q[i].name_idx > d[j].name_idx) { /* skip defn, not in query */
  426. j++;
  427. continue;
  428. }
  429. if (q[i].name_idx == d[j].name_idx) { /* both in defn and query */
  430. const int eq = q[i].type == d[j].type
  431. && memcmp(&q[i].v, &d[j].v, sizeof(q[i].v)) == 0;
  432. if ((eq && oper == PROPERTY_OPER_EQ)
  433. || (!eq && oper == PROPERTY_OPER_NE))
  434. matches++;
  435. else if (!q[i].optional)
  436. return -1;
  437. i++;
  438. j++;
  439. continue;
  440. }
  441. }
  442. /*
  443. * Handle the cases of a missing value and a query with no corresponding
  444. * definition. The former fails for any comparision except inequality,
  445. * the latter is treated as a comparison against the Boolean false.
  446. */
  447. if (q[i].type == PROPERTY_TYPE_VALUE_UNDEFINED) {
  448. if (oper == PROPERTY_OPER_NE)
  449. matches++;
  450. else if (!q[i].optional)
  451. return -1;
  452. } else if (q[i].type != PROPERTY_TYPE_STRING
  453. || (oper == PROPERTY_OPER_EQ
  454. && q[i].v.str_val != ossl_property_false)
  455. || (oper == PROPERTY_OPER_NE
  456. && q[i].v.str_val == ossl_property_false)) {
  457. if (!q[i].optional)
  458. return -1;
  459. } else {
  460. matches++;
  461. }
  462. i++;
  463. }
  464. return matches;
  465. }
  466. void ossl_property_free(OSSL_PROPERTY_LIST *p)
  467. {
  468. OPENSSL_free(p);
  469. }
  470. /*
  471. * Merge two property lists.
  472. * If there is a common name, the one from the first list is used.
  473. */
  474. OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a,
  475. const OSSL_PROPERTY_LIST *b)
  476. {
  477. const PROPERTY_DEFINITION *const ap = a->properties;
  478. const PROPERTY_DEFINITION *const bp = b->properties;
  479. const PROPERTY_DEFINITION *copy;
  480. OSSL_PROPERTY_LIST *r;
  481. int i, j, n;
  482. const int t = a->n + b->n;
  483. r = OPENSSL_malloc(sizeof(*r)
  484. + (t == 0 ? 0 : t - 1) * sizeof(r->properties[0]));
  485. if (r == NULL)
  486. return NULL;
  487. for (i = j = n = 0; i < a->n || j < b->n; n++) {
  488. if (i >= a->n) {
  489. copy = &bp[j++];
  490. } else if (j >= b->n) {
  491. copy = &ap[i++];
  492. } else if (ap[i].name_idx <= bp[j].name_idx) {
  493. if (ap[i].name_idx == bp[j].name_idx)
  494. j++;
  495. copy = &ap[i++];
  496. } else {
  497. copy = &bp[j++];
  498. }
  499. memcpy(r->properties + n, copy, sizeof(r->properties[0]));
  500. }
  501. r->n = n;
  502. if (n != t)
  503. r = OPENSSL_realloc(r, sizeof(*r) + (n - 1) * sizeof(r->properties[0]));
  504. return r;
  505. }
  506. int ossl_property_parse_init(OPENSSL_CTX *ctx)
  507. {
  508. static const char *const predefined_names[] = {
  509. "default", /* Being provided by the default built-in provider */
  510. "legacy", /* Provided by the legacy provider */
  511. "provider", /* Name of provider (default, fips) */
  512. "version", /* Version number of this provider */
  513. "fips", /* FIPS supporting provider */
  514. "engine", /* An old style engine masquerading as a provider */
  515. };
  516. size_t i;
  517. for (i = 0; i < OSSL_NELEM(predefined_names); i++)
  518. if (ossl_property_name(ctx, predefined_names[i], 1) == 0)
  519. goto err;
  520. /* Pre-populate the two Boolean values */
  521. if ((ossl_property_true = ossl_property_value(ctx, "yes", 1)) == 0
  522. || (ossl_property_false = ossl_property_value(ctx, "no", 1)) == 0)
  523. goto err;
  524. return 1;
  525. err:
  526. return 0;
  527. }