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