v3_utl.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:20k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* v3_utl.c */
  2. /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
  3.  * project.
  4.  */
  5. /* ====================================================================
  6.  * Copyright (c) 1999-2003 The OpenSSL Project.  All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  *
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer. 
  14.  *
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in
  17.  *    the documentation and/or other materials provided with the
  18.  *    distribution.
  19.  *
  20.  * 3. All advertising materials mentioning features or use of this
  21.  *    software must display the following acknowledgment:
  22.  *    "This product includes software developed by the OpenSSL Project
  23.  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24.  *
  25.  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26.  *    endorse or promote products derived from this software without
  27.  *    prior written permission. For written permission, please contact
  28.  *    licensing@OpenSSL.org.
  29.  *
  30.  * 5. Products derived from this software may not be called "OpenSSL"
  31.  *    nor may "OpenSSL" appear in their names without prior written
  32.  *    permission of the OpenSSL Project.
  33.  *
  34.  * 6. Redistributions of any form whatsoever must retain the following
  35.  *    acknowledgment:
  36.  *    "This product includes software developed by the OpenSSL Project
  37.  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38.  *
  39.  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  51.  * ====================================================================
  52.  *
  53.  * This product includes cryptographic software written by Eric Young
  54.  * (eay@cryptsoft.com).  This product includes software written by Tim
  55.  * Hudson (tjh@cryptsoft.com).
  56.  *
  57.  */
  58. /* X509 v3 extension utilities */
  59. #include <stdio.h>
  60. #include <ctype.h>
  61. #include "cryptlib.h"
  62. #include <openssl/conf.h>
  63. #include <openssl/x509v3.h>
  64. #include <openssl/bn.h>
  65. static char *strip_spaces(char *name);
  66. static int sk_strcmp(const char * const *a, const char * const *b);
  67. static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens);
  68. static void str_free(void *str);
  69. static int append_ia5(STACK **sk, ASN1_IA5STRING *email);
  70. static int a2i_ipadd(unsigned char *ipout, const char *ipasc);
  71. static int ipv4_from_asc(unsigned char *v4, const char *in);
  72. static int ipv6_from_asc(unsigned char *v6, const char *in);
  73. static int ipv6_cb(const char *elem, int len, void *usr);
  74. static int ipv6_hex(unsigned char *out, const char *in, int inlen);
  75. /* Add a CONF_VALUE name value pair to stack */
  76. int X509V3_add_value(const char *name, const char *value,
  77. STACK_OF(CONF_VALUE) **extlist)
  78. {
  79. CONF_VALUE *vtmp = NULL;
  80. char *tname = NULL, *tvalue = NULL;
  81. if(name && !(tname = BUF_strdup(name))) goto err;
  82. if(value && !(tvalue = BUF_strdup(value))) goto err;;
  83. if(!(vtmp = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) goto err;
  84. if(!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) goto err;
  85. vtmp->section = NULL;
  86. vtmp->name = tname;
  87. vtmp->value = tvalue;
  88. if(!sk_CONF_VALUE_push(*extlist, vtmp)) goto err;
  89. return 1;
  90. err:
  91. X509V3err(X509V3_F_X509V3_ADD_VALUE,ERR_R_MALLOC_FAILURE);
  92. if(vtmp) OPENSSL_free(vtmp);
  93. if(tname) OPENSSL_free(tname);
  94. if(tvalue) OPENSSL_free(tvalue);
  95. return 0;
  96. }
  97. int X509V3_add_value_uchar(const char *name, const unsigned char *value,
  98.    STACK_OF(CONF_VALUE) **extlist)
  99.     {
  100.     return X509V3_add_value(name,(const char *)value,extlist);
  101.     }
  102. /* Free function for STACK_OF(CONF_VALUE) */
  103. void X509V3_conf_free(CONF_VALUE *conf)
  104. {
  105. if(!conf) return;
  106. if(conf->name) OPENSSL_free(conf->name);
  107. if(conf->value) OPENSSL_free(conf->value);
  108. if(conf->section) OPENSSL_free(conf->section);
  109. OPENSSL_free(conf);
  110. }
  111. int X509V3_add_value_bool(const char *name, int asn1_bool,
  112. STACK_OF(CONF_VALUE) **extlist)
  113. {
  114. if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
  115. return X509V3_add_value(name, "FALSE", extlist);
  116. }
  117. int X509V3_add_value_bool_nf(char *name, int asn1_bool,
  118. STACK_OF(CONF_VALUE) **extlist)
  119. {
  120. if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist);
  121. return 1;
  122. }
  123. char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
  124. {
  125. BIGNUM *bntmp = NULL;
  126. char *strtmp = NULL;
  127. if(!a) return NULL;
  128. if(!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
  129.     !(strtmp = BN_bn2dec(bntmp)) )
  130. X509V3err(X509V3_F_I2S_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
  131. BN_free(bntmp);
  132. return strtmp;
  133. }
  134. char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
  135. {
  136. BIGNUM *bntmp = NULL;
  137. char *strtmp = NULL;
  138. if(!a) return NULL;
  139. if(!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
  140.     !(strtmp = BN_bn2dec(bntmp)) )
  141. X509V3err(X509V3_F_I2S_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
  142. BN_free(bntmp);
  143. return strtmp;
  144. }
  145. ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
  146. {
  147. BIGNUM *bn = NULL;
  148. ASN1_INTEGER *aint;
  149. int isneg, ishex;
  150. int ret;
  151. if (!value) {
  152. X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_INVALID_NULL_VALUE);
  153. return 0;
  154. }
  155. bn = BN_new();
  156. if (value[0] == '-') {
  157. value++;
  158. isneg = 1;
  159. } else isneg = 0;
  160. if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
  161. value += 2;
  162. ishex = 1;
  163. } else ishex = 0;
  164. if (ishex) ret = BN_hex2bn(&bn, value);
  165. else ret = BN_dec2bn(&bn, value);
  166. if (!ret || value[ret]) {
  167. BN_free(bn);
  168. X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_DEC2BN_ERROR);
  169. return 0;
  170. }
  171. if (isneg && BN_is_zero(bn)) isneg = 0;
  172. aint = BN_to_ASN1_INTEGER(bn, NULL);
  173. BN_free(bn);
  174. if (!aint) {
  175. X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
  176. return 0;
  177. }
  178. if (isneg) aint->type |= V_ASN1_NEG;
  179. return aint;
  180. }
  181. int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
  182.      STACK_OF(CONF_VALUE) **extlist)
  183. {
  184. char *strtmp;
  185. int ret;
  186. if(!aint) return 1;
  187. if(!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) return 0;
  188. ret = X509V3_add_value(name, strtmp, extlist);
  189. OPENSSL_free(strtmp);
  190. return ret;
  191. }
  192. int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
  193. {
  194. char *btmp;
  195. if(!(btmp = value->value)) goto err;
  196. if(!strcmp(btmp, "TRUE") || !strcmp(btmp, "true")
  197.  || !strcmp(btmp, "Y") || !strcmp(btmp, "y")
  198. || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
  199. *asn1_bool = 0xff;
  200. return 1;
  201. } else if(!strcmp(btmp, "FALSE") || !strcmp(btmp, "false")
  202.  || !strcmp(btmp, "N") || !strcmp(btmp, "n")
  203. || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
  204. *asn1_bool = 0;
  205. return 1;
  206. }
  207. err:
  208. X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,X509V3_R_INVALID_BOOLEAN_STRING);
  209. X509V3_conf_err(value);
  210. return 0;
  211. }
  212. int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint)
  213. {
  214. ASN1_INTEGER *itmp;
  215. if(!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
  216. X509V3_conf_err(value);
  217. return 0;
  218. }
  219. *aint = itmp;
  220. return 1;
  221. }
  222. #define HDR_NAME 1
  223. #define HDR_VALUE 2
  224. /*#define DEBUG*/
  225. STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
  226. {
  227. char *p, *q, c;
  228. char *ntmp, *vtmp;
  229. STACK_OF(CONF_VALUE) *values = NULL;
  230. char *linebuf;
  231. int state;
  232. /* We are going to modify the line so copy it first */
  233. linebuf = BUF_strdup(line);
  234. state = HDR_NAME;
  235. ntmp = NULL;
  236. /* Go through all characters */
  237. for(p = linebuf, q = linebuf; (c = *p) && (c!='r') && (c!='n'); p++) {
  238. switch(state) {
  239. case HDR_NAME:
  240. if(c == ':') {
  241. state = HDR_VALUE;
  242. *p = 0;
  243. ntmp = strip_spaces(q);
  244. if(!ntmp) {
  245. X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
  246. goto err;
  247. }
  248. q = p + 1;
  249. } else if(c == ',') {
  250. *p = 0;
  251. ntmp = strip_spaces(q);
  252. q = p + 1;
  253. #if 0
  254. printf("%sn", ntmp);
  255. #endif
  256. if(!ntmp) {
  257. X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
  258. goto err;
  259. }
  260. X509V3_add_value(ntmp, NULL, &values);
  261. }
  262. break ;
  263. case HDR_VALUE:
  264. if(c == ',') {
  265. state = HDR_NAME;
  266. *p = 0;
  267. vtmp = strip_spaces(q);
  268. #if 0
  269. printf("%sn", ntmp);
  270. #endif
  271. if(!vtmp) {
  272. X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_VALUE);
  273. goto err;
  274. }
  275. X509V3_add_value(ntmp, vtmp, &values);
  276. ntmp = NULL;
  277. q = p + 1;
  278. }
  279. }
  280. }
  281. if(state == HDR_VALUE) {
  282. vtmp = strip_spaces(q);
  283. #if 0
  284. printf("%s=%sn", ntmp, vtmp);
  285. #endif
  286. if(!vtmp) {
  287. X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_VALUE);
  288. goto err;
  289. }
  290. X509V3_add_value(ntmp, vtmp, &values);
  291. } else {
  292. ntmp = strip_spaces(q);
  293. #if 0
  294. printf("%sn", ntmp);
  295. #endif
  296. if(!ntmp) {
  297. X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
  298. goto err;
  299. }
  300. X509V3_add_value(ntmp, NULL, &values);
  301. }
  302. OPENSSL_free(linebuf);
  303. return values;
  304. err:
  305. OPENSSL_free(linebuf);
  306. sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
  307. return NULL;
  308. }
  309. /* Delete leading and trailing spaces from a string */
  310. static char *strip_spaces(char *name)
  311. {
  312. char *p, *q;
  313. /* Skip over leading spaces */
  314. p = name;
  315. while(*p && isspace((unsigned char)*p)) p++;
  316. if(!*p) return NULL;
  317. q = p + strlen(p) - 1;
  318. while((q != p) && isspace((unsigned char)*q)) q--;
  319. if(p != q) q[1] = 0;
  320. if(!*p) return NULL;
  321. return p;
  322. }
  323. /* hex string utilities */
  324. /* Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
  325.  * hex representation
  326.  * @@@ (Contents of buffer are always kept in ASCII, also on EBCDIC machines)
  327.  */
  328. char *hex_to_string(unsigned char *buffer, long len)
  329. {
  330. char *tmp, *q;
  331. unsigned char *p;
  332. int i;
  333. static char hexdig[] = "0123456789ABCDEF";
  334. if(!buffer || !len) return NULL;
  335. if(!(tmp = OPENSSL_malloc(len * 3 + 1))) {
  336. X509V3err(X509V3_F_HEX_TO_STRING,ERR_R_MALLOC_FAILURE);
  337. return NULL;
  338. }
  339. q = tmp;
  340. for(i = 0, p = buffer; i < len; i++,p++) {
  341. *q++ = hexdig[(*p >> 4) & 0xf];
  342. *q++ = hexdig[*p & 0xf];
  343. *q++ = ':';
  344. }
  345. q[-1] = 0;
  346. #ifdef CHARSET_EBCDIC
  347. ebcdic2ascii(tmp, tmp, q - tmp - 1);
  348. #endif
  349. return tmp;
  350. }
  351. /* Give a string of hex digits convert to
  352.  * a buffer
  353.  */
  354. unsigned char *string_to_hex(char *str, long *len)
  355. {
  356. unsigned char *hexbuf, *q;
  357. unsigned char ch, cl, *p;
  358. if(!str) {
  359. X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_INVALID_NULL_ARGUMENT);
  360. return NULL;
  361. }
  362. if(!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) goto err;
  363. for(p = (unsigned char *)str, q = hexbuf; *p;) {
  364. ch = *p++;
  365. #ifdef CHARSET_EBCDIC
  366. ch = os_toebcdic[ch];
  367. #endif
  368. if(ch == ':') continue;
  369. cl = *p++;
  370. #ifdef CHARSET_EBCDIC
  371. cl = os_toebcdic[cl];
  372. #endif
  373. if(!cl) {
  374. X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ODD_NUMBER_OF_DIGITS);
  375. OPENSSL_free(hexbuf);
  376. return NULL;
  377. }
  378. if(isupper(ch)) ch = tolower(ch);
  379. if(isupper(cl)) cl = tolower(cl);
  380. if((ch >= '0') && (ch <= '9')) ch -= '0';
  381. else if ((ch >= 'a') && (ch <= 'f')) ch -= 'a' - 10;
  382. else goto badhex;
  383. if((cl >= '0') && (cl <= '9')) cl -= '0';
  384. else if ((cl >= 'a') && (cl <= 'f')) cl -= 'a' - 10;
  385. else goto badhex;
  386. *q++ = (ch << 4) | cl;
  387. }
  388. if(len) *len = q - hexbuf;
  389. return hexbuf;
  390. err:
  391. if(hexbuf) OPENSSL_free(hexbuf);
  392. X509V3err(X509V3_F_STRING_TO_HEX,ERR_R_MALLOC_FAILURE);
  393. return NULL;
  394. badhex:
  395. OPENSSL_free(hexbuf);
  396. X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ILLEGAL_HEX_DIGIT);
  397. return NULL;
  398. }
  399. /* V2I name comparison function: returns zero if 'name' matches
  400.  * cmp or cmp.*
  401.  */
  402. int name_cmp(const char *name, const char *cmp)
  403. {
  404. int len, ret;
  405. char c;
  406. len = strlen(cmp);
  407. if((ret = strncmp(name, cmp, len))) return ret;
  408. c = name[len];
  409. if(!c || (c=='.')) return 0;
  410. return 1;
  411. }
  412. static int sk_strcmp(const char * const *a, const char * const *b)
  413. {
  414. return strcmp(*a, *b);
  415. }
  416. STACK *X509_get1_email(X509 *x)
  417. {
  418. GENERAL_NAMES *gens;
  419. STACK *ret;
  420. gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
  421. ret = get_email(X509_get_subject_name(x), gens);
  422. sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
  423. return ret;
  424. }
  425. STACK *X509_REQ_get1_email(X509_REQ *x)
  426. {
  427. GENERAL_NAMES *gens;
  428. STACK_OF(X509_EXTENSION) *exts;
  429. STACK *ret;
  430. exts = X509_REQ_get_extensions(x);
  431. gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
  432. ret = get_email(X509_REQ_get_subject_name(x), gens);
  433. sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
  434. sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
  435. return ret;
  436. }
  437. static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens)
  438. {
  439. STACK *ret = NULL;
  440. X509_NAME_ENTRY *ne;
  441. ASN1_IA5STRING *email;
  442. GENERAL_NAME *gen;
  443. int i;
  444. /* Now add any email address(es) to STACK */
  445. i = -1;
  446. /* First supplied X509_NAME */
  447. while((i = X509_NAME_get_index_by_NID(name,
  448.  NID_pkcs9_emailAddress, i)) >= 0) {
  449. ne = X509_NAME_get_entry(name, i);
  450. email = X509_NAME_ENTRY_get_data(ne);
  451. if(!append_ia5(&ret, email)) return NULL;
  452. }
  453. for(i = 0; i < sk_GENERAL_NAME_num(gens); i++)
  454. {
  455. gen = sk_GENERAL_NAME_value(gens, i);
  456. if(gen->type != GEN_EMAIL) continue;
  457. if(!append_ia5(&ret, gen->d.ia5)) return NULL;
  458. }
  459. return ret;
  460. }
  461. static void str_free(void *str)
  462. {
  463. OPENSSL_free(str);
  464. }
  465. static int append_ia5(STACK **sk, ASN1_IA5STRING *email)
  466. {
  467. char *emtmp;
  468. /* First some sanity checks */
  469. if(email->type != V_ASN1_IA5STRING) return 1;
  470. if(!email->data || !email->length) return 1;
  471. if(!*sk) *sk = sk_new(sk_strcmp);
  472. if(!*sk) return 0;
  473. /* Don't add duplicates */
  474. if(sk_find(*sk, (char *)email->data) != -1) return 1;
  475. emtmp = BUF_strdup((char *)email->data);
  476. if(!emtmp || !sk_push(*sk, emtmp)) {
  477. X509_email_free(*sk);
  478. *sk = NULL;
  479. return 0;
  480. }
  481. return 1;
  482. }
  483. void X509_email_free(STACK *sk)
  484. {
  485. sk_pop_free(sk, str_free);
  486. }
  487. /* Convert IP addresses both IPv4 and IPv6 into an 
  488.  * OCTET STRING compatible with RFC3280.
  489.  */
  490. ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc)
  491. {
  492. unsigned char ipout[16];
  493. ASN1_OCTET_STRING *ret;
  494. int iplen;
  495. /* If string contains a ':' assume IPv6 */
  496. iplen = a2i_ipadd(ipout, ipasc);
  497. if (!iplen)
  498. return NULL;
  499. ret = ASN1_OCTET_STRING_new();
  500. if (!ret)
  501. return NULL;
  502. if (!ASN1_OCTET_STRING_set(ret, ipout, iplen))
  503. {
  504. ASN1_OCTET_STRING_free(ret);
  505. return NULL;
  506. }
  507. return ret;
  508. }
  509. ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc)
  510. {
  511. ASN1_OCTET_STRING *ret = NULL;
  512. unsigned char ipout[32];
  513. char *iptmp = NULL, *p;
  514. int iplen1, iplen2;
  515. p = strchr(ipasc,'/');
  516. if (!p)
  517. return NULL;
  518. iptmp = BUF_strdup(ipasc);
  519. if (!iptmp)
  520. return NULL;
  521. p = iptmp + (p - ipasc);
  522. *p++ = 0;
  523. iplen1 = a2i_ipadd(ipout, iptmp);
  524. if (!iplen1)
  525. goto err;
  526. iplen2 = a2i_ipadd(ipout + iplen1, p);
  527. OPENSSL_free(iptmp);
  528. iptmp = NULL;
  529. if (!iplen2 || (iplen1 != iplen2))
  530. goto err;
  531. ret = ASN1_OCTET_STRING_new();
  532. if (!ret)
  533. goto err;
  534. if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
  535. goto err;
  536. return ret;
  537. err:
  538. if (iptmp)
  539. OPENSSL_free(iptmp);
  540. if (ret)
  541. ASN1_OCTET_STRING_free(ret);
  542. return NULL;
  543. }
  544. static int a2i_ipadd(unsigned char *ipout, const char *ipasc)
  545. {
  546. /* If string contains a ':' assume IPv6 */
  547. if (strchr(ipasc, ':'))
  548. {
  549. if (!ipv6_from_asc(ipout, ipasc))
  550. return 0;
  551. return 16;
  552. }
  553. else
  554. {
  555. if (!ipv4_from_asc(ipout, ipasc))
  556. return 0;
  557. return 4;
  558. }
  559. }
  560. static int ipv4_from_asc(unsigned char *v4, const char *in)
  561. {
  562. int a0, a1, a2, a3;
  563. if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
  564. return 0;
  565. if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
  566. || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
  567. return 0;
  568. v4[0] = a0;
  569. v4[1] = a1;
  570. v4[2] = a2;
  571. v4[3] = a3;
  572. return 1;
  573. }
  574. typedef struct {
  575. /* Temporary store for IPV6 output */
  576. unsigned char tmp[16];
  577. /* Total number of bytes in tmp */
  578. int total;
  579. /* The position of a zero (corresponding to '::') */
  580. int zero_pos;
  581. /* Number of zeroes */
  582. int zero_cnt;
  583. } IPV6_STAT;
  584. static int ipv6_from_asc(unsigned char *v6, const char *in)
  585. {
  586. IPV6_STAT v6stat;
  587. v6stat.total = 0;
  588. v6stat.zero_pos = -1;
  589. v6stat.zero_cnt = 0;
  590. /* Treat the IPv6 representation as a list of values
  591.  * separated by ':'. The presence of a '::' will parse
  592.    * as one, two or three zero length elements.
  593.  */
  594. if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
  595. return 0;
  596. /* Now for some sanity checks */
  597. if (v6stat.zero_pos == -1)
  598. {
  599. /* If no '::' must have exactly 16 bytes */
  600. if (v6stat.total != 16)
  601. return 0;
  602. }
  603. else 
  604. {
  605. /* If '::' must have less than 16 bytes */
  606. if (v6stat.total == 16)
  607. return 0;
  608. /* More than three zeroes is an error */
  609. if (v6stat.zero_cnt > 3)
  610. return 0;
  611. /* Can only have three zeroes if nothing else present */
  612. else if (v6stat.zero_cnt == 3)
  613. {
  614. if (v6stat.total > 0)
  615. return 0;
  616. }
  617. /* Can only have two zeroes if at start or end */
  618. else if (v6stat.zero_cnt == 2)
  619. {
  620. if ((v6stat.zero_pos != 0)
  621. && (v6stat.zero_pos != v6stat.total))
  622. return 0;
  623. }
  624. else 
  625. /* Can only have one zero if *not* start or end */
  626. {
  627. if ((v6stat.zero_pos == 0)
  628. || (v6stat.zero_pos == v6stat.total))
  629. return 0;
  630. }
  631. }
  632. /* Format result */
  633. /* Copy initial part */
  634. if (v6stat.zero_pos > 0)
  635. memcpy(v6, v6stat.tmp, v6stat.zero_pos);
  636. /* Zero middle */
  637. if (v6stat.total != 16)
  638. memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
  639. /* Copy final part */
  640. if (v6stat.total != v6stat.zero_pos)
  641. memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
  642. v6stat.tmp + v6stat.zero_pos,
  643. v6stat.total - v6stat.zero_pos);
  644. return 1;
  645. }
  646. static int ipv6_cb(const char *elem, int len, void *usr)
  647. {
  648. IPV6_STAT *s = usr;
  649. /* Error if 16 bytes written */
  650. if (s->total == 16)
  651. return 0;
  652. if (len == 0)
  653. {
  654. /* Zero length element, corresponds to '::' */
  655. if (s->zero_pos == -1)
  656. s->zero_pos = s->total;
  657. /* If we've already got a :: its an error */
  658. else if (s->zero_pos != s->total)
  659. return 0;
  660. s->zero_cnt++;
  661. }
  662. else 
  663. {
  664. /* If more than 4 characters could be final a.b.c.d form */
  665. if (len > 4)
  666. {
  667. /* Need at least 4 bytes left */
  668. if (s->total > 12)
  669. return 0;
  670. /* Must be end of string */
  671. if (elem[len])
  672. return 0;
  673. if (!ipv4_from_asc(s->tmp + s->total, elem))
  674. return 0;
  675. s->total += 4;
  676. }
  677. else
  678. {
  679. if (!ipv6_hex(s->tmp + s->total, elem, len))
  680. return 0;
  681. s->total += 2;
  682. }
  683. }
  684. return 1;
  685. }
  686. /* Convert a string of up to 4 hex digits into the corresponding
  687.  * IPv6 form.
  688.  */
  689. static int ipv6_hex(unsigned char *out, const char *in, int inlen)
  690. {
  691. unsigned char c;
  692. unsigned int num = 0;
  693. if (inlen > 4)
  694. return 0;
  695. while(inlen--)
  696. {
  697. c = *in++;
  698. num <<= 4;
  699. if ((c >= '0') && (c <= '9'))
  700. num |= c - '0';
  701. else if ((c >= 'A') && (c <= 'F'))
  702. num |= c - 'A' + 10;
  703. else if ((c >= 'a') && (c <= 'f'))
  704. num |=  c - 'a' + 10;
  705. else
  706. return 0;
  707. }
  708. out[0] = num >> 8;
  709. out[1] = num & 0xff;
  710. return 1;
  711. }
  712. int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
  713. unsigned long chtype)
  714. {
  715. CONF_VALUE *v;
  716. int i, mval;
  717. char *p, *type;
  718. if (!nm)
  719. return 0;
  720. for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
  721. {
  722. v=sk_CONF_VALUE_value(dn_sk,i);
  723. type=v->name;
  724. /* Skip past any leading X. X: X, etc to allow for
  725.  * multiple instances 
  726.  */
  727. for(p = type; *p ; p++) 
  728. #ifndef CHARSET_EBCDIC
  729. if ((*p == ':') || (*p == ',') || (*p == '.'))
  730. #else
  731. if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.']))
  732. #endif
  733. {
  734. p++;
  735. if(*p) type = p;
  736. break;
  737. }
  738. #ifndef CHARSET_EBCDIC
  739. if (*type == '+')
  740. #else
  741. if (*type == os_toascii['+'])
  742. #endif
  743. {
  744. mval = -1;
  745. type++;
  746. }
  747. else
  748. mval = 0;
  749. if (!X509_NAME_add_entry_by_txt(nm,type, chtype,
  750. (unsigned char *) v->value,-1,-1,mval))
  751. return 0;
  752. }
  753. return 1;
  754. }