v3_utl.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273
  1. /*
  2. * Copyright 1999-2021 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. /* X509 v3 extension utilities */
  10. #include "e_os.h"
  11. #include "internal/cryptlib.h"
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include "crypto/ctype.h"
  15. #include <openssl/conf.h>
  16. #include <openssl/crypto.h>
  17. #include <openssl/x509v3.h>
  18. #include "crypto/x509.h"
  19. #include <openssl/bn.h>
  20. #include "ext_dat.h"
  21. static char *strip_spaces(char *name);
  22. static int sk_strcmp(const char *const *a, const char *const *b);
  23. static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
  24. GENERAL_NAMES *gens);
  25. static void str_free(OPENSSL_STRING str);
  26. static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email);
  27. static int ipv4_from_asc(unsigned char *v4, const char *in);
  28. static int ipv6_from_asc(unsigned char *v6, const char *in);
  29. static int ipv6_cb(const char *elem, int len, void *usr);
  30. static int ipv6_hex(unsigned char *out, const char *in, int inlen);
  31. /* Add a CONF_VALUE name value pair to stack */
  32. static int x509v3_add_len_value(const char *name, const char *value,
  33. size_t vallen, STACK_OF(CONF_VALUE) **extlist)
  34. {
  35. CONF_VALUE *vtmp = NULL;
  36. char *tname = NULL, *tvalue = NULL;
  37. int sk_allocated = (*extlist == NULL);
  38. if (name != NULL && (tname = OPENSSL_strdup(name)) == NULL)
  39. goto err;
  40. if (value != NULL && vallen > 0) {
  41. /*
  42. * We tolerate a single trailing NUL character, but otherwise no
  43. * embedded NULs
  44. */
  45. if (memchr(value, 0, vallen - 1) != NULL)
  46. goto err;
  47. tvalue = OPENSSL_strndup(value, vallen);
  48. if (tvalue == NULL)
  49. goto err;
  50. }
  51. if ((vtmp = OPENSSL_malloc(sizeof(*vtmp))) == NULL)
  52. goto err;
  53. if (sk_allocated && (*extlist = sk_CONF_VALUE_new_null()) == NULL)
  54. goto err;
  55. vtmp->section = NULL;
  56. vtmp->name = tname;
  57. vtmp->value = tvalue;
  58. if (!sk_CONF_VALUE_push(*extlist, vtmp))
  59. goto err;
  60. return 1;
  61. err:
  62. X509V3err(X509V3_F_X509V3_ADD_LEN_VALUE, ERR_R_MALLOC_FAILURE);
  63. if (sk_allocated) {
  64. sk_CONF_VALUE_free(*extlist);
  65. *extlist = NULL;
  66. }
  67. OPENSSL_free(vtmp);
  68. OPENSSL_free(tname);
  69. OPENSSL_free(tvalue);
  70. return 0;
  71. }
  72. int X509V3_add_value(const char *name, const char *value,
  73. STACK_OF(CONF_VALUE) **extlist)
  74. {
  75. return x509v3_add_len_value(name, value,
  76. value != NULL ? strlen((const char *)value) : 0,
  77. extlist);
  78. }
  79. int X509V3_add_value_uchar(const char *name, const unsigned char *value,
  80. STACK_OF(CONF_VALUE) **extlist)
  81. {
  82. return x509v3_add_len_value(name, (const char *)value,
  83. value != NULL ? strlen((const char *)value) : 0,
  84. extlist);
  85. }
  86. int x509v3_add_len_value_uchar(const char *name, const unsigned char *value,
  87. size_t vallen, STACK_OF(CONF_VALUE) **extlist)
  88. {
  89. return x509v3_add_len_value(name, (const char *)value, vallen, extlist);
  90. }
  91. /* Free function for STACK_OF(CONF_VALUE) */
  92. void X509V3_conf_free(CONF_VALUE *conf)
  93. {
  94. if (!conf)
  95. return;
  96. OPENSSL_free(conf->name);
  97. OPENSSL_free(conf->value);
  98. OPENSSL_free(conf->section);
  99. OPENSSL_free(conf);
  100. }
  101. int X509V3_add_value_bool(const char *name, int asn1_bool,
  102. STACK_OF(CONF_VALUE) **extlist)
  103. {
  104. if (asn1_bool)
  105. return X509V3_add_value(name, "TRUE", extlist);
  106. return X509V3_add_value(name, "FALSE", extlist);
  107. }
  108. int X509V3_add_value_bool_nf(const char *name, int asn1_bool,
  109. STACK_OF(CONF_VALUE) **extlist)
  110. {
  111. if (asn1_bool)
  112. return X509V3_add_value(name, "TRUE", extlist);
  113. return 1;
  114. }
  115. static char *bignum_to_string(const BIGNUM *bn)
  116. {
  117. char *tmp, *ret;
  118. size_t len;
  119. /*
  120. * Display large numbers in hex and small numbers in decimal. Converting to
  121. * decimal takes quadratic time and is no more useful than hex for large
  122. * numbers.
  123. */
  124. if (BN_num_bits(bn) < 128)
  125. return BN_bn2dec(bn);
  126. tmp = BN_bn2hex(bn);
  127. if (tmp == NULL)
  128. return NULL;
  129. len = strlen(tmp) + 3;
  130. ret = OPENSSL_malloc(len);
  131. if (ret == NULL) {
  132. X509V3err(X509V3_F_BIGNUM_TO_STRING, ERR_R_MALLOC_FAILURE);
  133. OPENSSL_free(tmp);
  134. return NULL;
  135. }
  136. /* Prepend "0x", but place it after the "-" if negative. */
  137. if (tmp[0] == '-') {
  138. OPENSSL_strlcpy(ret, "-0x", len);
  139. OPENSSL_strlcat(ret, tmp + 1, len);
  140. } else {
  141. OPENSSL_strlcpy(ret, "0x", len);
  142. OPENSSL_strlcat(ret, tmp, len);
  143. }
  144. OPENSSL_free(tmp);
  145. return ret;
  146. }
  147. char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *a)
  148. {
  149. BIGNUM *bntmp = NULL;
  150. char *strtmp = NULL;
  151. if (!a)
  152. return NULL;
  153. if ((bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) == NULL
  154. || (strtmp = bignum_to_string(bntmp)) == NULL)
  155. X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
  156. BN_free(bntmp);
  157. return strtmp;
  158. }
  159. char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, const ASN1_INTEGER *a)
  160. {
  161. BIGNUM *bntmp = NULL;
  162. char *strtmp = NULL;
  163. if (!a)
  164. return NULL;
  165. if ((bntmp = ASN1_INTEGER_to_BN(a, NULL)) == NULL
  166. || (strtmp = bignum_to_string(bntmp)) == NULL)
  167. X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
  168. BN_free(bntmp);
  169. return strtmp;
  170. }
  171. ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value)
  172. {
  173. BIGNUM *bn = NULL;
  174. ASN1_INTEGER *aint;
  175. int isneg, ishex;
  176. int ret;
  177. if (value == NULL) {
  178. X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE);
  179. return NULL;
  180. }
  181. bn = BN_new();
  182. if (bn == NULL) {
  183. X509V3err(X509V3_F_S2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
  184. return NULL;
  185. }
  186. if (value[0] == '-') {
  187. value++;
  188. isneg = 1;
  189. } else
  190. isneg = 0;
  191. if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
  192. value += 2;
  193. ishex = 1;
  194. } else
  195. ishex = 0;
  196. if (ishex)
  197. ret = BN_hex2bn(&bn, value);
  198. else
  199. ret = BN_dec2bn(&bn, value);
  200. if (!ret || value[ret]) {
  201. BN_free(bn);
  202. X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR);
  203. return NULL;
  204. }
  205. if (isneg && BN_is_zero(bn))
  206. isneg = 0;
  207. aint = BN_to_ASN1_INTEGER(bn, NULL);
  208. BN_free(bn);
  209. if (!aint) {
  210. X509V3err(X509V3_F_S2I_ASN1_INTEGER,
  211. X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
  212. return NULL;
  213. }
  214. if (isneg)
  215. aint->type |= V_ASN1_NEG;
  216. return aint;
  217. }
  218. int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint,
  219. STACK_OF(CONF_VALUE) **extlist)
  220. {
  221. char *strtmp;
  222. int ret;
  223. if (!aint)
  224. return 1;
  225. if ((strtmp = i2s_ASN1_INTEGER(NULL, aint)) == NULL)
  226. return 0;
  227. ret = X509V3_add_value(name, strtmp, extlist);
  228. OPENSSL_free(strtmp);
  229. return ret;
  230. }
  231. int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool)
  232. {
  233. const char *btmp;
  234. if ((btmp = value->value) == NULL)
  235. goto err;
  236. if (strcmp(btmp, "TRUE") == 0
  237. || strcmp(btmp, "true") == 0
  238. || strcmp(btmp, "Y") == 0
  239. || strcmp(btmp, "y") == 0
  240. || strcmp(btmp, "YES") == 0
  241. || strcmp(btmp, "yes") == 0) {
  242. *asn1_bool = 0xff;
  243. return 1;
  244. }
  245. if (strcmp(btmp, "FALSE") == 0
  246. || strcmp(btmp, "false") == 0
  247. || strcmp(btmp, "N") == 0
  248. || strcmp(btmp, "n") == 0
  249. || strcmp(btmp, "NO") == 0
  250. || strcmp(btmp, "no") == 0) {
  251. *asn1_bool = 0;
  252. return 1;
  253. }
  254. err:
  255. X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,
  256. X509V3_R_INVALID_BOOLEAN_STRING);
  257. X509V3_conf_err(value);
  258. return 0;
  259. }
  260. int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint)
  261. {
  262. ASN1_INTEGER *itmp;
  263. if ((itmp = s2i_ASN1_INTEGER(NULL, value->value)) == NULL) {
  264. X509V3_conf_err(value);
  265. return 0;
  266. }
  267. *aint = itmp;
  268. return 1;
  269. }
  270. #define HDR_NAME 1
  271. #define HDR_VALUE 2
  272. /*
  273. * #define DEBUG
  274. */
  275. STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
  276. {
  277. char *p, *q, c;
  278. char *ntmp, *vtmp;
  279. STACK_OF(CONF_VALUE) *values = NULL;
  280. char *linebuf;
  281. int state;
  282. /* We are going to modify the line so copy it first */
  283. linebuf = OPENSSL_strdup(line);
  284. if (linebuf == NULL) {
  285. X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE);
  286. goto err;
  287. }
  288. state = HDR_NAME;
  289. ntmp = NULL;
  290. /* Go through all characters */
  291. for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
  292. p++) {
  293. switch (state) {
  294. case HDR_NAME:
  295. if (c == ':') {
  296. state = HDR_VALUE;
  297. *p = 0;
  298. ntmp = strip_spaces(q);
  299. if (!ntmp) {
  300. X509V3err(X509V3_F_X509V3_PARSE_LIST,
  301. X509V3_R_INVALID_NULL_NAME);
  302. goto err;
  303. }
  304. q = p + 1;
  305. } else if (c == ',') {
  306. *p = 0;
  307. ntmp = strip_spaces(q);
  308. q = p + 1;
  309. if (!ntmp) {
  310. X509V3err(X509V3_F_X509V3_PARSE_LIST,
  311. X509V3_R_INVALID_NULL_NAME);
  312. goto err;
  313. }
  314. X509V3_add_value(ntmp, NULL, &values);
  315. }
  316. break;
  317. case HDR_VALUE:
  318. if (c == ',') {
  319. state = HDR_NAME;
  320. *p = 0;
  321. vtmp = strip_spaces(q);
  322. if (!vtmp) {
  323. X509V3err(X509V3_F_X509V3_PARSE_LIST,
  324. X509V3_R_INVALID_NULL_VALUE);
  325. goto err;
  326. }
  327. X509V3_add_value(ntmp, vtmp, &values);
  328. ntmp = NULL;
  329. q = p + 1;
  330. }
  331. }
  332. }
  333. if (state == HDR_VALUE) {
  334. vtmp = strip_spaces(q);
  335. if (!vtmp) {
  336. X509V3err(X509V3_F_X509V3_PARSE_LIST,
  337. X509V3_R_INVALID_NULL_VALUE);
  338. goto err;
  339. }
  340. X509V3_add_value(ntmp, vtmp, &values);
  341. } else {
  342. ntmp = strip_spaces(q);
  343. if (!ntmp) {
  344. X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
  345. goto err;
  346. }
  347. X509V3_add_value(ntmp, NULL, &values);
  348. }
  349. OPENSSL_free(linebuf);
  350. return values;
  351. err:
  352. OPENSSL_free(linebuf);
  353. sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
  354. return NULL;
  355. }
  356. /* Delete leading and trailing spaces from a string */
  357. static char *strip_spaces(char *name)
  358. {
  359. char *p, *q;
  360. /* Skip over leading spaces */
  361. p = name;
  362. while (*p && ossl_isspace(*p))
  363. p++;
  364. if (!*p)
  365. return NULL;
  366. q = p + strlen(p) - 1;
  367. while ((q != p) && ossl_isspace(*q))
  368. q--;
  369. if (p != q)
  370. q[1] = 0;
  371. if (!*p)
  372. return NULL;
  373. return p;
  374. }
  375. /*
  376. * V2I name comparison function: returns zero if 'name' matches cmp or cmp.*
  377. */
  378. int name_cmp(const char *name, const char *cmp)
  379. {
  380. int len, ret;
  381. char c;
  382. len = strlen(cmp);
  383. if ((ret = strncmp(name, cmp, len)))
  384. return ret;
  385. c = name[len];
  386. if (!c || (c == '.'))
  387. return 0;
  388. return 1;
  389. }
  390. static int sk_strcmp(const char *const *a, const char *const *b)
  391. {
  392. return strcmp(*a, *b);
  393. }
  394. STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
  395. {
  396. GENERAL_NAMES *gens;
  397. STACK_OF(OPENSSL_STRING) *ret;
  398. gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
  399. ret = get_email(X509_get_subject_name(x), gens);
  400. sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
  401. return ret;
  402. }
  403. STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
  404. {
  405. AUTHORITY_INFO_ACCESS *info;
  406. STACK_OF(OPENSSL_STRING) *ret = NULL;
  407. int i;
  408. info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
  409. if (!info)
  410. return NULL;
  411. for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
  412. ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
  413. if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
  414. if (ad->location->type == GEN_URI) {
  415. if (!append_ia5
  416. (&ret, ad->location->d.uniformResourceIdentifier))
  417. break;
  418. }
  419. }
  420. }
  421. AUTHORITY_INFO_ACCESS_free(info);
  422. return ret;
  423. }
  424. STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
  425. {
  426. GENERAL_NAMES *gens;
  427. STACK_OF(X509_EXTENSION) *exts;
  428. STACK_OF(OPENSSL_STRING) *ret;
  429. exts = X509_REQ_get_extensions(x);
  430. gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
  431. ret = get_email(X509_REQ_get_subject_name(x), gens);
  432. sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
  433. sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
  434. return ret;
  435. }
  436. static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
  437. GENERAL_NAMES *gens)
  438. {
  439. STACK_OF(OPENSSL_STRING) *ret = NULL;
  440. X509_NAME_ENTRY *ne;
  441. const ASN1_IA5STRING *email;
  442. GENERAL_NAME *gen;
  443. int i = -1;
  444. /* Now add any email address(es) to STACK */
  445. /* First supplied X509_NAME */
  446. while ((i = X509_NAME_get_index_by_NID(name,
  447. NID_pkcs9_emailAddress, i)) >= 0) {
  448. ne = X509_NAME_get_entry(name, i);
  449. email = X509_NAME_ENTRY_get_data(ne);
  450. if (!append_ia5(&ret, email))
  451. return NULL;
  452. }
  453. for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
  454. gen = sk_GENERAL_NAME_value(gens, i);
  455. if (gen->type != GEN_EMAIL)
  456. continue;
  457. if (!append_ia5(&ret, gen->d.ia5))
  458. return NULL;
  459. }
  460. return ret;
  461. }
  462. static void str_free(OPENSSL_STRING str)
  463. {
  464. OPENSSL_free(str);
  465. }
  466. static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email)
  467. {
  468. char *emtmp;
  469. /* First some sanity checks */
  470. if (email->type != V_ASN1_IA5STRING)
  471. return 1;
  472. if (email->data == NULL || email->length == 0)
  473. return 1;
  474. if (memchr(email->data, 0, email->length) != NULL)
  475. return 1;
  476. if (*sk == NULL)
  477. *sk = sk_OPENSSL_STRING_new(sk_strcmp);
  478. if (*sk == NULL)
  479. return 0;
  480. emtmp = OPENSSL_strndup((char *)email->data, email->length);
  481. if (emtmp == NULL)
  482. return 0;
  483. /* Don't add duplicates */
  484. if (sk_OPENSSL_STRING_find(*sk, emtmp) != -1) {
  485. OPENSSL_free(emtmp);
  486. return 1;
  487. }
  488. if (!sk_OPENSSL_STRING_push(*sk, emtmp)) {
  489. OPENSSL_free(emtmp); /* free on push failure */
  490. X509_email_free(*sk);
  491. *sk = NULL;
  492. return 0;
  493. }
  494. return 1;
  495. }
  496. void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
  497. {
  498. sk_OPENSSL_STRING_pop_free(sk, str_free);
  499. }
  500. typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len,
  501. const unsigned char *subject, size_t subject_len,
  502. unsigned int flags);
  503. /* Skip pattern prefix to match "wildcard" subject */
  504. static void skip_prefix(const unsigned char **p, size_t *plen,
  505. size_t subject_len,
  506. unsigned int flags)
  507. {
  508. const unsigned char *pattern = *p;
  509. size_t pattern_len = *plen;
  510. /*
  511. * If subject starts with a leading '.' followed by more octets, and
  512. * pattern is longer, compare just an equal-length suffix with the
  513. * full subject (starting at the '.'), provided the prefix contains
  514. * no NULs.
  515. */
  516. if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0)
  517. return;
  518. while (pattern_len > subject_len && *pattern) {
  519. if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) &&
  520. *pattern == '.')
  521. break;
  522. ++pattern;
  523. --pattern_len;
  524. }
  525. /* Skip if entire prefix acceptable */
  526. if (pattern_len == subject_len) {
  527. *p = pattern;
  528. *plen = pattern_len;
  529. }
  530. }
  531. /* Compare while ASCII ignoring case. */
  532. static int equal_nocase(const unsigned char *pattern, size_t pattern_len,
  533. const unsigned char *subject, size_t subject_len,
  534. unsigned int flags)
  535. {
  536. skip_prefix(&pattern, &pattern_len, subject_len, flags);
  537. if (pattern_len != subject_len)
  538. return 0;
  539. while (pattern_len) {
  540. unsigned char l = *pattern;
  541. unsigned char r = *subject;
  542. /* The pattern must not contain NUL characters. */
  543. if (l == 0)
  544. return 0;
  545. if (l != r) {
  546. if ('A' <= l && l <= 'Z')
  547. l = (l - 'A') + 'a';
  548. if ('A' <= r && r <= 'Z')
  549. r = (r - 'A') + 'a';
  550. if (l != r)
  551. return 0;
  552. }
  553. ++pattern;
  554. ++subject;
  555. --pattern_len;
  556. }
  557. return 1;
  558. }
  559. /* Compare using memcmp. */
  560. static int equal_case(const unsigned char *pattern, size_t pattern_len,
  561. const unsigned char *subject, size_t subject_len,
  562. unsigned int flags)
  563. {
  564. skip_prefix(&pattern, &pattern_len, subject_len, flags);
  565. if (pattern_len != subject_len)
  566. return 0;
  567. return !memcmp(pattern, subject, pattern_len);
  568. }
  569. /*
  570. * RFC 5280, section 7.5, requires that only the domain is compared in a
  571. * case-insensitive manner.
  572. */
  573. static int equal_email(const unsigned char *a, size_t a_len,
  574. const unsigned char *b, size_t b_len,
  575. unsigned int unused_flags)
  576. {
  577. size_t i = a_len;
  578. if (a_len != b_len)
  579. return 0;
  580. /*
  581. * We search backwards for the '@' character, so that we do not have to
  582. * deal with quoted local-parts. The domain part is compared in a
  583. * case-insensitive manner.
  584. */
  585. while (i > 0) {
  586. --i;
  587. if (a[i] == '@' || b[i] == '@') {
  588. if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0))
  589. return 0;
  590. break;
  591. }
  592. }
  593. if (i == 0)
  594. i = a_len;
  595. return equal_case(a, i, b, i, 0);
  596. }
  597. /*
  598. * Compare the prefix and suffix with the subject, and check that the
  599. * characters in-between are valid.
  600. */
  601. static int wildcard_match(const unsigned char *prefix, size_t prefix_len,
  602. const unsigned char *suffix, size_t suffix_len,
  603. const unsigned char *subject, size_t subject_len,
  604. unsigned int flags)
  605. {
  606. const unsigned char *wildcard_start;
  607. const unsigned char *wildcard_end;
  608. const unsigned char *p;
  609. int allow_multi = 0;
  610. int allow_idna = 0;
  611. if (subject_len < prefix_len + suffix_len)
  612. return 0;
  613. if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags))
  614. return 0;
  615. wildcard_start = subject + prefix_len;
  616. wildcard_end = subject + (subject_len - suffix_len);
  617. if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags))
  618. return 0;
  619. /*
  620. * If the wildcard makes up the entire first label, it must match at
  621. * least one character.
  622. */
  623. if (prefix_len == 0 && *suffix == '.') {
  624. if (wildcard_start == wildcard_end)
  625. return 0;
  626. allow_idna = 1;
  627. if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS)
  628. allow_multi = 1;
  629. }
  630. /* IDNA labels cannot match partial wildcards */
  631. if (!allow_idna &&
  632. subject_len >= 4 && strncasecmp((char *)subject, "xn--", 4) == 0)
  633. return 0;
  634. /* The wildcard may match a literal '*' */
  635. if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*')
  636. return 1;
  637. /*
  638. * Check that the part matched by the wildcard contains only
  639. * permitted characters and only matches a single label unless
  640. * allow_multi is set.
  641. */
  642. for (p = wildcard_start; p != wildcard_end; ++p)
  643. if (!(('0' <= *p && *p <= '9') ||
  644. ('A' <= *p && *p <= 'Z') ||
  645. ('a' <= *p && *p <= 'z') ||
  646. *p == '-' || (allow_multi && *p == '.')))
  647. return 0;
  648. return 1;
  649. }
  650. #define LABEL_START (1 << 0)
  651. #define LABEL_END (1 << 1)
  652. #define LABEL_HYPHEN (1 << 2)
  653. #define LABEL_IDNA (1 << 3)
  654. static const unsigned char *valid_star(const unsigned char *p, size_t len,
  655. unsigned int flags)
  656. {
  657. const unsigned char *star = 0;
  658. size_t i;
  659. int state = LABEL_START;
  660. int dots = 0;
  661. for (i = 0; i < len; ++i) {
  662. /*
  663. * Locate first and only legal wildcard, either at the start
  664. * or end of a non-IDNA first and not final label.
  665. */
  666. if (p[i] == '*') {
  667. int atstart = (state & LABEL_START);
  668. int atend = (i == len - 1 || p[i + 1] == '.');
  669. /*-
  670. * At most one wildcard per pattern.
  671. * No wildcards in IDNA labels.
  672. * No wildcards after the first label.
  673. */
  674. if (star != NULL || (state & LABEL_IDNA) != 0 || dots)
  675. return NULL;
  676. /* Only full-label '*.example.com' wildcards? */
  677. if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS)
  678. && (!atstart || !atend))
  679. return NULL;
  680. /* No 'foo*bar' wildcards */
  681. if (!atstart && !atend)
  682. return NULL;
  683. star = &p[i];
  684. state &= ~LABEL_START;
  685. } else if (('a' <= p[i] && p[i] <= 'z')
  686. || ('A' <= p[i] && p[i] <= 'Z')
  687. || ('0' <= p[i] && p[i] <= '9')) {
  688. if ((state & LABEL_START) != 0
  689. && len - i >= 4 && strncasecmp((char *)&p[i], "xn--", 4) == 0)
  690. state |= LABEL_IDNA;
  691. state &= ~(LABEL_HYPHEN | LABEL_START);
  692. } else if (p[i] == '.') {
  693. if ((state & (LABEL_HYPHEN | LABEL_START)) != 0)
  694. return NULL;
  695. state = LABEL_START;
  696. ++dots;
  697. } else if (p[i] == '-') {
  698. /* no domain/subdomain starts with '-' */
  699. if ((state & LABEL_START) != 0)
  700. return NULL;
  701. state |= LABEL_HYPHEN;
  702. } else
  703. return NULL;
  704. }
  705. /*
  706. * The final label must not end in a hyphen or ".", and
  707. * there must be at least two dots after the star.
  708. */
  709. if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2)
  710. return NULL;
  711. return star;
  712. }
  713. /* Compare using wildcards. */
  714. static int equal_wildcard(const unsigned char *pattern, size_t pattern_len,
  715. const unsigned char *subject, size_t subject_len,
  716. unsigned int flags)
  717. {
  718. const unsigned char *star = NULL;
  719. /*
  720. * Subject names starting with '.' can only match a wildcard pattern
  721. * via a subject sub-domain pattern suffix match.
  722. */
  723. if (!(subject_len > 1 && subject[0] == '.'))
  724. star = valid_star(pattern, pattern_len, flags);
  725. if (star == NULL)
  726. return equal_nocase(pattern, pattern_len,
  727. subject, subject_len, flags);
  728. return wildcard_match(pattern, star - pattern,
  729. star + 1, (pattern + pattern_len) - star - 1,
  730. subject, subject_len, flags);
  731. }
  732. /*
  733. * Compare an ASN1_STRING to a supplied string. If they match return 1. If
  734. * cmp_type > 0 only compare if string matches the type, otherwise convert it
  735. * to UTF8.
  736. */
  737. static int do_check_string(const ASN1_STRING *a, int cmp_type, equal_fn equal,
  738. unsigned int flags, const char *b, size_t blen,
  739. char **peername)
  740. {
  741. int rv = 0;
  742. if (!a->data || !a->length)
  743. return 0;
  744. if (cmp_type > 0) {
  745. if (cmp_type != a->type)
  746. return 0;
  747. if (cmp_type == V_ASN1_IA5STRING)
  748. rv = equal(a->data, a->length, (unsigned char *)b, blen, flags);
  749. else if (a->length == (int)blen && !memcmp(a->data, b, blen))
  750. rv = 1;
  751. if (rv > 0 && peername)
  752. *peername = OPENSSL_strndup((char *)a->data, a->length);
  753. } else {
  754. int astrlen;
  755. unsigned char *astr;
  756. astrlen = ASN1_STRING_to_UTF8(&astr, a);
  757. if (astrlen < 0) {
  758. /*
  759. * -1 could be an internal malloc failure or a decoding error from
  760. * malformed input; we can't distinguish.
  761. */
  762. return -1;
  763. }
  764. rv = equal(astr, astrlen, (unsigned char *)b, blen, flags);
  765. if (rv > 0 && peername)
  766. *peername = OPENSSL_strndup((char *)astr, astrlen);
  767. OPENSSL_free(astr);
  768. }
  769. return rv;
  770. }
  771. static int do_x509_check(X509 *x, const char *chk, size_t chklen,
  772. unsigned int flags, int check_type, char **peername)
  773. {
  774. GENERAL_NAMES *gens = NULL;
  775. X509_NAME *name = NULL;
  776. int i;
  777. int cnid = NID_undef;
  778. int alt_type;
  779. int san_present = 0;
  780. int rv = 0;
  781. equal_fn equal;
  782. /* See below, this flag is internal-only */
  783. flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
  784. if (check_type == GEN_EMAIL) {
  785. cnid = NID_pkcs9_emailAddress;
  786. alt_type = V_ASN1_IA5STRING;
  787. equal = equal_email;
  788. } else if (check_type == GEN_DNS) {
  789. cnid = NID_commonName;
  790. /* Implicit client-side DNS sub-domain pattern */
  791. if (chklen > 1 && chk[0] == '.')
  792. flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
  793. alt_type = V_ASN1_IA5STRING;
  794. if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
  795. equal = equal_nocase;
  796. else
  797. equal = equal_wildcard;
  798. } else {
  799. alt_type = V_ASN1_OCTET_STRING;
  800. equal = equal_case;
  801. }
  802. if (chklen == 0)
  803. chklen = strlen(chk);
  804. gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
  805. if (gens) {
  806. for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
  807. GENERAL_NAME *gen;
  808. ASN1_STRING *cstr;
  809. gen = sk_GENERAL_NAME_value(gens, i);
  810. if (gen->type != check_type)
  811. continue;
  812. san_present = 1;
  813. if (check_type == GEN_EMAIL)
  814. cstr = gen->d.rfc822Name;
  815. else if (check_type == GEN_DNS)
  816. cstr = gen->d.dNSName;
  817. else
  818. cstr = gen->d.iPAddress;
  819. /* Positive on success, negative on error! */
  820. if ((rv = do_check_string(cstr, alt_type, equal, flags,
  821. chk, chklen, peername)) != 0)
  822. break;
  823. }
  824. GENERAL_NAMES_free(gens);
  825. if (rv != 0)
  826. return rv;
  827. if (san_present && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT))
  828. return 0;
  829. }
  830. /* We're done if CN-ID is not pertinent */
  831. if (cnid == NID_undef || (flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT))
  832. return 0;
  833. i = -1;
  834. name = X509_get_subject_name(x);
  835. while ((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) {
  836. const X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, i);
  837. const ASN1_STRING *str = X509_NAME_ENTRY_get_data(ne);
  838. /* Positive on success, negative on error! */
  839. if ((rv = do_check_string(str, -1, equal, flags,
  840. chk, chklen, peername)) != 0)
  841. return rv;
  842. }
  843. return 0;
  844. }
  845. int X509_check_host(X509 *x, const char *chk, size_t chklen,
  846. unsigned int flags, char **peername)
  847. {
  848. if (chk == NULL)
  849. return -2;
  850. /*
  851. * Embedded NULs are disallowed, except as the last character of a
  852. * string of length 2 or more (tolerate caller including terminating
  853. * NUL in string length).
  854. */
  855. if (chklen == 0)
  856. chklen = strlen(chk);
  857. else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen))
  858. return -2;
  859. if (chklen > 1 && chk[chklen - 1] == '\0')
  860. --chklen;
  861. return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername);
  862. }
  863. int X509_check_email(X509 *x, const char *chk, size_t chklen,
  864. unsigned int flags)
  865. {
  866. if (chk == NULL)
  867. return -2;
  868. /*
  869. * Embedded NULs are disallowed, except as the last character of a
  870. * string of length 2 or more (tolerate caller including terminating
  871. * NUL in string length).
  872. */
  873. if (chklen == 0)
  874. chklen = strlen((char *)chk);
  875. else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen))
  876. return -2;
  877. if (chklen > 1 && chk[chklen - 1] == '\0')
  878. --chklen;
  879. return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL);
  880. }
  881. int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
  882. unsigned int flags)
  883. {
  884. if (chk == NULL)
  885. return -2;
  886. return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL);
  887. }
  888. int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags)
  889. {
  890. unsigned char ipout[16];
  891. size_t iplen;
  892. if (ipasc == NULL)
  893. return -2;
  894. iplen = (size_t)a2i_ipadd(ipout, ipasc);
  895. if (iplen == 0)
  896. return -2;
  897. return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
  898. }
  899. /*
  900. * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible
  901. * with RFC3280.
  902. */
  903. ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc)
  904. {
  905. unsigned char ipout[16];
  906. ASN1_OCTET_STRING *ret;
  907. int iplen;
  908. /* If string contains a ':' assume IPv6 */
  909. iplen = a2i_ipadd(ipout, ipasc);
  910. if (!iplen)
  911. return NULL;
  912. ret = ASN1_OCTET_STRING_new();
  913. if (ret == NULL)
  914. return NULL;
  915. if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) {
  916. ASN1_OCTET_STRING_free(ret);
  917. return NULL;
  918. }
  919. return ret;
  920. }
  921. ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc)
  922. {
  923. ASN1_OCTET_STRING *ret = NULL;
  924. unsigned char ipout[32];
  925. char *iptmp = NULL, *p;
  926. int iplen1, iplen2;
  927. p = strchr(ipasc, '/');
  928. if (!p)
  929. return NULL;
  930. iptmp = OPENSSL_strdup(ipasc);
  931. if (!iptmp)
  932. return NULL;
  933. p = iptmp + (p - ipasc);
  934. *p++ = 0;
  935. iplen1 = a2i_ipadd(ipout, iptmp);
  936. if (!iplen1)
  937. goto err;
  938. iplen2 = a2i_ipadd(ipout + iplen1, p);
  939. OPENSSL_free(iptmp);
  940. iptmp = NULL;
  941. if (!iplen2 || (iplen1 != iplen2))
  942. goto err;
  943. ret = ASN1_OCTET_STRING_new();
  944. if (ret == NULL)
  945. goto err;
  946. if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
  947. goto err;
  948. return ret;
  949. err:
  950. OPENSSL_free(iptmp);
  951. ASN1_OCTET_STRING_free(ret);
  952. return NULL;
  953. }
  954. int a2i_ipadd(unsigned char *ipout, const char *ipasc)
  955. {
  956. /* If string contains a ':' assume IPv6 */
  957. if (strchr(ipasc, ':')) {
  958. if (!ipv6_from_asc(ipout, ipasc))
  959. return 0;
  960. return 16;
  961. } else {
  962. if (!ipv4_from_asc(ipout, ipasc))
  963. return 0;
  964. return 4;
  965. }
  966. }
  967. static int ipv4_from_asc(unsigned char *v4, const char *in)
  968. {
  969. int a0, a1, a2, a3;
  970. if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
  971. return 0;
  972. if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
  973. || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
  974. return 0;
  975. v4[0] = a0;
  976. v4[1] = a1;
  977. v4[2] = a2;
  978. v4[3] = a3;
  979. return 1;
  980. }
  981. typedef struct {
  982. /* Temporary store for IPV6 output */
  983. unsigned char tmp[16];
  984. /* Total number of bytes in tmp */
  985. int total;
  986. /* The position of a zero (corresponding to '::') */
  987. int zero_pos;
  988. /* Number of zeroes */
  989. int zero_cnt;
  990. } IPV6_STAT;
  991. static int ipv6_from_asc(unsigned char *v6, const char *in)
  992. {
  993. IPV6_STAT v6stat;
  994. v6stat.total = 0;
  995. v6stat.zero_pos = -1;
  996. v6stat.zero_cnt = 0;
  997. /*
  998. * Treat the IPv6 representation as a list of values separated by ':'.
  999. * The presence of a '::' will parse as one, two or three zero length
  1000. * elements.
  1001. */
  1002. if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
  1003. return 0;
  1004. /* Now for some sanity checks */
  1005. if (v6stat.zero_pos == -1) {
  1006. /* If no '::' must have exactly 16 bytes */
  1007. if (v6stat.total != 16)
  1008. return 0;
  1009. } else {
  1010. /* If '::' must have less than 16 bytes */
  1011. if (v6stat.total == 16)
  1012. return 0;
  1013. /* More than three zeroes is an error */
  1014. if (v6stat.zero_cnt > 3)
  1015. return 0;
  1016. /* Can only have three zeroes if nothing else present */
  1017. else if (v6stat.zero_cnt == 3) {
  1018. if (v6stat.total > 0)
  1019. return 0;
  1020. }
  1021. /* Can only have two zeroes if at start or end */
  1022. else if (v6stat.zero_cnt == 2) {
  1023. if ((v6stat.zero_pos != 0)
  1024. && (v6stat.zero_pos != v6stat.total))
  1025. return 0;
  1026. } else
  1027. /* Can only have one zero if *not* start or end */
  1028. {
  1029. if ((v6stat.zero_pos == 0)
  1030. || (v6stat.zero_pos == v6stat.total))
  1031. return 0;
  1032. }
  1033. }
  1034. /* Format result */
  1035. if (v6stat.zero_pos >= 0) {
  1036. /* Copy initial part */
  1037. memcpy(v6, v6stat.tmp, v6stat.zero_pos);
  1038. /* Zero middle */
  1039. memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
  1040. /* Copy final part */
  1041. if (v6stat.total != v6stat.zero_pos)
  1042. memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
  1043. v6stat.tmp + v6stat.zero_pos,
  1044. v6stat.total - v6stat.zero_pos);
  1045. } else
  1046. memcpy(v6, v6stat.tmp, 16);
  1047. return 1;
  1048. }
  1049. static int ipv6_cb(const char *elem, int len, void *usr)
  1050. {
  1051. IPV6_STAT *s = usr;
  1052. /* Error if 16 bytes written */
  1053. if (s->total == 16)
  1054. return 0;
  1055. if (len == 0) {
  1056. /* Zero length element, corresponds to '::' */
  1057. if (s->zero_pos == -1)
  1058. s->zero_pos = s->total;
  1059. /* If we've already got a :: its an error */
  1060. else if (s->zero_pos != s->total)
  1061. return 0;
  1062. s->zero_cnt++;
  1063. } else {
  1064. /* If more than 4 characters could be final a.b.c.d form */
  1065. if (len > 4) {
  1066. /* Need at least 4 bytes left */
  1067. if (s->total > 12)
  1068. return 0;
  1069. /* Must be end of string */
  1070. if (elem[len])
  1071. return 0;
  1072. if (!ipv4_from_asc(s->tmp + s->total, elem))
  1073. return 0;
  1074. s->total += 4;
  1075. } else {
  1076. if (!ipv6_hex(s->tmp + s->total, elem, len))
  1077. return 0;
  1078. s->total += 2;
  1079. }
  1080. }
  1081. return 1;
  1082. }
  1083. /*
  1084. * Convert a string of up to 4 hex digits into the corresponding IPv6 form.
  1085. */
  1086. static int ipv6_hex(unsigned char *out, const char *in, int inlen)
  1087. {
  1088. unsigned char c;
  1089. unsigned int num = 0;
  1090. int x;
  1091. if (inlen > 4)
  1092. return 0;
  1093. while (inlen--) {
  1094. c = *in++;
  1095. num <<= 4;
  1096. x = OPENSSL_hexchar2int(c);
  1097. if (x < 0)
  1098. return 0;
  1099. num |= (char)x;
  1100. }
  1101. out[0] = num >> 8;
  1102. out[1] = num & 0xff;
  1103. return 1;
  1104. }
  1105. int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
  1106. unsigned long chtype)
  1107. {
  1108. CONF_VALUE *v;
  1109. int i, mval, spec_char, plus_char;
  1110. char *p, *type;
  1111. if (!nm)
  1112. return 0;
  1113. for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
  1114. v = sk_CONF_VALUE_value(dn_sk, i);
  1115. type = v->name;
  1116. /*
  1117. * Skip past any leading X. X: X, etc to allow for multiple instances
  1118. */
  1119. for (p = type; *p; p++) {
  1120. #ifndef CHARSET_EBCDIC
  1121. spec_char = ((*p == ':') || (*p == ',') || (*p == '.'));
  1122. #else
  1123. spec_char = ((*p == os_toascii[':']) || (*p == os_toascii[','])
  1124. || (*p == os_toascii['.']));
  1125. #endif
  1126. if (spec_char) {
  1127. p++;
  1128. if (*p)
  1129. type = p;
  1130. break;
  1131. }
  1132. }
  1133. #ifndef CHARSET_EBCDIC
  1134. plus_char = (*type == '+');
  1135. #else
  1136. plus_char = (*type == os_toascii['+']);
  1137. #endif
  1138. if (plus_char) {
  1139. mval = -1;
  1140. type++;
  1141. } else
  1142. mval = 0;
  1143. if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
  1144. (unsigned char *)v->value, -1, -1,
  1145. mval))
  1146. return 0;
  1147. }
  1148. return 1;
  1149. }