You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

528 lines
14 KiB

  1. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  2. * All rights reserved.
  3. *
  4. * This package is an SSL implementation written
  5. * by Eric Young (eay@cryptsoft.com).
  6. * The implementation was written so as to conform with Netscapes SSL.
  7. *
  8. * This library is free for commercial and non-commercial use as long as
  9. * the following conditions are aheared to. The following conditions
  10. * apply to all code found in this distribution, be it the RC4, RSA,
  11. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  12. * included with this distribution is covered by the same copyright terms
  13. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  14. *
  15. * Copyright remains Eric Young's, and as such any Copyright notices in
  16. * the code are not to be removed.
  17. * If this package is used in a product, Eric Young should be given attribution
  18. * as the author of the parts of the library used.
  19. * This can be in the form of a textual message at program startup or
  20. * in documentation (online or textual) provided with the package.
  21. *
  22. * Redistribution and use in source and binary forms, with or without
  23. * modification, are permitted provided that the following conditions
  24. * are met:
  25. * 1. Redistributions of source code must retain the copyright
  26. * notice, this list of conditions and the following disclaimer.
  27. * 2. Redistributions in binary form must reproduce the above copyright
  28. * notice, this list of conditions and the following disclaimer in the
  29. * documentation and/or other materials provided with the distribution.
  30. * 3. All advertising materials mentioning features or use of this software
  31. * must display the following acknowledgement:
  32. * "This product includes cryptographic software written by
  33. * Eric Young (eay@cryptsoft.com)"
  34. * The word 'cryptographic' can be left out if the rouines from the library
  35. * being used are not cryptographic related :-).
  36. * 4. If you include any Windows specific code (or a derivative thereof) from
  37. * the apps directory (application code) you must include an acknowledgement:
  38. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  41. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  43. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  44. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  48. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  49. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  50. * SUCH DAMAGE.
  51. *
  52. * The licence and distribution terms for any publically available version or
  53. * derivative of this code cannot be changed. i.e. this code cannot simply be
  54. * copied and put under another distribution licence
  55. * [including the GNU Public Licence.] */
  56. #include <ctype.h>
  57. #include <openssl/asn1.h>
  58. #include <openssl/asn1t.h>
  59. #include <openssl/buf.h>
  60. #include <openssl/err.h>
  61. #include <openssl/mem.h>
  62. #include <openssl/obj.h>
  63. #include <openssl/stack.h>
  64. #include <openssl/x509.h>
  65. #include "../asn1/asn1_locl.h"
  66. typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
  67. DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
  68. static int x509_name_ex_d2i(ASN1_VALUE **val,
  69. const unsigned char **in, long len,
  70. const ASN1_ITEM *it,
  71. int tag, int aclass, char opt, ASN1_TLC *ctx);
  72. static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
  73. const ASN1_ITEM *it, int tag, int aclass);
  74. static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
  75. static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
  76. static int x509_name_encode(X509_NAME *a);
  77. static int x509_name_canon(X509_NAME *a);
  78. static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
  79. static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
  80. unsigned char **in);
  81. static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
  82. int indent,
  83. const char *fname,
  84. const ASN1_PCTX *pctx);
  85. ASN1_SEQUENCE(X509_NAME_ENTRY) = {
  86. ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
  87. ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
  88. } ASN1_SEQUENCE_END(X509_NAME_ENTRY)
  89. IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
  90. IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
  91. /* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY }
  92. * so declare two template wrappers for this
  93. */
  94. ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
  95. ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
  96. ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
  97. ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
  98. ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
  99. ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
  100. /* Normally that's where it would end: we'd have two nested STACK structures
  101. * representing the ASN1. Unfortunately X509_NAME uses a completely different
  102. * form and caches encodings so we have to process the internal form and convert
  103. * to the external form.
  104. */
  105. const ASN1_EXTERN_FUNCS x509_name_ff = {
  106. NULL,
  107. x509_name_ex_new,
  108. x509_name_ex_free,
  109. 0, /* Default clear behaviour is OK */
  110. x509_name_ex_d2i,
  111. x509_name_ex_i2d,
  112. x509_name_ex_print
  113. };
  114. IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
  115. IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
  116. IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
  117. static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
  118. {
  119. X509_NAME *ret = NULL;
  120. ret = OPENSSL_malloc(sizeof(X509_NAME));
  121. if(!ret) goto memerr;
  122. if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL)
  123. goto memerr;
  124. if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr;
  125. ret->canon_enc = NULL;
  126. ret->canon_enclen = 0;
  127. ret->modified=1;
  128. *val = (ASN1_VALUE *)ret;
  129. return 1;
  130. memerr:
  131. OPENSSL_PUT_ERROR(X509, x509_name_ex_new, ERR_R_MALLOC_FAILURE);
  132. if (ret)
  133. {
  134. if (ret->entries)
  135. sk_X509_NAME_ENTRY_free(ret->entries);
  136. OPENSSL_free(ret);
  137. }
  138. return 0;
  139. }
  140. static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
  141. {
  142. X509_NAME *a;
  143. if(!pval || !*pval)
  144. return;
  145. a = (X509_NAME *)*pval;
  146. BUF_MEM_free(a->bytes);
  147. sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free);
  148. if (a->canon_enc)
  149. OPENSSL_free(a->canon_enc);
  150. OPENSSL_free(a);
  151. *pval = NULL;
  152. }
  153. static int x509_name_ex_d2i(ASN1_VALUE **val,
  154. const unsigned char **in, long len, const ASN1_ITEM *it,
  155. int tag, int aclass, char opt, ASN1_TLC *ctx)
  156. {
  157. const unsigned char *p = *in, *q;
  158. union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
  159. ASN1_VALUE *a; } intname = {NULL};
  160. union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL};
  161. size_t i, j;
  162. int ret;
  163. STACK_OF(X509_NAME_ENTRY) *entries;
  164. X509_NAME_ENTRY *entry;
  165. q = p;
  166. /* Get internal representation of Name */
  167. ret = ASN1_item_ex_d2i(&intname.a,
  168. &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
  169. tag, aclass, opt, ctx);
  170. if(ret <= 0) return ret;
  171. if(*val) x509_name_ex_free(val, NULL);
  172. if(!x509_name_ex_new(&nm.a, NULL)) goto err;
  173. /* We've decoded it: now cache encoding */
  174. if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err;
  175. memcpy(nm.x->bytes->data, q, p - q);
  176. /* Convert internal representation to X509_NAME structure */
  177. for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
  178. entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
  179. for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
  180. entry = sk_X509_NAME_ENTRY_value(entries, j);
  181. entry->set = i;
  182. if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
  183. goto err;
  184. }
  185. sk_X509_NAME_ENTRY_free(entries);
  186. }
  187. sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
  188. ret = x509_name_canon(nm.x);
  189. if (!ret)
  190. goto err;
  191. nm.x->modified = 0;
  192. *val = nm.a;
  193. *in = p;
  194. return ret;
  195. err:
  196. if (nm.x != NULL)
  197. X509_NAME_free(nm.x);
  198. OPENSSL_PUT_ERROR(X509, x509_name_ex_d2i, ERR_R_ASN1_LIB);
  199. return 0;
  200. }
  201. static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
  202. {
  203. int ret;
  204. X509_NAME *a = (X509_NAME *)*val;
  205. if(a->modified) {
  206. ret = x509_name_encode(a);
  207. if(ret < 0)
  208. return ret;
  209. ret = x509_name_canon(a);
  210. if(ret < 0)
  211. return ret;
  212. }
  213. ret = a->bytes->length;
  214. if(out != NULL) {
  215. memcpy(*out,a->bytes->data,ret);
  216. *out+=ret;
  217. }
  218. return ret;
  219. }
  220. static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
  221. {
  222. sk_X509_NAME_ENTRY_free(ne);
  223. }
  224. static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
  225. {
  226. sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
  227. }
  228. static int x509_name_encode(X509_NAME *a)
  229. {
  230. union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
  231. ASN1_VALUE *a; } intname = {NULL};
  232. int len;
  233. unsigned char *p;
  234. STACK_OF(X509_NAME_ENTRY) *entries = NULL;
  235. X509_NAME_ENTRY *entry;
  236. int set = -1;
  237. size_t i;
  238. intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
  239. if(!intname.s) goto memerr;
  240. for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
  241. entry = sk_X509_NAME_ENTRY_value(a->entries, i);
  242. if(entry->set != set) {
  243. entries = sk_X509_NAME_ENTRY_new_null();
  244. if(!entries) goto memerr;
  245. if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
  246. entries))
  247. goto memerr;
  248. set = entry->set;
  249. }
  250. if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr;
  251. }
  252. len = ASN1_item_ex_i2d(&intname.a, NULL,
  253. ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
  254. if (!BUF_MEM_grow(a->bytes,len)) goto memerr;
  255. p=(unsigned char *)a->bytes->data;
  256. ASN1_item_ex_i2d(&intname.a,
  257. &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
  258. sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
  259. local_sk_X509_NAME_ENTRY_free);
  260. a->modified = 0;
  261. return len;
  262. memerr:
  263. sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
  264. local_sk_X509_NAME_ENTRY_free);
  265. OPENSSL_PUT_ERROR(X509, x509_name_encode, ERR_R_MALLOC_FAILURE);
  266. return -1;
  267. }
  268. static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
  269. int indent,
  270. const char *fname,
  271. const ASN1_PCTX *pctx)
  272. {
  273. if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
  274. indent, pctx->nm_flags) <= 0)
  275. return 0;
  276. return 2;
  277. }
  278. /* This function generates the canonical encoding of the Name structure.
  279. * In it all strings are converted to UTF8, leading, trailing and
  280. * multiple spaces collapsed, converted to lower case and the leading
  281. * SEQUENCE header removed.
  282. *
  283. * In future we could also normalize the UTF8 too.
  284. *
  285. * By doing this comparison of Name structures can be rapidly
  286. * perfomed by just using memcmp() of the canonical encoding.
  287. * By omitting the leading SEQUENCE name constraints of type
  288. * dirName can also be checked with a simple memcmp().
  289. */
  290. static int x509_name_canon(X509_NAME *a)
  291. {
  292. unsigned char *p;
  293. STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
  294. STACK_OF(X509_NAME_ENTRY) *entries = NULL;
  295. X509_NAME_ENTRY *entry, *tmpentry = NULL;
  296. int set = -1, ret = 0;
  297. size_t i;
  298. if (a->canon_enc)
  299. {
  300. OPENSSL_free(a->canon_enc);
  301. a->canon_enc = NULL;
  302. }
  303. /* Special case: empty X509_NAME => null encoding */
  304. if (sk_X509_NAME_ENTRY_num(a->entries) == 0)
  305. {
  306. a->canon_enclen = 0;
  307. return 1;
  308. }
  309. intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
  310. if(!intname)
  311. goto err;
  312. for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++)
  313. {
  314. entry = sk_X509_NAME_ENTRY_value(a->entries, i);
  315. if(entry->set != set)
  316. {
  317. entries = sk_X509_NAME_ENTRY_new_null();
  318. if(!entries)
  319. goto err;
  320. if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
  321. goto err;
  322. set = entry->set;
  323. }
  324. tmpentry = X509_NAME_ENTRY_new();
  325. tmpentry->object = OBJ_dup(entry->object);
  326. if (!asn1_string_canon(tmpentry->value, entry->value))
  327. goto err;
  328. if(!sk_X509_NAME_ENTRY_push(entries, tmpentry))
  329. goto err;
  330. tmpentry = NULL;
  331. }
  332. /* Finally generate encoding */
  333. a->canon_enclen = i2d_name_canon(intname, NULL);
  334. p = OPENSSL_malloc(a->canon_enclen);
  335. if (!p)
  336. goto err;
  337. a->canon_enc = p;
  338. i2d_name_canon(intname, &p);
  339. ret = 1;
  340. err:
  341. if (tmpentry)
  342. X509_NAME_ENTRY_free(tmpentry);
  343. if (intname)
  344. sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
  345. local_sk_X509_NAME_ENTRY_pop_free);
  346. return ret;
  347. }
  348. /* Bitmap of all the types of string that will be canonicalized. */
  349. #define ASN1_MASK_CANON \
  350. (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
  351. | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
  352. | B_ASN1_VISIBLESTRING)
  353. static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
  354. {
  355. unsigned char *to, *from;
  356. int len, i;
  357. /* If type not in bitmask just copy string across */
  358. if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
  359. {
  360. if (!ASN1_STRING_copy(out, in))
  361. return 0;
  362. return 1;
  363. }
  364. out->type = V_ASN1_UTF8STRING;
  365. out->length = ASN1_STRING_to_UTF8(&out->data, in);
  366. if (out->length == -1)
  367. return 0;
  368. to = out->data;
  369. from = to;
  370. len = out->length;
  371. /* Convert string in place to canonical form.
  372. * Ultimately we may need to handle a wider range of characters
  373. * but for now ignore anything with MSB set and rely on the
  374. * isspace() and tolower() functions.
  375. */
  376. /* Ignore leading spaces */
  377. while((len > 0) && !(*from & 0x80) && isspace(*from))
  378. {
  379. from++;
  380. len--;
  381. }
  382. to = from + len - 1;
  383. /* Ignore trailing spaces */
  384. while ((len > 0) && !(*to & 0x80) && isspace(*to))
  385. {
  386. to--;
  387. len--;
  388. }
  389. to = out->data;
  390. i = 0;
  391. while(i < len)
  392. {
  393. /* If MSB set just copy across */
  394. if (*from & 0x80)
  395. {
  396. *to++ = *from++;
  397. i++;
  398. }
  399. /* Collapse multiple spaces */
  400. else if (isspace(*from))
  401. {
  402. /* Copy one space across */
  403. *to++ = ' ';
  404. /* Ignore subsequent spaces. Note: don't need to
  405. * check len here because we know the last
  406. * character is a non-space so we can't overflow.
  407. */
  408. do
  409. {
  410. from++;
  411. i++;
  412. }
  413. while(!(*from & 0x80) && isspace(*from));
  414. }
  415. else
  416. {
  417. *to++ = tolower(*from);
  418. from++;
  419. i++;
  420. }
  421. }
  422. out->length = to - out->data;
  423. return 1;
  424. }
  425. static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname,
  426. unsigned char **in)
  427. {
  428. int len, ltmp;
  429. size_t i;
  430. ASN1_VALUE *v;
  431. STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
  432. len = 0;
  433. for (i = 0; i < sk_ASN1_VALUE_num(intname); i++)
  434. {
  435. v = sk_ASN1_VALUE_value(intname, i);
  436. ltmp = ASN1_item_ex_i2d(&v, in,
  437. ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
  438. if (ltmp < 0)
  439. return ltmp;
  440. len += ltmp;
  441. }
  442. return len;
  443. }
  444. int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
  445. {
  446. X509_NAME *in;
  447. if (!xn || !name) return(0);
  448. if (*xn != name)
  449. {
  450. in=X509_NAME_dup(name);
  451. if (in != NULL)
  452. {
  453. X509_NAME_free(*xn);
  454. *xn=in;
  455. }
  456. }
  457. return(*xn != NULL);
  458. }
  459. IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)