1 /* $OpenBSD: x_name.c,v 1.44 2024/07/08 14:48:49 beck Exp $ */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "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 <ctype.h> 60 #include <stdio.h> 61 #include <string.h> 62 63 #include <openssl/asn1t.h> 64 #include <openssl/err.h> 65 #include <openssl/x509.h> 66 67 #include "asn1_local.h" 68 #include "x509_local.h" 69 70 typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; 71 DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY) 72 73 static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, 74 long len, const ASN1_ITEM *it, int tag, int aclass, char opt, 75 ASN1_TLC *ctx); 76 77 static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, 78 const ASN1_ITEM *it, int tag, int aclass); 79 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); 80 static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); 81 82 static int x509_name_encode(X509_NAME *a); 83 static int x509_name_canon(X509_NAME *a); 84 static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); 85 static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname, 86 unsigned char **in); 87 88 static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, int indent, 89 const char *fname, const ASN1_PCTX *pctx); 90 91 static const ASN1_TEMPLATE X509_NAME_ENTRY_seq_tt[] = { 92 { 93 .offset = offsetof(X509_NAME_ENTRY, object), 94 .field_name = "object", 95 .item = &ASN1_OBJECT_it, 96 }, 97 { 98 .offset = offsetof(X509_NAME_ENTRY, value), 99 .field_name = "value", 100 .item = &ASN1_PRINTABLE_it, 101 }, 102 }; 103 104 const ASN1_ITEM X509_NAME_ENTRY_it = { 105 .itype = ASN1_ITYPE_SEQUENCE, 106 .utype = V_ASN1_SEQUENCE, 107 .templates = X509_NAME_ENTRY_seq_tt, 108 .tcount = sizeof(X509_NAME_ENTRY_seq_tt) / sizeof(ASN1_TEMPLATE), 109 .size = sizeof(X509_NAME_ENTRY), 110 .sname = "X509_NAME_ENTRY", 111 }; 112 LCRYPTO_ALIAS(X509_NAME_ENTRY_it); 113 114 115 X509_NAME_ENTRY * 116 d2i_X509_NAME_ENTRY(X509_NAME_ENTRY **a, const unsigned char **in, long len) 117 { 118 return (X509_NAME_ENTRY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 119 &X509_NAME_ENTRY_it); 120 } 121 LCRYPTO_ALIAS(d2i_X509_NAME_ENTRY); 122 123 int 124 i2d_X509_NAME_ENTRY(X509_NAME_ENTRY *a, unsigned char **out) 125 { 126 return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_NAME_ENTRY_it); 127 } 128 LCRYPTO_ALIAS(i2d_X509_NAME_ENTRY); 129 130 X509_NAME_ENTRY * 131 X509_NAME_ENTRY_new(void) 132 { 133 return (X509_NAME_ENTRY *)ASN1_item_new(&X509_NAME_ENTRY_it); 134 } 135 LCRYPTO_ALIAS(X509_NAME_ENTRY_new); 136 137 void 138 X509_NAME_ENTRY_free(X509_NAME_ENTRY *a) 139 { 140 ASN1_item_free((ASN1_VALUE *)a, &X509_NAME_ENTRY_it); 141 } 142 LCRYPTO_ALIAS(X509_NAME_ENTRY_free); 143 144 X509_NAME_ENTRY * 145 X509_NAME_ENTRY_dup(X509_NAME_ENTRY *x) 146 { 147 return ASN1_item_dup(&X509_NAME_ENTRY_it, x); 148 } 149 LCRYPTO_ALIAS(X509_NAME_ENTRY_dup); 150 151 /* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } 152 * so declare two template wrappers for this 153 */ 154 155 static const ASN1_TEMPLATE X509_NAME_ENTRIES_item_tt = { 156 .flags = ASN1_TFLG_SET_OF, 157 .tag = 0, 158 .offset = 0, 159 .field_name = "RDNS", 160 .item = &X509_NAME_ENTRY_it, 161 }; 162 163 static const ASN1_ITEM X509_NAME_ENTRIES_it = { 164 .itype = ASN1_ITYPE_PRIMITIVE, 165 .utype = -1, 166 .templates = &X509_NAME_ENTRIES_item_tt, 167 .tcount = 0, 168 .funcs = NULL, 169 .size = 0, 170 .sname = "X509_NAME_ENTRIES", 171 }; 172 173 static const ASN1_TEMPLATE X509_NAME_INTERNAL_item_tt = { 174 .flags = ASN1_TFLG_SEQUENCE_OF, 175 .tag = 0, 176 .offset = 0, 177 .field_name = "Name", 178 .item = &X509_NAME_ENTRIES_it, 179 }; 180 181 static const ASN1_ITEM X509_NAME_INTERNAL_it = { 182 .itype = ASN1_ITYPE_PRIMITIVE, 183 .utype = -1, 184 .templates = &X509_NAME_INTERNAL_item_tt, 185 .tcount = 0, 186 .funcs = NULL, 187 .size = 0, 188 .sname = "X509_NAME_INTERNAL", 189 }; 190 191 /* Normally that's where it would end: we'd have two nested STACK structures 192 * representing the ASN1. Unfortunately X509_NAME uses a completely different 193 * form and caches encodings so we have to process the internal form and convert 194 * to the external form. 195 */ 196 197 const ASN1_EXTERN_FUNCS x509_name_ff = { 198 .app_data = NULL, 199 .asn1_ex_new = x509_name_ex_new, 200 .asn1_ex_free = x509_name_ex_free, 201 .asn1_ex_clear = NULL, 202 .asn1_ex_d2i = x509_name_ex_d2i, 203 .asn1_ex_i2d = x509_name_ex_i2d, 204 .asn1_ex_print = x509_name_ex_print, 205 }; 206 207 const ASN1_ITEM X509_NAME_it = { 208 .itype = ASN1_ITYPE_EXTERN, 209 .utype = V_ASN1_SEQUENCE, 210 .templates = NULL, 211 .tcount = 0, 212 .funcs = &x509_name_ff, 213 .size = 0, 214 .sname = "X509_NAME", 215 }; 216 LCRYPTO_ALIAS(X509_NAME_it); 217 218 X509_NAME * 219 d2i_X509_NAME(X509_NAME **a, const unsigned char **in, long len) 220 { 221 return (X509_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, 222 &X509_NAME_it); 223 } 224 LCRYPTO_ALIAS(d2i_X509_NAME); 225 226 int 227 i2d_X509_NAME(X509_NAME *a, unsigned char **out) 228 { 229 return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_NAME_it); 230 } 231 LCRYPTO_ALIAS(i2d_X509_NAME); 232 233 X509_NAME * 234 X509_NAME_new(void) 235 { 236 return (X509_NAME *)ASN1_item_new(&X509_NAME_it); 237 } 238 LCRYPTO_ALIAS(X509_NAME_new); 239 240 void 241 X509_NAME_free(X509_NAME *a) 242 { 243 ASN1_item_free((ASN1_VALUE *)a, &X509_NAME_it); 244 } 245 LCRYPTO_ALIAS(X509_NAME_free); 246 247 X509_NAME * 248 X509_NAME_dup(X509_NAME *x) 249 { 250 return ASN1_item_dup(&X509_NAME_it, x); 251 } 252 LCRYPTO_ALIAS(X509_NAME_dup); 253 254 static int 255 x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) 256 { 257 X509_NAME *ret = NULL; 258 259 ret = malloc(sizeof(X509_NAME)); 260 if (!ret) 261 goto memerr; 262 if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) 263 goto memerr; 264 if ((ret->bytes = BUF_MEM_new()) == NULL) 265 goto memerr; 266 ret->canon_enc = NULL; 267 ret->canon_enclen = 0; 268 ret->modified = 1; 269 *val = (ASN1_VALUE *)ret; 270 return 1; 271 272 memerr: 273 ASN1error(ERR_R_MALLOC_FAILURE); 274 if (ret) { 275 if (ret->entries) 276 sk_X509_NAME_ENTRY_free(ret->entries); 277 free(ret); 278 } 279 return 0; 280 } 281 282 static void 283 x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 284 { 285 X509_NAME *a; 286 287 if (!pval || !*pval) 288 return; 289 a = (X509_NAME *)*pval; 290 291 BUF_MEM_free(a->bytes); 292 sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free); 293 free(a->canon_enc); 294 free(a); 295 *pval = NULL; 296 } 297 298 static int 299 x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len, 300 const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx) 301 { 302 const unsigned char *p = *in, *q; 303 union { 304 STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; 305 ASN1_VALUE *a; 306 } intname = {NULL}; 307 union { 308 X509_NAME *x; 309 ASN1_VALUE *a; 310 } nm = {NULL}; 311 int i, j, ret; 312 STACK_OF(X509_NAME_ENTRY) *entries; 313 X509_NAME_ENTRY *entry; 314 q = p; 315 316 /* Get internal representation of Name */ 317 ret = ASN1_item_ex_d2i(&intname.a, &p, len, 318 &X509_NAME_INTERNAL_it, tag, aclass, opt, ctx); 319 320 if (ret <= 0) 321 return ret; 322 323 if (*val) 324 x509_name_ex_free(val, NULL); 325 if (!x509_name_ex_new(&nm.a, NULL)) 326 goto err; 327 /* We've decoded it: now cache encoding */ 328 if (!BUF_MEM_grow(nm.x->bytes, p - q)) 329 goto err; 330 memcpy(nm.x->bytes->data, q, p - q); 331 332 /* Convert internal representation to X509_NAME structure */ 333 for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) { 334 entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i); 335 for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { 336 entry = sk_X509_NAME_ENTRY_value(entries, j); 337 entry->set = i; 338 if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) 339 goto err; 340 } 341 sk_X509_NAME_ENTRY_free(entries); 342 } 343 sk_STACK_OF_X509_NAME_ENTRY_free(intname.s); 344 ret = x509_name_canon(nm.x); 345 if (!ret) 346 goto err; 347 nm.x->modified = 0; 348 *val = nm.a; 349 *in = p; 350 return ret; 351 352 err: 353 if (nm.x != NULL) 354 X509_NAME_free(nm.x); 355 ASN1error(ERR_R_NESTED_ASN1_ERROR); 356 return 0; 357 } 358 359 static int 360 x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, 361 int tag, int aclass) 362 { 363 int ret; 364 X509_NAME *a = (X509_NAME *)*val; 365 366 if (a->modified) { 367 ret = x509_name_encode(a); 368 if (ret < 0) 369 return ret; 370 ret = x509_name_canon(a); 371 if (ret < 0) 372 return ret; 373 } 374 ret = a->bytes->length; 375 if (out != NULL) { 376 memcpy(*out, a->bytes->data, ret); 377 *out += ret; 378 } 379 return ret; 380 } 381 382 static void 383 local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) 384 { 385 sk_X509_NAME_ENTRY_free(ne); 386 } 387 388 static void 389 local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) 390 { 391 sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); 392 } 393 394 static int 395 x509_name_encode(X509_NAME *a) 396 { 397 union { 398 STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; 399 ASN1_VALUE *a; 400 } intname = {NULL}; 401 int len; 402 unsigned char *p; 403 STACK_OF(X509_NAME_ENTRY) *entries = NULL; 404 X509_NAME_ENTRY *entry; 405 int i, set = -1; 406 407 intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); 408 if (!intname.s) 409 goto memerr; 410 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { 411 entry = sk_X509_NAME_ENTRY_value(a->entries, i); 412 if (entry->set != set) { 413 entries = sk_X509_NAME_ENTRY_new_null(); 414 if (!entries) 415 goto memerr; 416 if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, 417 entries)) 418 goto memerr; 419 set = entry->set; 420 } 421 if (entries == NULL /* if entry->set is bogusly -1 */ || 422 !sk_X509_NAME_ENTRY_push(entries, entry)) 423 goto memerr; 424 } 425 len = ASN1_item_ex_i2d(&intname.a, NULL, 426 &X509_NAME_INTERNAL_it, -1, -1); 427 if (!BUF_MEM_grow(a->bytes, len)) 428 goto memerr; 429 p = (unsigned char *)a->bytes->data; 430 ASN1_item_ex_i2d(&intname.a, &p, &X509_NAME_INTERNAL_it, 431 -1, -1); 432 sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, 433 local_sk_X509_NAME_ENTRY_free); 434 a->modified = 0; 435 return len; 436 437 memerr: 438 sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, 439 local_sk_X509_NAME_ENTRY_free); 440 ASN1error(ERR_R_MALLOC_FAILURE); 441 return -1; 442 } 443 444 static int 445 x509_name_ex_print(BIO *out, ASN1_VALUE **pval, int indent, const char *fname, 446 const ASN1_PCTX *pctx) 447 { 448 if (X509_NAME_print_ex(out, (X509_NAME *)*pval, indent, 449 pctx->nm_flags) <= 0) 450 return 0; 451 return 2; 452 } 453 454 /* This function generates the canonical encoding of the Name structure. 455 * In it all strings are converted to UTF8, leading, trailing and 456 * multiple spaces collapsed, converted to lower case and the leading 457 * SEQUENCE header removed. 458 * 459 * In future we could also normalize the UTF8 too. 460 * 461 * By doing this comparison of Name structures can be rapidly 462 * performed by just using memcmp() of the canonical encoding. 463 * By omitting the leading SEQUENCE name constraints of type 464 * dirName can also be checked with a simple memcmp(). 465 */ 466 467 static int 468 x509_name_canon(X509_NAME *a) 469 { 470 unsigned char *p; 471 STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; 472 STACK_OF(X509_NAME_ENTRY) *entries = NULL; 473 X509_NAME_ENTRY *entry, *tmpentry = NULL; 474 int i, len, set = -1, ret = 0; 475 476 if (a->canon_enc) { 477 free(a->canon_enc); 478 a->canon_enc = NULL; 479 } 480 /* Special case: empty X509_NAME => null encoding */ 481 if (sk_X509_NAME_ENTRY_num(a->entries) == 0) { 482 a->canon_enclen = 0; 483 return 1; 484 } 485 intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); 486 if (!intname) 487 goto err; 488 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { 489 entry = sk_X509_NAME_ENTRY_value(a->entries, i); 490 if (entry->set != set) { 491 entries = sk_X509_NAME_ENTRY_new_null(); 492 if (!entries) 493 goto err; 494 if (sk_STACK_OF_X509_NAME_ENTRY_push(intname, 495 entries) == 0) { 496 sk_X509_NAME_ENTRY_free(entries); 497 goto err; 498 } 499 set = entry->set; 500 } 501 tmpentry = X509_NAME_ENTRY_new(); 502 if (tmpentry == NULL) 503 goto err; 504 tmpentry->object = OBJ_dup(entry->object); 505 if (tmpentry->object == NULL) 506 goto err; 507 if (!asn1_string_canon(tmpentry->value, entry->value)) 508 goto err; 509 if (entries == NULL /* if entry->set is bogusly -1 */ || 510 !sk_X509_NAME_ENTRY_push(entries, tmpentry)) 511 goto err; 512 tmpentry = NULL; 513 } 514 515 /* Finally generate encoding */ 516 len = i2d_name_canon(intname, NULL); 517 if (len < 0) 518 goto err; 519 p = malloc(len); 520 if (p == NULL) 521 goto err; 522 a->canon_enc = p; 523 a->canon_enclen = len; 524 i2d_name_canon(intname, &p); 525 ret = 1; 526 527 err: 528 if (tmpentry) 529 X509_NAME_ENTRY_free(tmpentry); 530 if (intname) 531 sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, 532 local_sk_X509_NAME_ENTRY_pop_free); 533 return ret; 534 } 535 536 /* Bitmap of all the types of string that will be canonicalized. */ 537 538 #define ASN1_MASK_CANON \ 539 (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ 540 | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ 541 | B_ASN1_VISIBLESTRING) 542 543 544 static int 545 asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) 546 { 547 unsigned char *to, *from; 548 int len, i; 549 550 /* If type not in bitmask just copy string across */ 551 if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) { 552 if (!ASN1_STRING_copy(out, in)) 553 return 0; 554 return 1; 555 } 556 557 out->type = V_ASN1_UTF8STRING; 558 out->length = ASN1_STRING_to_UTF8(&out->data, in); 559 if (out->length == -1) 560 return 0; 561 562 to = out->data; 563 from = to; 564 565 len = out->length; 566 567 /* Convert string in place to canonical form. 568 * Ultimately we may need to handle a wider range of characters 569 * but for now ignore anything with MSB set and rely on the 570 * isspace() and tolower() functions. 571 */ 572 573 /* Ignore leading spaces */ 574 while ((len > 0) && !(*from & 0x80) && isspace(*from)) { 575 from++; 576 len--; 577 } 578 579 to = from + len - 1; 580 581 /* Ignore trailing spaces */ 582 while ((len > 0) && !(*to & 0x80) && isspace(*to)) { 583 to--; 584 len--; 585 } 586 587 to = out->data; 588 589 i = 0; 590 while (i < len) { 591 /* If MSB set just copy across */ 592 if (*from & 0x80) { 593 *to++ = *from++; 594 i++; 595 } 596 /* Collapse multiple spaces */ 597 else if (isspace(*from)) { 598 /* Copy one space across */ 599 *to++ = ' '; 600 /* Ignore subsequent spaces. Note: don't need to 601 * check len here because we know the last 602 * character is a non-space so we can't overflow. 603 */ 604 do { 605 from++; 606 i++; 607 } while (!(*from & 0x80) && isspace(*from)); 608 } else { 609 *to++ = tolower(*from); 610 from++; 611 i++; 612 } 613 } 614 615 out->length = to - out->data; 616 617 return 1; 618 } 619 620 static int 621 i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname, unsigned char **in) 622 { 623 int i, len, ltmp; 624 ASN1_VALUE *v; 625 STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; 626 627 len = 0; 628 for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) { 629 v = sk_ASN1_VALUE_value(intname, i); 630 ltmp = ASN1_item_ex_i2d(&v, in, 631 &X509_NAME_ENTRIES_it, -1, -1); 632 if (ltmp < 0) 633 return ltmp; 634 len += ltmp; 635 } 636 return len; 637 } 638 639 int 640 X509_NAME_set(X509_NAME **xn, X509_NAME *name) 641 { 642 if (*xn == name) 643 return *xn != NULL; 644 if ((name = X509_NAME_dup(name)) == NULL) 645 return 0; 646 X509_NAME_free(*xn); 647 *xn = name; 648 return 1; 649 } 650 LCRYPTO_ALIAS(X509_NAME_set); 651 652 int 653 X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, size_t *pderlen) 654 { 655 /* Make sure encoding is valid. */ 656 if (i2d_X509_NAME(nm, NULL) <= 0) 657 return 0; 658 if (pder != NULL) 659 *pder = (unsigned char *)nm->bytes->data; 660 if (pderlen != NULL) 661 *pderlen = nm->bytes->length; 662 return 1; 663 } 664 LCRYPTO_ALIAS(X509_NAME_get0_der); 665