Return to x509_cert.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / x509 |
1.1 misho 1: /* 2: * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann 3: * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss 4: * Copyright (C) 2002 Mario Strasser 5: * Copyright (C) 2000-2017 Andreas Steffen 6: * Copyright (C) 2006-2009 Martin Willi 7: * Copyright (C) 2008-2017 Tobias Brunner 8: * HSR Hochschule fuer Technik Rapperswil 9: * 10: * This program is free software; you can redistribute it and/or modify it 11: * under the terms of the GNU General Public License as published by the 12: * Free Software Foundation; either version 2 of the License, or (at your 13: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 14: * 15: * This program is distributed in the hope that it will be useful, but 16: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18: * for more details. 19: */ 20: 21: #define _GNU_SOURCE 22: 23: #include <sys/stat.h> 24: #include <time.h> 25: #include <unistd.h> 26: #include <string.h> 27: #include <stdio.h> 28: 29: #include "x509_cert.h" 30: 31: #include <library.h> 32: #include <utils/debug.h> 33: #include <asn1/oid.h> 34: #include <asn1/asn1.h> 35: #include <asn1/asn1_parser.h> 36: #include <crypto/hashers/hasher.h> 37: #include <credentials/keys/private_key.h> 38: #include <collections/linked_list.h> 39: #include <utils/identification.h> 40: #include <selectors/traffic_selector.h> 41: 42: /** 43: * Different kinds of generalNames 44: */ 45: typedef enum { 46: GN_OTHER_NAME = 0, 47: GN_RFC822_NAME = 1, 48: GN_DNS_NAME = 2, 49: GN_X400_ADDRESS = 3, 50: GN_DIRECTORY_NAME = 4, 51: GN_EDI_PARTY_NAME = 5, 52: GN_URI = 6, 53: GN_IP_ADDRESS = 7, 54: GN_REGISTERED_ID = 8, 55: } generalNames_t; 56: 57: 58: typedef struct private_x509_cert_t private_x509_cert_t; 59: 60: /** 61: * Private data of a x509_cert_t object. 62: */ 63: struct private_x509_cert_t { 64: /** 65: * Public interface for this certificate. 66: */ 67: x509_cert_t public; 68: 69: /** 70: * X.509 certificate encoding in ASN.1 DER format 71: */ 72: chunk_t encoding; 73: 74: /** 75: * SHA1 hash of the DER encoding of this X.509 certificate 76: */ 77: chunk_t encoding_hash; 78: 79: /** 80: * X.509 certificate body over which signature is computed 81: */ 82: chunk_t tbsCertificate; 83: 84: /** 85: * Version of the X.509 certificate 86: */ 87: u_int version; 88: 89: /** 90: * Serial number of the X.509 certificate 91: */ 92: chunk_t serialNumber; 93: 94: /** 95: * ID representing the certificate issuer 96: */ 97: identification_t *issuer; 98: 99: /** 100: * Start time of certificate validity 101: */ 102: time_t notBefore; 103: 104: /** 105: * End time of certificate validity 106: */ 107: time_t notAfter; 108: 109: /** 110: * ID representing the certificate subject 111: */ 112: identification_t *subject; 113: 114: /** 115: * List of subjectAltNames as identification_t 116: */ 117: linked_list_t *subjectAltNames; 118: 119: /** 120: * List of crlDistributionPoints as x509_cdp_t* 121: */ 122: linked_list_t *crl_uris; 123: 124: /** 125: * List of ocspAccessLocations as allocated char* 126: */ 127: linked_list_t *ocsp_uris; 128: 129: /** 130: * List of ipAddrBlocks as traffic_selector_t 131: */ 132: linked_list_t *ipAddrBlocks; 133: 134: /** 135: * List of permitted name constraints 136: */ 137: linked_list_t *permitted_names; 138: 139: /** 140: * List of excluded name constraints 141: */ 142: linked_list_t *excluded_names; 143: 144: /** 145: * List of certificatePolicies, as x509_cert_policy_t 146: */ 147: linked_list_t *cert_policies; 148: 149: /** 150: * List of policyMappings, as x509_policy_mapping_t 151: */ 152: linked_list_t *policy_mappings; 153: 154: /** 155: * certificate's embedded public key 156: */ 157: public_key_t *public_key; 158: 159: /** 160: * Subject Key Identifier 161: */ 162: chunk_t subjectKeyIdentifier; 163: 164: /** 165: * Authority Key Identifier 166: */ 167: chunk_t authKeyIdentifier; 168: 169: /** 170: * Authority Key Serial Number 171: */ 172: chunk_t authKeySerialNumber; 173: 174: /** 175: * Optional OID of an [unsupported] critical extension 176: */ 177: chunk_t critical_extension_oid; 178: 179: /** 180: * Path Length Constraint 181: */ 182: u_char pathLenConstraint; 183: 184: /** 185: * requireExplicitPolicy Constraint 186: */ 187: u_char require_explicit; 188: 189: /** 190: * inhibitPolicyMapping Constraint 191: */ 192: u_char inhibit_mapping; 193: 194: /** 195: * inhibitAnyPolicy Constraint 196: */ 197: u_char inhibit_any; 198: 199: /** 200: * x509 constraints and other flags 201: */ 202: x509_flag_t flags; 203: 204: /** 205: * Signature scheme 206: */ 207: signature_params_t *scheme; 208: 209: /** 210: * Signature 211: */ 212: chunk_t signature; 213: 214: /** 215: * Certificate parsed from blob/file? 216: */ 217: bool parsed; 218: 219: /** 220: * reference count 221: */ 222: refcount_t ref; 223: }; 224: 225: /** 226: * Convert a generalName to a string 227: */ 228: static bool gn_to_string(identification_t *id, char **uri) 229: { 230: int len; 231: 232: #ifdef USE_FUZZING 233: chunk_t proper; 234: chunk_printable(id->get_encoding(id), &proper, '?'); 235: len = asprintf(uri, "%.*s", (int)proper.len, proper.ptr); 236: chunk_free(&proper); 237: #else 238: len = asprintf(uri, "%Y", id); 239: #endif 240: if (!len) 241: { 242: free(*uri); 243: return FALSE; 244: } 245: return len > 0; 246: } 247: 248: /** 249: * Destroy a CertificatePolicy 250: */ 251: static void cert_policy_destroy(x509_cert_policy_t *this) 252: { 253: free(this->oid.ptr); 254: free(this->cps_uri); 255: free(this->unotice_text); 256: free(this); 257: } 258: 259: /** 260: * Free policy mapping 261: */ 262: static void policy_mapping_destroy(x509_policy_mapping_t *mapping) 263: { 264: free(mapping->issuer.ptr); 265: free(mapping->subject.ptr); 266: free(mapping); 267: } 268: 269: /** 270: * Parse a length constraint from an unwrapped integer 271: */ 272: static u_int parse_constraint(chunk_t object) 273: { 274: switch (object.len) 275: { 276: case 0: 277: return 0; 278: case 1: 279: return (object.ptr[0] & 0x80) ? X509_NO_CONSTRAINT : object.ptr[0]; 280: default: 281: return X509_NO_CONSTRAINT; 282: } 283: } 284: 285: /** 286: * ASN.1 definition of a basicConstraints extension 287: */ 288: static const asn1Object_t basicConstraintsObjects[] = { 289: { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ 290: { 1, "CA", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 1 */ 291: { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */ 292: { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */ 293: { 0, "exit", ASN1_EOC, ASN1_EXIT } 294: }; 295: #define BASIC_CONSTRAINTS_CA 1 296: #define BASIC_CONSTRAINTS_PATH_LEN 2 297: 298: /** 299: * Extracts the basicConstraints extension 300: */ 301: static bool parse_basicConstraints(chunk_t blob, int level0, 302: private_x509_cert_t *this) 303: { 304: asn1_parser_t *parser; 305: chunk_t object; 306: int objectID; 307: bool isCA = FALSE; 308: bool success; 309: 310: parser = asn1_parser_create(basicConstraintsObjects, blob); 311: parser->set_top_level(parser, level0); 312: 313: while (parser->iterate(parser, &objectID, &object)) 314: { 315: switch (objectID) 316: { 317: case BASIC_CONSTRAINTS_CA: 318: isCA = object.len && *object.ptr; 319: DBG2(DBG_ASN, " %s", isCA ? "TRUE" : "FALSE"); 320: if (isCA) 321: { 322: this->flags |= X509_CA; 323: } 324: break; 325: case BASIC_CONSTRAINTS_PATH_LEN: 326: if (isCA) 327: { 328: this->pathLenConstraint = parse_constraint(object); 329: } 330: break; 331: default: 332: break; 333: } 334: } 335: success = parser->success(parser); 336: parser->destroy(parser); 337: 338: return success; 339: } 340: 341: /** 342: * ASN.1 definition of otherName 343: */ 344: static const asn1Object_t otherNameObjects[] = { 345: {0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */ 346: {0, "value", ASN1_CONTEXT_C_0, ASN1_BODY }, /* 1 */ 347: {0, "exit", ASN1_EOC, ASN1_EXIT } 348: }; 349: #define ON_OBJ_ID_TYPE 0 350: #define ON_OBJ_VALUE 1 351: 352: /** 353: * Extracts an otherName 354: */ 355: static bool parse_otherName(chunk_t *blob, int level0, id_type_t *type) 356: { 357: asn1_parser_t *parser; 358: chunk_t object; 359: int objectID; 360: int oid = OID_UNKNOWN; 361: bool success = FALSE; 362: 363: parser = asn1_parser_create(otherNameObjects, *blob); 364: parser->set_top_level(parser, level0); 365: 366: while (parser->iterate(parser, &objectID, &object)) 367: { 368: switch (objectID) 369: { 370: case ON_OBJ_ID_TYPE: 371: oid = asn1_known_oid(object); 372: break; 373: case ON_OBJ_VALUE: 374: switch (oid) 375: { 376: case OID_XMPP_ADDR: 377: if (asn1_parse_simple_object(&object, ASN1_UTF8STRING, 378: parser->get_level(parser)+1, "xmppAddr")) 379: { /* we handle xmppAddr as RFC822 addr */ 380: *blob = object; 381: *type = ID_RFC822_ADDR; 382: } 383: else 384: { 385: goto end; 386: } 387: break; 388: case OID_USER_PRINCIPAL_NAME: 389: if (asn1_parse_simple_object(&object, ASN1_UTF8STRING, 390: parser->get_level(parser)+1, "msUPN")) 391: { /* we handle UPNs as RFC822 addr */ 392: *blob = object; 393: *type = ID_RFC822_ADDR; 394: } 395: else 396: { 397: goto end; 398: } 399: break; 400: } 401: break; 402: default: 403: break; 404: } 405: } 406: success = parser->success(parser); 407: 408: end: 409: parser->destroy(parser); 410: return success; 411: } 412: 413: /** 414: * ASN.1 definition of generalName 415: */ 416: static const asn1Object_t generalNameObjects[] = { 417: { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */ 418: { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */ 419: { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */ 420: { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */ 421: { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */ 422: { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */ 423: { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */ 424: { 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */ 425: { 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT|ASN1_BODY }, /* 8 */ 426: { 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */ 427: { 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT|ASN1_BODY }, /* 10 */ 428: { 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */ 429: { 0, "URI", ASN1_CONTEXT_S_6, ASN1_OPT|ASN1_BODY }, /* 12 */ 430: { 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */ 431: { 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT|ASN1_BODY }, /* 14 */ 432: { 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */ 433: { 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT|ASN1_BODY }, /* 16 */ 434: { 0, "end choice", ASN1_EOC, ASN1_END }, /* 17 */ 435: { 0, "exit", ASN1_EOC, ASN1_EXIT } 436: }; 437: #define GN_OBJ_OTHER_NAME 0 438: #define GN_OBJ_RFC822_NAME 2 439: #define GN_OBJ_DNS_NAME 4 440: #define GN_OBJ_X400_ADDRESS 6 441: #define GN_OBJ_DIRECTORY_NAME 8 442: #define GN_OBJ_EDI_PARTY_NAME 10 443: #define GN_OBJ_URI 12 444: #define GN_OBJ_IP_ADDRESS 14 445: #define GN_OBJ_REGISTERED_ID 16 446: 447: /** 448: * Extracts a generalName 449: */ 450: static identification_t *parse_generalName(chunk_t blob, int level0) 451: { 452: asn1_parser_t *parser; 453: chunk_t object; 454: int objectID ; 455: 456: identification_t *gn = NULL; 457: 458: parser = asn1_parser_create(generalNameObjects, blob); 459: parser->set_top_level(parser, level0); 460: 461: while (parser->iterate(parser, &objectID, &object)) 462: { 463: id_type_t id_type = ID_ANY; 464: 465: switch (objectID) 466: { 467: case GN_OBJ_RFC822_NAME: 468: id_type = ID_RFC822_ADDR; 469: break; 470: case GN_OBJ_DNS_NAME: 471: id_type = ID_FQDN; 472: break; 473: case GN_OBJ_URI: 474: id_type = ID_DER_ASN1_GN_URI; 475: break; 476: case GN_OBJ_DIRECTORY_NAME: 477: id_type = ID_DER_ASN1_DN; 478: break; 479: case GN_OBJ_IP_ADDRESS: 480: switch (object.len) 481: { 482: case 4: 483: id_type = ID_IPV4_ADDR; 484: break; 485: case 16: 486: id_type = ID_IPV6_ADDR; 487: break; 488: default: 489: break; 490: } 491: break; 492: case GN_OBJ_OTHER_NAME: 493: if (!parse_otherName(&object, parser->get_level(parser)+1, 494: &id_type)) 495: { 496: goto end; 497: } 498: break; 499: case GN_OBJ_X400_ADDRESS: 500: case GN_OBJ_EDI_PARTY_NAME: 501: case GN_OBJ_REGISTERED_ID: 502: default: 503: break; 504: } 505: if (id_type != ID_ANY) 506: { 507: gn = identification_create_from_encoding(id_type, object); 508: DBG2(DBG_ASN, " '%Y'", gn); 509: goto end; 510: } 511: } 512: 513: end: 514: parser->destroy(parser); 515: return gn; 516: } 517: 518: /** 519: * ASN.1 definition of generalNames 520: */ 521: static const asn1Object_t generalNamesObjects[] = { 522: { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ 523: { 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */ 524: { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */ 525: { 0, "exit", ASN1_EOC, ASN1_EXIT } 526: }; 527: #define GENERAL_NAMES_GN 1 528: 529: /** 530: * Extracts one or several GNs and puts them into a chained list 531: */ 532: bool x509_parse_generalNames(chunk_t blob, int level0, bool implicit, 533: linked_list_t *list) 534: { 535: asn1_parser_t *parser; 536: chunk_t object; 537: identification_t *gn; 538: int objectID; 539: bool success = FALSE; 540: 541: parser = asn1_parser_create(generalNamesObjects, blob); 542: parser->set_top_level(parser, level0); 543: parser->set_flags(parser, implicit, FALSE); 544: 545: while (parser->iterate(parser, &objectID, &object)) 546: { 547: if (objectID == GENERAL_NAMES_GN) 548: { 549: gn = parse_generalName(object, parser->get_level(parser)+1); 550: if (!gn) 551: { 552: goto end; 553: } 554: list->insert_last(list, (void *)gn); 555: } 556: } 557: success = parser->success(parser); 558: 559: end: 560: parser->destroy(parser); 561: 562: return success; 563: } 564: 565: /** 566: * ASN.1 definition of a authorityKeyIdentifier extension 567: */ 568: static const asn1Object_t authKeyIdentifierObjects[] = { 569: { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ 570: { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_BODY }, /* 1 */ 571: { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */ 572: { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */ 573: { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */ 574: { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */ 575: { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */ 576: { 0, "exit", ASN1_EOC, ASN1_EXIT } 577: }; 578: #define AUTH_KEY_ID_KEY_ID 1 579: #define AUTH_KEY_ID_CERT_ISSUER 3 580: #define AUTH_KEY_ID_CERT_SERIAL 5 581: 582: /** 583: * Extracts an authoritykeyIdentifier 584: */ 585: chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob, int level0, 586: chunk_t *authKeySerialNumber) 587: { 588: asn1_parser_t *parser; 589: chunk_t object; 590: int objectID; 591: chunk_t authKeyIdentifier = chunk_empty; 592: 593: *authKeySerialNumber = chunk_empty; 594: 595: parser = asn1_parser_create(authKeyIdentifierObjects, blob); 596: parser->set_top_level(parser, level0); 597: 598: while (parser->iterate(parser, &objectID, &object)) 599: { 600: switch (objectID) 601: { 602: case AUTH_KEY_ID_KEY_ID: 603: authKeyIdentifier = chunk_clone(object); 604: break; 605: case AUTH_KEY_ID_CERT_ISSUER: 606: /* TODO: x509_parse_generalNames(object, level+1, TRUE); */ 607: break; 608: case AUTH_KEY_ID_CERT_SERIAL: 609: *authKeySerialNumber = object; 610: break; 611: default: 612: break; 613: } 614: } 615: parser->destroy(parser); 616: 617: return authKeyIdentifier; 618: } 619: 620: /** 621: * ASN.1 definition of a authorityInfoAccess extension 622: */ 623: static const asn1Object_t authInfoAccessObjects[] = { 624: { 0, "authorityInfoAccess", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ 625: { 1, "accessDescription", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ 626: { 2, "accessMethod", ASN1_OID, ASN1_BODY }, /* 2 */ 627: { 2, "accessLocation", ASN1_EOC, ASN1_RAW }, /* 3 */ 628: { 0, "end loop", ASN1_EOC, ASN1_END }, /* 4 */ 629: { 0, "exit", ASN1_EOC, ASN1_EXIT } 630: }; 631: #define AUTH_INFO_ACCESS_METHOD 2 632: #define AUTH_INFO_ACCESS_LOCATION 3 633: 634: /** 635: * Extracts an authorityInfoAcess location 636: */ 637: static bool parse_authorityInfoAccess(chunk_t blob, int level0, 638: private_x509_cert_t *this) 639: { 640: asn1_parser_t *parser; 641: chunk_t object; 642: int objectID; 643: int accessMethod = OID_UNKNOWN; 644: bool success = FALSE; 645: 646: parser = asn1_parser_create(authInfoAccessObjects, blob); 647: parser->set_top_level(parser, level0); 648: 649: while (parser->iterate(parser, &objectID, &object)) 650: { 651: switch (objectID) 652: { 653: case AUTH_INFO_ACCESS_METHOD: 654: accessMethod = asn1_known_oid(object); 655: break; 656: case AUTH_INFO_ACCESS_LOCATION: 657: { 658: switch (accessMethod) 659: { 660: case OID_OCSP: 661: case OID_CA_ISSUERS: 662: { 663: identification_t *id; 664: char *uri; 665: 666: id = parse_generalName(object, 667: parser->get_level(parser)+1); 668: if (id == NULL) 669: { 670: /* parsing went wrong - abort */ 671: goto end; 672: } 673: DBG2(DBG_ASN, " '%Y'", id); 674: if (accessMethod == OID_OCSP && 675: gn_to_string(id, &uri)) 676: { 677: this->ocsp_uris->insert_last(this->ocsp_uris, uri); 678: } 679: id->destroy(id); 680: } 681: break; 682: default: 683: /* unknown accessMethod, ignoring */ 684: break; 685: } 686: break; 687: } 688: default: 689: break; 690: } 691: } 692: success = parser->success(parser); 693: 694: end: 695: parser->destroy(parser); 696: 697: return success; 698: } 699: 700: /** 701: * Extract KeyUsage flags 702: */ 703: static void parse_keyUsage(chunk_t blob, private_x509_cert_t *this) 704: { 705: enum { 706: KU_DIGITAL_SIGNATURE = 0, 707: KU_NON_REPUDIATION = 1, 708: KU_KEY_ENCIPHERMENT = 2, 709: KU_DATA_ENCIPHERMENT = 3, 710: KU_KEY_AGREEMENT = 4, 711: KU_KEY_CERT_SIGN = 5, 712: KU_CRL_SIGN = 6, 713: KU_ENCIPHER_ONLY = 7, 714: KU_DECIPHER_ONLY = 8, 715: }; 716: 717: /* to be compliant with RFC 4945 specific KUs have to be included */ 718: this->flags &= ~X509_IKE_COMPLIANT; 719: 720: if (asn1_unwrap(&blob, &blob) == ASN1_BIT_STRING && blob.len) 721: { 722: int bit, byte, unused = blob.ptr[0]; 723: 724: blob = chunk_skip(blob, 1); 725: for (byte = 0; byte < blob.len; byte++) 726: { 727: for (bit = 0; bit < 8; bit++) 728: { 729: if (byte == blob.len - 1 && bit > (7 - unused)) 730: { 731: break; 732: } 733: if (blob.ptr[byte] & 1 << (7 - bit)) 734: { 735: switch (byte * 8 + bit) 736: { 737: case KU_CRL_SIGN: 738: this->flags |= X509_CRL_SIGN; 739: break; 740: case KU_DIGITAL_SIGNATURE: 741: case KU_NON_REPUDIATION: 742: this->flags |= X509_IKE_COMPLIANT; 743: break; 744: case KU_KEY_CERT_SIGN: 745: /* we use the caBasicConstraint, MUST be set */ 746: case KU_KEY_ENCIPHERMENT: 747: case KU_DATA_ENCIPHERMENT: 748: case KU_KEY_AGREEMENT: 749: case KU_ENCIPHER_ONLY: 750: case KU_DECIPHER_ONLY: 751: break; 752: } 753: } 754: } 755: } 756: } 757: } 758: 759: /** 760: * ASN.1 definition of a extendedKeyUsage extension 761: */ 762: static const asn1Object_t extendedKeyUsageObjects[] = { 763: { 0, "extendedKeyUsage", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ 764: { 1, "keyPurposeID", ASN1_OID, ASN1_BODY }, /* 1 */ 765: { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */ 766: { 0, "exit", ASN1_EOC, ASN1_EXIT } 767: }; 768: #define EXT_KEY_USAGE_PURPOSE_ID 1 769: 770: /** 771: * Extracts extendedKeyUsage OIDs 772: */ 773: static bool parse_extendedKeyUsage(chunk_t blob, int level0, 774: private_x509_cert_t *this) 775: { 776: asn1_parser_t *parser; 777: chunk_t object; 778: int objectID; 779: bool success; 780: 781: parser = asn1_parser_create(extendedKeyUsageObjects, blob); 782: parser->set_top_level(parser, level0); 783: 784: while (parser->iterate(parser, &objectID, &object)) 785: { 786: if (objectID == EXT_KEY_USAGE_PURPOSE_ID) 787: { 788: switch (asn1_known_oid(object)) 789: { 790: case OID_SERVER_AUTH: 791: this->flags |= X509_SERVER_AUTH; 792: break; 793: case OID_CLIENT_AUTH: 794: this->flags |= X509_CLIENT_AUTH; 795: break; 796: case OID_IKE_INTERMEDIATE: 797: this->flags |= X509_IKE_INTERMEDIATE; 798: break; 799: case OID_OCSP_SIGNING: 800: this->flags |= X509_OCSP_SIGNER; 801: break; 802: case OID_MS_SMARTCARD_LOGON: 803: this->flags |= X509_MS_SMARTCARD_LOGON; 804: break; 805: default: 806: break; 807: } 808: } 809: } 810: success = parser->success(parser); 811: parser->destroy(parser); 812: 813: return success; 814: } 815: 816: /** 817: * ASN.1 definition of crlDistributionPoints 818: */ 819: static const asn1Object_t crlDistributionPointsObjects[] = { 820: { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ 821: { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ 822: { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_CHOICE }, /* 2 */ 823: { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */ 824: { 3, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 4 */ 825: { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */ 826: { 3, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 6 */ 827: { 2, "end opt/choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 7 */ 828: { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */ 829: { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */ 830: { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_OBJ }, /* 10 */ 831: { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */ 832: { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */ 833: { 0, "exit", ASN1_EOC, ASN1_EXIT } 834: }; 835: #define CRL_DIST_POINTS 1 836: #define CRL_DIST_POINTS_FULLNAME 3 837: #define CRL_DIST_POINTS_ISSUER 10 838: 839: /** 840: * Add entry to the list of each pairing of URI and Issuer 841: */ 842: static void add_cdps(linked_list_t *list, linked_list_t *uris, 843: linked_list_t *issuers) 844: { 845: identification_t *issuer, *id; 846: enumerator_t *enumerator; 847: x509_cdp_t *cdp; 848: char *uri; 849: 850: while (uris->remove_last(uris, (void**)&id) == SUCCESS) 851: { 852: if (gn_to_string(id, &uri)) 853: { 854: if (issuers->get_count(issuers)) 855: { 856: enumerator = issuers->create_enumerator(issuers); 857: while (enumerator->enumerate(enumerator, &issuer)) 858: { 859: INIT(cdp, 860: .uri = strdup(uri), 861: .issuer = issuer->clone(issuer), 862: ); 863: list->insert_last(list, cdp); 864: } 865: enumerator->destroy(enumerator); 866: free(uri); 867: } 868: else 869: { 870: INIT(cdp, 871: .uri = uri, 872: ); 873: list->insert_last(list, cdp); 874: } 875: } 876: id->destroy(id); 877: } 878: while (issuers->remove_last(issuers, (void**)&id) == SUCCESS) 879: { 880: id->destroy(id); 881: } 882: } 883: 884: /** 885: * Extracts one or several crlDistributionPoints into a list 886: */ 887: bool x509_parse_crlDistributionPoints(chunk_t blob, int level0, 888: linked_list_t *list) 889: { 890: linked_list_t *uris, *issuers; 891: asn1_parser_t *parser; 892: chunk_t object; 893: int objectID; 894: bool success = FALSE; 895: 896: uris = linked_list_create(); 897: issuers = linked_list_create(); 898: parser = asn1_parser_create(crlDistributionPointsObjects, blob); 899: parser->set_top_level(parser, level0); 900: 901: while (parser->iterate(parser, &objectID, &object)) 902: { 903: switch (objectID) 904: { 905: case CRL_DIST_POINTS: 906: add_cdps(list, uris, issuers); 907: break; 908: case CRL_DIST_POINTS_FULLNAME: 909: if (!x509_parse_generalNames(object, 910: parser->get_level(parser) + 1, TRUE, uris)) 911: { 912: goto end; 913: } 914: break; 915: case CRL_DIST_POINTS_ISSUER: 916: if (!x509_parse_generalNames(object, 917: parser->get_level(parser) + 1, TRUE, issuers)) 918: { 919: goto end; 920: } 921: break; 922: default: 923: break; 924: } 925: } 926: success = parser->success(parser); 927: add_cdps(list, uris, issuers); 928: 929: end: 930: parser->destroy(parser); 931: uris->destroy_offset(uris, offsetof(identification_t, destroy)); 932: issuers->destroy_offset(issuers, offsetof(identification_t, destroy)); 933: 934: return success; 935: } 936: 937: /** 938: * ASN.1 definition of nameConstraints 939: */ 940: static const asn1Object_t nameConstraintsObjects[] = { 941: { 0, "nameConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ 942: { 1, "permittedSubtrees", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 1 */ 943: { 2, "generalSubtree", ASN1_SEQUENCE, ASN1_BODY }, /* 2 */ 944: { 1, "end loop", ASN1_EOC, ASN1_END }, /* 3 */ 945: { 1, "excludedSubtrees", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_LOOP }, /* 4 */ 946: { 2, "generalSubtree", ASN1_SEQUENCE, ASN1_BODY }, /* 5 */ 947: { 1, "end loop", ASN1_EOC, ASN1_END }, /* 6 */ 948: { 0, "exit", ASN1_EOC, ASN1_EXIT } 949: }; 950: #define NAME_CONSTRAINT_PERMITTED 2 951: #define NAME_CONSTRAINT_EXCLUDED 5 952: 953: /** 954: * Parse permitted/excluded nameConstraints 955: */ 956: static bool parse_nameConstraints(chunk_t blob, int level0, 957: private_x509_cert_t *this) 958: { 959: asn1_parser_t *parser; 960: identification_t *id; 961: chunk_t object; 962: int objectID; 963: bool success = FALSE; 964: 965: parser = asn1_parser_create(nameConstraintsObjects, blob); 966: parser->set_top_level(parser, level0); 967: 968: while (parser->iterate(parser, &objectID, &object)) 969: { 970: switch (objectID) 971: { 972: case NAME_CONSTRAINT_PERMITTED: 973: id = parse_generalName(object, parser->get_level(parser) + 1); 974: if (!id) 975: { 976: goto end; 977: } 978: this->permitted_names->insert_last(this->permitted_names, id); 979: break; 980: case NAME_CONSTRAINT_EXCLUDED: 981: id = parse_generalName(object, parser->get_level(parser) + 1); 982: if (!id) 983: { 984: goto end; 985: } 986: this->excluded_names->insert_last(this->excluded_names, id); 987: break; 988: default: 989: break; 990: } 991: } 992: success = parser->success(parser); 993: 994: end: 995: parser->destroy(parser); 996: 997: return success; 998: } 999: 1000: /** 1001: * ASN.1 definition of a certificatePolicies extension 1002: */ 1003: static const asn1Object_t certificatePoliciesObject[] = { 1004: { 0, "certificatePolicies", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ 1005: { 1, "policyInformation", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ 1006: { 2, "policyId", ASN1_OID, ASN1_BODY }, /* 2 */ 1007: { 2, "qualifiers", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 3 */ 1008: { 3, "qualifierInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 4 */ 1009: { 4, "qualifierId", ASN1_OID, ASN1_BODY }, /* 5 */ 1010: { 4, "qualifier", ASN1_EOC, ASN1_CHOICE }, /* 6 */ 1011: { 5, "cPSuri", ASN1_IA5STRING, ASN1_OPT|ASN1_BODY }, /* 7 */ 1012: { 5, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 8 */ 1013: { 5, "userNotice", ASN1_SEQUENCE, ASN1_OPT|ASN1_BODY }, /* 9 */ 1014: { 6, "explicitText", ASN1_EOC, ASN1_RAW }, /* 10 */ 1015: { 5, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 11 */ 1016: { 4, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 12 */ 1017: { 2, "end opt/loop", ASN1_EOC, ASN1_END }, /* 13 */ 1018: { 0, "end loop", ASN1_EOC, ASN1_END }, /* 14 */ 1019: { 0, "exit", ASN1_EOC, ASN1_EXIT } 1020: }; 1021: #define CERT_POLICY_ID 2 1022: #define CERT_POLICY_QUALIFIER_ID 5 1023: #define CERT_POLICY_CPS_URI 7 1024: #define CERT_POLICY_EXPLICIT_TEXT 10 1025: 1026: /** 1027: * Parse certificatePolicies 1028: */ 1029: static bool parse_certificatePolicies(chunk_t blob, int level0, 1030: private_x509_cert_t *this) 1031: { 1032: x509_cert_policy_t *policy = NULL; 1033: asn1_parser_t *parser; 1034: chunk_t object; 1035: int objectID, qualifier = OID_UNKNOWN; 1036: bool success; 1037: 1038: parser = asn1_parser_create(certificatePoliciesObject, blob); 1039: parser->set_top_level(parser, level0); 1040: 1041: while (parser->iterate(parser, &objectID, &object)) 1042: { 1043: switch (objectID) 1044: { 1045: case CERT_POLICY_ID: 1046: INIT(policy, 1047: .oid = chunk_clone(object), 1048: ); 1049: this->cert_policies->insert_last(this->cert_policies, policy); 1050: break; 1051: case CERT_POLICY_QUALIFIER_ID: 1052: qualifier = asn1_known_oid(object); 1053: break; 1054: case CERT_POLICY_CPS_URI: 1055: if (policy && !policy->cps_uri && object.len && 1056: qualifier == OID_POLICY_QUALIFIER_CPS && 1057: chunk_printable(object, NULL, 0)) 1058: { 1059: policy->cps_uri = strndup(object.ptr, object.len); 1060: } 1061: break; 1062: case CERT_POLICY_EXPLICIT_TEXT: 1063: /* TODO */ 1064: break; 1065: default: 1066: break; 1067: } 1068: } 1069: success = parser->success(parser); 1070: parser->destroy(parser); 1071: 1072: return success; 1073: } 1074: 1075: /** 1076: * ASN.1 definition of a policyMappings extension 1077: */ 1078: static const asn1Object_t policyMappingsObjects[] = { 1079: { 0, "policyMappings", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ 1080: { 1, "policyMapping", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ 1081: { 2, "issuerPolicy", ASN1_OID, ASN1_BODY }, /* 2 */ 1082: { 2, "subjectPolicy", ASN1_OID, ASN1_BODY }, /* 3 */ 1083: { 0, "end loop", ASN1_EOC, ASN1_END }, /* 4 */ 1084: { 0, "exit", ASN1_EOC, ASN1_EXIT } 1085: }; 1086: #define POLICY_MAPPING 1 1087: #define POLICY_MAPPING_ISSUER 2 1088: #define POLICY_MAPPING_SUBJECT 3 1089: 1090: /** 1091: * Parse policyMappings 1092: */ 1093: static bool parse_policyMappings(chunk_t blob, int level0, 1094: private_x509_cert_t *this) 1095: { 1096: x509_policy_mapping_t *map = NULL; 1097: asn1_parser_t *parser; 1098: chunk_t object; 1099: int objectID; 1100: bool success; 1101: 1102: parser = asn1_parser_create(policyMappingsObjects, blob); 1103: parser->set_top_level(parser, level0); 1104: 1105: while (parser->iterate(parser, &objectID, &object)) 1106: { 1107: switch (objectID) 1108: { 1109: case POLICY_MAPPING: 1110: INIT(map); 1111: this->policy_mappings->insert_last(this->policy_mappings, map); 1112: break; 1113: case POLICY_MAPPING_ISSUER: 1114: if (map && !map->issuer.len) 1115: { 1116: map->issuer = chunk_clone(object); 1117: } 1118: break; 1119: case POLICY_MAPPING_SUBJECT: 1120: if (map && !map->subject.len) 1121: { 1122: map->subject = chunk_clone(object); 1123: } 1124: break; 1125: default: 1126: break; 1127: } 1128: } 1129: success = parser->success(parser); 1130: parser->destroy(parser); 1131: 1132: return success; 1133: } 1134: 1135: /** 1136: * ASN.1 definition of a policyConstraints extension 1137: */ 1138: static const asn1Object_t policyConstraintsObjects[] = { 1139: { 0, "policyConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ 1140: { 1, "requireExplicitPolicy", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_NONE }, /* 1 */ 1141: { 2, "SkipCerts", ASN1_INTEGER, ASN1_BODY }, /* 2 */ 1142: { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */ 1143: { 1, "inhibitPolicyMapping", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_NONE }, /* 4 */ 1144: { 2, "SkipCerts", ASN1_INTEGER, ASN1_BODY }, /* 5 */ 1145: { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */ 1146: { 0, "exit", ASN1_EOC, ASN1_EXIT } 1147: }; 1148: #define POLICY_CONSTRAINT_EXPLICIT 2 1149: #define POLICY_CONSTRAINT_INHIBIT 5 1150: 1151: /** 1152: * Parse policyConstraints 1153: */ 1154: static bool parse_policyConstraints(chunk_t blob, int level0, 1155: private_x509_cert_t *this) 1156: { 1157: asn1_parser_t *parser; 1158: chunk_t object; 1159: int objectID; 1160: bool success; 1161: 1162: parser = asn1_parser_create(policyConstraintsObjects, blob); 1163: parser->set_top_level(parser, level0); 1164: 1165: while (parser->iterate(parser, &objectID, &object)) 1166: { 1167: switch (objectID) 1168: { 1169: case POLICY_CONSTRAINT_EXPLICIT: 1170: this->require_explicit = parse_constraint(object); 1171: break; 1172: case POLICY_CONSTRAINT_INHIBIT: 1173: this->inhibit_mapping = parse_constraint(object); 1174: break; 1175: default: 1176: break; 1177: } 1178: } 1179: success = parser->success(parser); 1180: parser->destroy(parser); 1181: 1182: return success; 1183: } 1184: 1185: /** 1186: * ASN.1 definition of ipAddrBlocks according to RFC 3779 1187: */ 1188: static const asn1Object_t ipAddrBlocksObjects[] = { 1189: { 0, "ipAddrBlocks", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ 1190: { 1, "ipAddressFamily", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ 1191: { 2, "addressFamily", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */ 1192: { 2, "ipAddressChoice", ASN1_EOC, ASN1_CHOICE }, /* 3 */ 1193: { 3, "inherit", ASN1_NULL, ASN1_OPT }, /* 4 */ 1194: { 3, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 5 */ 1195: { 3, "addressesOrRanges", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 6 */ 1196: { 4, "addressOrRange", ASN1_EOC, ASN1_CHOICE }, /* 7 */ 1197: { 5, "addressPrefix", ASN1_BIT_STRING, ASN1_OPT|ASN1_BODY }, /* 8 */ 1198: { 5, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 9 */ 1199: { 5, "addressRange", ASN1_SEQUENCE, ASN1_OPT }, /* 10 */ 1200: { 6, "min", ASN1_BIT_STRING, ASN1_BODY }, /* 11 */ 1201: { 6, "max", ASN1_BIT_STRING, ASN1_BODY }, /* 12 */ 1202: { 5, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 13 */ 1203: { 4, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 14 */ 1204: { 3, "end loop/choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 15 */ 1205: { 2, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 16 */ 1206: { 0, "end loop", ASN1_EOC, ASN1_END }, /* 17 */ 1207: { 0, "exit", ASN1_EOC, ASN1_EXIT } 1208: }; 1209: #define IP_ADDR_BLOCKS_FAMILY 2 1210: #define IP_ADDR_BLOCKS_INHERIT 4 1211: #define IP_ADDR_BLOCKS_PREFIX 8 1212: #define IP_ADDR_BLOCKS_MIN 11 1213: #define IP_ADDR_BLOCKS_MAX 12 1214: 1215: static bool check_address_object(ts_type_t ts_type, chunk_t object) 1216: { 1217: switch (ts_type) 1218: { 1219: case TS_IPV4_ADDR_RANGE: 1220: if (object.len > 5) 1221: { 1222: DBG1(DBG_ASN, "IPv4 address object is larger than 5 octets"); 1223: return FALSE; 1224: } 1225: break; 1226: case TS_IPV6_ADDR_RANGE: 1227: if (object.len > 17) 1228: { 1229: DBG1(DBG_ASN, "IPv6 address object is larger than 17 octets"); 1230: return FALSE; 1231: } 1232: break; 1233: default: 1234: DBG1(DBG_ASN, "unknown address family"); 1235: return FALSE; 1236: } 1237: if (object.len == 0) 1238: { 1239: DBG1(DBG_ASN, "An ASN.1 bit string must contain at least the " 1240: "initial octet"); 1241: return FALSE; 1242: } 1243: if (object.len == 1 && object.ptr[0] != 0) 1244: { 1245: DBG1(DBG_ASN, "An empty ASN.1 bit string must contain a zero " 1246: "initial octet"); 1247: return FALSE; 1248: } 1249: if (object.ptr[0] > 7) 1250: { 1251: DBG1(DBG_ASN, "number of unused bits is too large"); 1252: return FALSE; 1253: } 1254: return TRUE; 1255: } 1256: 1257: static bool parse_ipAddrBlocks(chunk_t blob, int level0, 1258: private_x509_cert_t *this) 1259: { 1260: asn1_parser_t *parser; 1261: chunk_t object, min_object; 1262: ts_type_t ts_type = 0; 1263: traffic_selector_t *ts; 1264: int objectID; 1265: bool success = FALSE; 1266: 1267: parser = asn1_parser_create(ipAddrBlocksObjects, blob); 1268: parser->set_top_level(parser, level0); 1269: 1270: while (parser->iterate(parser, &objectID, &object)) 1271: { 1272: switch (objectID) 1273: { 1274: case IP_ADDR_BLOCKS_FAMILY: 1275: ts_type = 0; 1276: if (object.len == 2 && object.ptr[0] == 0) 1277: { 1278: if (object.ptr[1] == 1) 1279: { 1280: ts_type = TS_IPV4_ADDR_RANGE; 1281: } 1282: else if (object.ptr[1] == 2) 1283: { 1284: ts_type = TS_IPV6_ADDR_RANGE; 1285: } 1286: else 1287: { 1288: break; 1289: } 1290: DBG2(DBG_ASN, " %N", ts_type_name, ts_type); 1291: } 1292: break; 1293: case IP_ADDR_BLOCKS_INHERIT: 1294: DBG1(DBG_ASN, "inherit choice is not supported"); 1295: break; 1296: case IP_ADDR_BLOCKS_PREFIX: 1297: if (!check_address_object(ts_type, object)) 1298: { 1299: goto end; 1300: } 1301: ts = traffic_selector_create_from_rfc3779_format(ts_type, 1302: object, object); 1303: DBG2(DBG_ASN, " %R", ts); 1304: this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts); 1305: break; 1306: case IP_ADDR_BLOCKS_MIN: 1307: if (!check_address_object(ts_type, object)) 1308: { 1309: goto end; 1310: } 1311: min_object = object; 1312: break; 1313: case IP_ADDR_BLOCKS_MAX: 1314: if (!check_address_object(ts_type, object)) 1315: { 1316: goto end; 1317: } 1318: ts = traffic_selector_create_from_rfc3779_format(ts_type, 1319: min_object, object); 1320: DBG2(DBG_ASN, " %R", ts); 1321: this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts); 1322: break; 1323: default: 1324: break; 1325: } 1326: } 1327: success = parser->success(parser); 1328: this->flags |= X509_IP_ADDR_BLOCKS; 1329: 1330: end: 1331: parser->destroy(parser); 1332: 1333: return success; 1334: } 1335: 1336: /** 1337: * ASN.1 definition of an X.509v3 x509_cert 1338: */ 1339: static const asn1Object_t certObjects[] = { 1340: { 0, "x509", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */ 1341: { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */ 1342: { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */ 1343: { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */ 1344: { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */ 1345: { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */ 1346: { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */ 1347: { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */ 1348: { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */ 1349: { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */ 1350: { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */ 1351: { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_RAW }, /* 11 */ 1352: { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */ 1353: { 2, "end opt", ASN1_EOC, ASN1_END }, /* 13 */ 1354: { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 14 */ 1355: { 2, "end opt", ASN1_EOC, ASN1_END }, /* 15 */ 1356: { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 16 */ 1357: { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 17 */ 1358: { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 18 */ 1359: { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 19 */ 1360: { 5, "critical", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 20 */ 1361: { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 21 */ 1362: { 3, "end loop", ASN1_EOC, ASN1_END }, /* 22 */ 1363: { 2, "end opt", ASN1_EOC, ASN1_END }, /* 23 */ 1364: { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 24 */ 1365: { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 25 */ 1366: { 0, "exit", ASN1_EOC, ASN1_EXIT } 1367: }; 1368: #define X509_OBJ_TBS_CERTIFICATE 1 1369: #define X509_OBJ_VERSION 3 1370: #define X509_OBJ_SERIAL_NUMBER 4 1371: #define X509_OBJ_SIG_ALG 5 1372: #define X509_OBJ_ISSUER 6 1373: #define X509_OBJ_NOT_BEFORE 8 1374: #define X509_OBJ_NOT_AFTER 9 1375: #define X509_OBJ_SUBJECT 10 1376: #define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO 11 1377: #define X509_OBJ_OPTIONAL_EXTENSIONS 16 1378: #define X509_OBJ_EXTN_ID 19 1379: #define X509_OBJ_CRITICAL 20 1380: #define X509_OBJ_EXTN_VALUE 21 1381: #define X509_OBJ_ALGORITHM 24 1382: #define X509_OBJ_SIGNATURE 25 1383: 1384: /** 1385: * Parses an X.509v3 certificate 1386: */ 1387: static bool parse_certificate(private_x509_cert_t *this) 1388: { 1389: asn1_parser_t *parser; 1390: chunk_t object; 1391: int objectID; 1392: int extn_oid = OID_UNKNOWN; 1393: signature_params_t sig_alg = {}; 1394: bool success = FALSE; 1395: bool critical = FALSE; 1396: 1397: parser = asn1_parser_create(certObjects, this->encoding); 1398: 1399: /* unless we see a keyUsage extension we are compliant with RFC 4945 */ 1400: this->flags |= X509_IKE_COMPLIANT; 1401: 1402: while (parser->iterate(parser, &objectID, &object)) 1403: { 1404: u_int level = parser->get_level(parser)+1; 1405: 1406: switch (objectID) 1407: { 1408: case X509_OBJ_TBS_CERTIFICATE: 1409: this->tbsCertificate = object; 1410: break; 1411: case X509_OBJ_VERSION: 1412: this->version = (object.len) ? (1+(u_int)*object.ptr) : 1; 1413: if (this->version < 1 || this->version > 3) 1414: { 1415: DBG1(DBG_ASN, "X.509v%d not supported", this->version); 1416: goto end; 1417: } 1418: else 1419: { 1420: DBG2(DBG_ASN, " X.509v%d", this->version); 1421: } 1422: break; 1423: case X509_OBJ_SERIAL_NUMBER: 1424: this->serialNumber = object; 1425: break; 1426: case X509_OBJ_SIG_ALG: 1427: if (!signature_params_parse(object, level, &sig_alg)) 1428: { 1429: DBG1(DBG_ASN, " unable to parse signature algorithm"); 1430: goto end; 1431: } 1432: break; 1433: case X509_OBJ_ISSUER: 1434: this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object); 1435: DBG2(DBG_ASN, " '%Y'", this->issuer); 1436: break; 1437: case X509_OBJ_NOT_BEFORE: 1438: this->notBefore = asn1_parse_time(object, level); 1439: break; 1440: case X509_OBJ_NOT_AFTER: 1441: this->notAfter = asn1_parse_time(object, level); 1442: break; 1443: case X509_OBJ_SUBJECT: 1444: this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object); 1445: DBG2(DBG_ASN, " '%Y'", this->subject); 1446: break; 1447: case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO: 1448: DBG2(DBG_ASN, "-- > --"); 1449: this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, 1450: KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END); 1451: DBG2(DBG_ASN, "-- < --"); 1452: if (this->public_key == NULL) 1453: { 1454: goto end; 1455: } 1456: break; 1457: case X509_OBJ_OPTIONAL_EXTENSIONS: 1458: if (this->version != 3) 1459: { 1460: DBG1(DBG_ASN, "Only X.509v3 certificates have extensions"); 1461: goto end; 1462: } 1463: break; 1464: case X509_OBJ_EXTN_ID: 1465: extn_oid = asn1_known_oid(object); 1466: break; 1467: case X509_OBJ_CRITICAL: 1468: critical = object.len && *object.ptr; 1469: DBG2(DBG_ASN, " %s", critical ? "TRUE" : "FALSE"); 1470: break; 1471: case X509_OBJ_EXTN_VALUE: 1472: { 1473: switch (extn_oid) 1474: { 1475: case OID_SUBJECT_KEY_ID: 1476: if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING, 1477: level, "keyIdentifier")) 1478: { 1479: goto end; 1480: } 1481: this->subjectKeyIdentifier = object; 1482: break; 1483: case OID_SUBJECT_ALT_NAME: 1484: if (!x509_parse_generalNames(object, level, FALSE, 1485: this->subjectAltNames)) 1486: { 1487: goto end; 1488: } 1489: break; 1490: case OID_BASIC_CONSTRAINTS: 1491: if (!parse_basicConstraints(object, level, this)) 1492: { 1493: goto end; 1494: } 1495: break; 1496: case OID_CRL_DISTRIBUTION_POINTS: 1497: if (!x509_parse_crlDistributionPoints(object, level, 1498: this->crl_uris)) 1499: { 1500: goto end; 1501: } 1502: break; 1503: case OID_AUTHORITY_KEY_ID: 1504: chunk_free(&this->authKeyIdentifier); 1505: this->authKeyIdentifier = x509_parse_authorityKeyIdentifier( 1506: object, level, &this->authKeySerialNumber); 1507: break; 1508: case OID_AUTHORITY_INFO_ACCESS: 1509: if (!parse_authorityInfoAccess(object, level, this)) 1510: { 1511: goto end; 1512: } 1513: break; 1514: case OID_KEY_USAGE: 1515: parse_keyUsage(object, this); 1516: break; 1517: case OID_EXTENDED_KEY_USAGE: 1518: if (!parse_extendedKeyUsage(object, level, this)) 1519: { 1520: goto end; 1521: } 1522: break; 1523: case OID_IP_ADDR_BLOCKS: 1524: if (!parse_ipAddrBlocks(object, level, this)) 1525: { 1526: goto end; 1527: } 1528: break; 1529: case OID_NAME_CONSTRAINTS: 1530: if (!parse_nameConstraints(object, level, this)) 1531: { 1532: goto end; 1533: } 1534: break; 1535: case OID_CERTIFICATE_POLICIES: 1536: if (!parse_certificatePolicies(object, level, this)) 1537: { 1538: goto end; 1539: } 1540: break; 1541: case OID_POLICY_MAPPINGS: 1542: if (!parse_policyMappings(object, level, this)) 1543: { 1544: goto end; 1545: } 1546: break; 1547: case OID_POLICY_CONSTRAINTS: 1548: if (!parse_policyConstraints(object, level, this)) 1549: { 1550: goto end; 1551: } 1552: break; 1553: case OID_INHIBIT_ANY_POLICY: 1554: if (!asn1_parse_simple_object(&object, ASN1_INTEGER, 1555: level, "inhibitAnyPolicy")) 1556: { 1557: goto end; 1558: } 1559: this->inhibit_any = parse_constraint(object); 1560: break; 1561: case OID_NS_REVOCATION_URL: 1562: case OID_NS_CA_REVOCATION_URL: 1563: case OID_NS_CA_POLICY_URL: 1564: case OID_NS_COMMENT: 1565: if (!asn1_parse_simple_object(&object, ASN1_IA5STRING, 1566: level, oid_names[extn_oid].name)) 1567: { 1568: goto end; 1569: } 1570: break; 1571: default: 1572: if (critical && lib->settings->get_bool(lib->settings, 1573: "%s.x509.enforce_critical", TRUE, lib->ns)) 1574: { 1575: DBG1(DBG_ASN, "critical '%s' extension not supported", 1576: (extn_oid == OID_UNKNOWN) ? "unknown" : 1577: (char*)oid_names[extn_oid].name); 1578: goto end; 1579: } 1580: break; 1581: } 1582: break; 1583: } 1584: case X509_OBJ_ALGORITHM: 1585: INIT(this->scheme); 1586: if (!signature_params_parse(object, level, this->scheme)) 1587: { 1588: DBG1(DBG_ASN, " unable to parse signature algorithm"); 1589: goto end; 1590: } 1591: if (!signature_params_equal(this->scheme, &sig_alg)) 1592: { 1593: DBG1(DBG_ASN, " signature algorithms do not agree"); 1594: goto end; 1595: } 1596: break; 1597: case X509_OBJ_SIGNATURE: 1598: this->signature = chunk_skip(object, 1); 1599: break; 1600: default: 1601: break; 1602: } 1603: } 1604: success = parser->success(parser); 1605: 1606: end: 1607: parser->destroy(parser); 1608: signature_params_clear(&sig_alg); 1609: if (success) 1610: { 1611: hasher_t *hasher; 1612: 1613: /* check if the certificate is self-signed */ 1614: if (this->public.interface.interface.issued_by( 1615: &this->public.interface.interface, 1616: &this->public.interface.interface, 1617: NULL)) 1618: { 1619: this->flags |= X509_SELF_SIGNED; 1620: } 1621: /* create certificate hash */ 1622: hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); 1623: if (!hasher || 1624: !hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash)) 1625: { 1626: DESTROY_IF(hasher); 1627: DBG1(DBG_ASN, " unable to create hash of certificate, SHA1 not supported"); 1628: return FALSE; 1629: } 1630: hasher->destroy(hasher); 1631: } 1632: return success; 1633: } 1634: 1635: METHOD(certificate_t, get_type, certificate_type_t, 1636: private_x509_cert_t *this) 1637: { 1638: return CERT_X509; 1639: } 1640: 1641: METHOD(certificate_t, get_subject, identification_t*, 1642: private_x509_cert_t *this) 1643: { 1644: return this->subject; 1645: } 1646: 1647: METHOD(certificate_t, get_issuer, identification_t*, 1648: private_x509_cert_t *this) 1649: { 1650: return this->issuer; 1651: } 1652: 1653: METHOD(certificate_t, has_subject, id_match_t, 1654: private_x509_cert_t *this, identification_t *subject) 1655: { 1656: identification_t *current; 1657: enumerator_t *enumerator; 1658: id_match_t match, best; 1659: chunk_t encoding; 1660: 1661: if (subject->get_type(subject) == ID_KEY_ID) 1662: { 1663: encoding = subject->get_encoding(subject); 1664: 1665: if (this->encoding_hash.len && 1666: chunk_equals(this->encoding_hash, encoding)) 1667: { 1668: return ID_MATCH_PERFECT; 1669: } 1670: if (this->subjectKeyIdentifier.len && 1671: chunk_equals(this->subjectKeyIdentifier, encoding)) 1672: { 1673: return ID_MATCH_PERFECT; 1674: } 1675: if (this->public_key && 1676: this->public_key->has_fingerprint(this->public_key, encoding)) 1677: { 1678: return ID_MATCH_PERFECT; 1679: } 1680: if (chunk_equals(this->serialNumber, encoding)) 1681: { 1682: return ID_MATCH_PERFECT; 1683: } 1684: } 1685: best = this->subject->matches(this->subject, subject); 1686: enumerator = this->subjectAltNames->create_enumerator(this->subjectAltNames); 1687: while (enumerator->enumerate(enumerator, ¤t)) 1688: { 1689: match = current->matches(current, subject); 1690: if (match > best) 1691: { 1692: best = match; 1693: } 1694: } 1695: enumerator->destroy(enumerator); 1696: return best; 1697: } 1698: 1699: METHOD(certificate_t, has_issuer, id_match_t, 1700: private_x509_cert_t *this, identification_t *issuer) 1701: { 1702: /* issuerAltNames currently not supported */ 1703: return this->issuer->matches(this->issuer, issuer); 1704: } 1705: 1706: METHOD(certificate_t, issued_by, bool, 1707: private_x509_cert_t *this, certificate_t *issuer, 1708: signature_params_t **scheme) 1709: { 1710: public_key_t *key; 1711: bool valid; 1712: x509_t *x509 = (x509_t*)issuer; 1713: 1714: if (&this->public.interface.interface == issuer) 1715: { 1716: if (this->flags & X509_SELF_SIGNED) 1717: { 1718: if (scheme) 1719: { 1720: *scheme = signature_params_clone(this->scheme); 1721: } 1722: return TRUE; 1723: } 1724: } 1725: else 1726: { 1727: if (issuer->get_type(issuer) != CERT_X509) 1728: { 1729: return FALSE; 1730: } 1731: if (!(x509->get_flags(x509) & X509_CA)) 1732: { 1733: return FALSE; 1734: } 1735: } 1736: if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer))) 1737: { 1738: return FALSE; 1739: } 1740: 1741: /* get the public key of the issuer */ 1742: key = issuer->get_public_key(issuer); 1743: if (!key) 1744: { 1745: return FALSE; 1746: } 1747: valid = key->verify(key, this->scheme->scheme, this->scheme->params, 1748: this->tbsCertificate, this->signature); 1749: key->destroy(key); 1750: if (valid && scheme) 1751: { 1752: *scheme = signature_params_clone(this->scheme); 1753: } 1754: return valid; 1755: } 1756: 1757: METHOD(certificate_t, get_public_key, public_key_t*, 1758: private_x509_cert_t *this) 1759: { 1760: this->public_key->get_ref(this->public_key); 1761: return this->public_key; 1762: } 1763: 1764: METHOD(certificate_t, get_ref, certificate_t*, 1765: private_x509_cert_t *this) 1766: { 1767: ref_get(&this->ref); 1768: return &this->public.interface.interface; 1769: } 1770: 1771: METHOD(certificate_t, get_validity, bool, 1772: private_x509_cert_t *this, time_t *when, time_t *not_before, 1773: time_t *not_after) 1774: { 1775: time_t t = when ? *when : time(NULL); 1776: 1777: if (not_before) 1778: { 1779: *not_before = this->notBefore; 1780: } 1781: if (not_after) 1782: { 1783: *not_after = this->notAfter; 1784: } 1785: return (t >= this->notBefore && t <= this->notAfter); 1786: } 1787: 1788: METHOD(certificate_t, get_encoding, bool, 1789: private_x509_cert_t *this, cred_encoding_type_t type, chunk_t *encoding) 1790: { 1791: if (type == CERT_ASN1_DER) 1792: { 1793: *encoding = chunk_clone(this->encoding); 1794: return TRUE; 1795: } 1796: return lib->encoding->encode(lib->encoding, type, NULL, encoding, 1797: CRED_PART_X509_ASN1_DER, this->encoding, CRED_PART_END); 1798: } 1799: 1800: METHOD(certificate_t, equals, bool, 1801: private_x509_cert_t *this, certificate_t *other) 1802: { 1803: chunk_t encoding; 1804: bool equal; 1805: 1806: if (this == (private_x509_cert_t*)other) 1807: { 1808: return TRUE; 1809: } 1810: if (other->get_type(other) != CERT_X509) 1811: { 1812: return FALSE; 1813: } 1814: if (other->equals == (void*)equals) 1815: { /* skip allocation if we have the same implementation */ 1816: return chunk_equals(this->encoding, ((private_x509_cert_t*)other)->encoding); 1817: } 1818: if (!other->get_encoding(other, CERT_ASN1_DER, &encoding)) 1819: { 1820: return FALSE; 1821: } 1822: equal = chunk_equals(this->encoding, encoding); 1823: free(encoding.ptr); 1824: return equal; 1825: } 1826: 1827: METHOD(x509_t, get_flags, x509_flag_t, 1828: private_x509_cert_t *this) 1829: { 1830: return this->flags; 1831: } 1832: 1833: METHOD(x509_t, get_serial, chunk_t, 1834: private_x509_cert_t *this) 1835: { 1836: return this->serialNumber; 1837: } 1838: 1839: METHOD(x509_t, get_subjectKeyIdentifier, chunk_t, 1840: private_x509_cert_t *this) 1841: { 1842: if (this->subjectKeyIdentifier.ptr) 1843: { 1844: return this->subjectKeyIdentifier; 1845: } 1846: else 1847: { 1848: chunk_t fingerprint; 1849: 1850: if (this->public_key->get_fingerprint(this->public_key, 1851: KEYID_PUBKEY_SHA1, &fingerprint)) 1852: { 1853: return fingerprint; 1854: } 1855: else 1856: { 1857: return chunk_empty; 1858: } 1859: } 1860: } 1861: 1862: METHOD(x509_t, get_authKeyIdentifier, chunk_t, 1863: private_x509_cert_t *this) 1864: { 1865: return this->authKeyIdentifier; 1866: } 1867: 1868: METHOD(x509_t, get_constraint, u_int, 1869: private_x509_cert_t *this, x509_constraint_t type) 1870: { 1871: switch (type) 1872: { 1873: case X509_PATH_LEN: 1874: return this->pathLenConstraint; 1875: case X509_REQUIRE_EXPLICIT_POLICY: 1876: return this->require_explicit; 1877: case X509_INHIBIT_POLICY_MAPPING: 1878: return this->inhibit_mapping; 1879: case X509_INHIBIT_ANY_POLICY: 1880: return this->inhibit_any; 1881: default: 1882: return X509_NO_CONSTRAINT; 1883: } 1884: } 1885: 1886: METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*, 1887: private_x509_cert_t *this) 1888: { 1889: return this->subjectAltNames->create_enumerator(this->subjectAltNames); 1890: } 1891: 1892: METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*, 1893: private_x509_cert_t *this) 1894: { 1895: return this->ocsp_uris->create_enumerator(this->ocsp_uris); 1896: } 1897: 1898: METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*, 1899: private_x509_cert_t *this) 1900: { 1901: return this->crl_uris->create_enumerator(this->crl_uris); 1902: } 1903: 1904: METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*, 1905: private_x509_cert_t *this) 1906: { 1907: return this->ipAddrBlocks->create_enumerator(this->ipAddrBlocks); 1908: } 1909: 1910: METHOD(x509_t, create_name_constraint_enumerator, enumerator_t*, 1911: private_x509_cert_t *this, bool perm) 1912: { 1913: if (perm) 1914: { 1915: return this->permitted_names->create_enumerator(this->permitted_names); 1916: } 1917: return this->excluded_names->create_enumerator(this->excluded_names); 1918: } 1919: 1920: METHOD(x509_t, create_cert_policy_enumerator, enumerator_t*, 1921: private_x509_cert_t *this) 1922: { 1923: return this->cert_policies->create_enumerator(this->cert_policies); 1924: } 1925: 1926: METHOD(x509_t, create_policy_mapping_enumerator, enumerator_t*, 1927: private_x509_cert_t *this) 1928: { 1929: return this->policy_mappings->create_enumerator(this->policy_mappings); 1930: } 1931: 1932: METHOD(certificate_t, destroy, void, 1933: private_x509_cert_t *this) 1934: { 1935: if (ref_put(&this->ref)) 1936: { 1937: this->subjectAltNames->destroy_offset(this->subjectAltNames, 1938: offsetof(identification_t, destroy)); 1939: this->crl_uris->destroy_function(this->crl_uris, 1940: (void*)x509_cdp_destroy); 1941: this->ocsp_uris->destroy_function(this->ocsp_uris, free); 1942: this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks, 1943: offsetof(traffic_selector_t, destroy)); 1944: this->permitted_names->destroy_offset(this->permitted_names, 1945: offsetof(identification_t, destroy)); 1946: this->excluded_names->destroy_offset(this->excluded_names, 1947: offsetof(identification_t, destroy)); 1948: this->cert_policies->destroy_function(this->cert_policies, 1949: (void*)cert_policy_destroy); 1950: this->policy_mappings->destroy_function(this->policy_mappings, 1951: (void*)policy_mapping_destroy); 1952: signature_params_destroy(this->scheme); 1953: DESTROY_IF(this->issuer); 1954: DESTROY_IF(this->subject); 1955: DESTROY_IF(this->public_key); 1956: chunk_free(&this->authKeyIdentifier); 1957: chunk_free(&this->encoding); 1958: chunk_free(&this->encoding_hash); 1959: chunk_free(&this->critical_extension_oid); 1960: if (!this->parsed) 1961: { /* only parsed certificates point these fields to "encoded" */ 1962: chunk_free(&this->signature); 1963: chunk_free(&this->serialNumber); 1964: chunk_free(&this->tbsCertificate); 1965: } 1966: free(this); 1967: } 1968: } 1969: 1970: /** 1971: * create an empty but initialized X.509 certificate 1972: */ 1973: static private_x509_cert_t* create_empty(void) 1974: { 1975: private_x509_cert_t *this; 1976: 1977: INIT(this, 1978: .public = { 1979: .interface = { 1980: .interface = { 1981: .get_type = _get_type, 1982: .get_subject = _get_subject, 1983: .get_issuer = _get_issuer, 1984: .has_subject = _has_subject, 1985: .has_issuer = _has_issuer, 1986: .issued_by = _issued_by, 1987: .get_public_key = _get_public_key, 1988: .get_validity = _get_validity, 1989: .get_encoding = _get_encoding, 1990: .equals = _equals, 1991: .get_ref = _get_ref, 1992: .destroy = _destroy, 1993: }, 1994: .get_flags = _get_flags, 1995: .get_serial = _get_serial, 1996: .get_subjectKeyIdentifier = _get_subjectKeyIdentifier, 1997: .get_authKeyIdentifier = _get_authKeyIdentifier, 1998: .get_constraint = _get_constraint, 1999: .create_subjectAltName_enumerator = _create_subjectAltName_enumerator, 2000: .create_crl_uri_enumerator = _create_crl_uri_enumerator, 2001: .create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator, 2002: .create_ipAddrBlock_enumerator = _create_ipAddrBlock_enumerator, 2003: .create_name_constraint_enumerator = _create_name_constraint_enumerator, 2004: .create_cert_policy_enumerator = _create_cert_policy_enumerator, 2005: .create_policy_mapping_enumerator = _create_policy_mapping_enumerator, 2006: }, 2007: }, 2008: .version = 1, 2009: .subjectAltNames = linked_list_create(), 2010: .crl_uris = linked_list_create(), 2011: .ocsp_uris = linked_list_create(), 2012: .ipAddrBlocks = linked_list_create(), 2013: .permitted_names = linked_list_create(), 2014: .excluded_names = linked_list_create(), 2015: .cert_policies = linked_list_create(), 2016: .policy_mappings = linked_list_create(), 2017: .pathLenConstraint = X509_NO_CONSTRAINT, 2018: .require_explicit = X509_NO_CONSTRAINT, 2019: .inhibit_mapping = X509_NO_CONSTRAINT, 2020: .inhibit_any = X509_NO_CONSTRAINT, 2021: .ref = 1, 2022: ); 2023: return this; 2024: } 2025: 2026: /** 2027: * Build a generalName from an id 2028: */ 2029: chunk_t build_generalName(identification_t *id) 2030: { 2031: int context; 2032: 2033: switch (id->get_type(id)) 2034: { 2035: case ID_DER_ASN1_GN: 2036: return chunk_clone(id->get_encoding(id)); 2037: case ID_RFC822_ADDR: 2038: context = ASN1_CONTEXT_S_1; 2039: break; 2040: case ID_FQDN: 2041: context = ASN1_CONTEXT_S_2; 2042: break; 2043: case ID_DER_ASN1_DN: 2044: context = ASN1_CONTEXT_C_4; 2045: break; 2046: case ID_IPV4_ADDR: 2047: case ID_IPV6_ADDR: 2048: context = ASN1_CONTEXT_S_7; 2049: break; 2050: default: 2051: DBG1(DBG_ASN, "encoding %N as generalName not supported", 2052: id_type_names, id->get_type(id)); 2053: return chunk_empty; 2054: } 2055: return asn1_wrap(context, "c", id->get_encoding(id)); 2056: } 2057: 2058: /** 2059: * Encode a linked list of subjectAltNames 2060: */ 2061: chunk_t x509_build_subjectAltNames(linked_list_t *list) 2062: { 2063: chunk_t subjectAltNames = chunk_empty, name; 2064: enumerator_t *enumerator; 2065: identification_t *id; 2066: 2067: if (list->get_count(list) == 0) 2068: { 2069: return chunk_empty; 2070: } 2071: 2072: enumerator = list->create_enumerator(list); 2073: while (enumerator->enumerate(enumerator, &id)) 2074: { 2075: name = build_generalName(id); 2076: subjectAltNames = chunk_cat("mm", subjectAltNames, name); 2077: } 2078: enumerator->destroy(enumerator); 2079: 2080: return asn1_wrap(ASN1_SEQUENCE, "mm", 2081: asn1_build_known_oid(OID_SUBJECT_ALT_NAME), 2082: asn1_wrap(ASN1_OCTET_STRING, "m", 2083: asn1_wrap(ASN1_SEQUENCE, "m", subjectAltNames) 2084: ) 2085: ); 2086: } 2087: 2088: /** 2089: * Encode CRL distribution points extension from a x509_cdp_t list 2090: */ 2091: chunk_t x509_build_crlDistributionPoints(linked_list_t *list, int extn) 2092: { 2093: chunk_t crlDistributionPoints = chunk_empty; 2094: enumerator_t *enumerator; 2095: x509_cdp_t *cdp; 2096: 2097: if (list->get_count(list) == 0) 2098: { 2099: return chunk_empty; 2100: } 2101: 2102: enumerator = list->create_enumerator(list); 2103: while (enumerator->enumerate(enumerator, &cdp)) 2104: { 2105: chunk_t distributionPoint, crlIssuer = chunk_empty; 2106: 2107: if (cdp->issuer) 2108: { 2109: crlIssuer = asn1_wrap(ASN1_CONTEXT_C_2, "m", 2110: build_generalName(cdp->issuer)); 2111: } 2112: distributionPoint = asn1_wrap(ASN1_SEQUENCE, "mm", 2113: asn1_wrap(ASN1_CONTEXT_C_0, "m", 2114: asn1_wrap(ASN1_CONTEXT_C_0, "m", 2115: asn1_wrap(ASN1_CONTEXT_S_6, "c", 2116: chunk_create(cdp->uri, strlen(cdp->uri))))), 2117: crlIssuer); 2118: crlDistributionPoints = chunk_cat("mm", crlDistributionPoints, 2119: distributionPoint); 2120: } 2121: enumerator->destroy(enumerator); 2122: 2123: return asn1_wrap(ASN1_SEQUENCE, "mm", 2124: asn1_build_known_oid(extn), 2125: asn1_wrap(ASN1_OCTET_STRING, "m", 2126: asn1_wrap(ASN1_SEQUENCE, "m", crlDistributionPoints))); 2127: } 2128: 2129: static chunk_t generate_ts(traffic_selector_t *ts) 2130: { 2131: chunk_t from, to; 2132: uint8_t minbits = 0, maxbits = 0, unused; 2133: host_t *net; 2134: int bit, byte; 2135: 2136: if (ts->to_subnet(ts, &net, &minbits)) 2137: { 2138: unused = round_up(minbits, BITS_PER_BYTE) - minbits; 2139: from = asn1_wrap(ASN1_BIT_STRING, "m", 2140: chunk_cat("cc", chunk_from_thing(unused), 2141: chunk_create(net->get_address(net).ptr, 2142: (minbits + unused) / BITS_PER_BYTE))); 2143: net->destroy(net); 2144: return from; 2145: } 2146: net->destroy(net); 2147: 2148: from = ts->get_from_address(ts); 2149: for (byte = from.len - 1; byte >= 0; byte--) 2150: { 2151: if (from.ptr[byte] != 0) 2152: { 2153: minbits = byte * BITS_PER_BYTE + BITS_PER_BYTE; 2154: for (bit = 0; bit < BITS_PER_BYTE; bit++) 2155: { 2156: if (from.ptr[byte] & 1 << bit) 2157: { 2158: break; 2159: } 2160: minbits--; 2161: } 2162: break; 2163: } 2164: } 2165: to = ts->get_to_address(ts); 2166: for (byte = to.len - 1; byte >= 0; byte--) 2167: { 2168: if (to.ptr[byte] != 0xFF) 2169: { 2170: maxbits = byte * BITS_PER_BYTE + BITS_PER_BYTE; 2171: for (bit = 0; bit < BITS_PER_BYTE; bit++) 2172: { 2173: if ((to.ptr[byte] & 1 << bit) == 0) 2174: { 2175: break; 2176: } 2177: maxbits--; 2178: } 2179: break; 2180: } 2181: } 2182: unused = round_up(minbits, BITS_PER_BYTE) - minbits; 2183: from = asn1_wrap(ASN1_BIT_STRING, "m", 2184: chunk_cat("cc", chunk_from_thing(unused), 2185: chunk_create(from.ptr, 2186: (minbits + unused) / BITS_PER_BYTE))); 2187: unused = round_up(maxbits, BITS_PER_BYTE) - maxbits; 2188: to = asn1_wrap(ASN1_BIT_STRING, "m", 2189: chunk_cat("cc", chunk_from_thing(unused), 2190: chunk_create(to.ptr, 2191: (maxbits + unused) / BITS_PER_BYTE))); 2192: return asn1_wrap(ASN1_SEQUENCE, "mm", from, to); 2193: } 2194: 2195: /** 2196: * Generate and sign a new certificate 2197: */ 2198: static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert, 2199: private_key_t *sign_key, int digest_alg) 2200: { 2201: const chunk_t keyUsageCrlSign = chunk_from_chars(0x01, 0x02); 2202: const chunk_t keyUsageCertSignCrlSign = chunk_from_chars(0x01, 0x06); 2203: chunk_t extensions = chunk_empty, extendedKeyUsage = chunk_empty; 2204: chunk_t serverAuth = chunk_empty, clientAuth = chunk_empty; 2205: chunk_t ocspSigning = chunk_empty, certPolicies = chunk_empty; 2206: chunk_t basicConstraints = chunk_empty, nameConstraints = chunk_empty; 2207: chunk_t keyUsage = chunk_empty, keyUsageBits = chunk_empty; 2208: chunk_t subjectAltNames = chunk_empty, policyMappings = chunk_empty; 2209: chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty; 2210: chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty; 2211: chunk_t policyConstraints = chunk_empty, inhibitAnyPolicy = chunk_empty; 2212: chunk_t ikeIntermediate = chunk_empty, msSmartcardLogon = chunk_empty; 2213: chunk_t ipAddrBlocks = chunk_empty, sig_scheme = chunk_empty; 2214: chunk_t criticalExtension = chunk_empty; 2215: identification_t *issuer, *subject; 2216: chunk_t key_info; 2217: hasher_t *hasher; 2218: enumerator_t *enumerator; 2219: char *uri; 2220: 2221: subject = cert->subject; 2222: if (sign_cert) 2223: { 2224: issuer = sign_cert->get_subject(sign_cert); 2225: if (!cert->public_key) 2226: { 2227: return FALSE; 2228: } 2229: } 2230: else 2231: { /* self signed */ 2232: issuer = subject; 2233: if (!cert->public_key) 2234: { 2235: cert->public_key = sign_key->get_public_key(sign_key); 2236: } 2237: cert->flags |= X509_SELF_SIGNED; 2238: } 2239: cert->issuer = issuer->clone(issuer); 2240: if (!cert->notBefore) 2241: { 2242: cert->notBefore = time(NULL); 2243: } 2244: if (!cert->notAfter) 2245: { /* defaults to 1 year from now */ 2246: cert->notAfter = cert->notBefore + 60 * 60 * 24 * 365; 2247: } 2248: 2249: /* select signature scheme, if not already specified */ 2250: if (!cert->scheme) 2251: { 2252: INIT(cert->scheme, 2253: .scheme = signature_scheme_from_oid( 2254: hasher_signature_algorithm_to_oid(digest_alg, 2255: sign_key->get_type(sign_key))), 2256: ); 2257: } 2258: if (cert->scheme->scheme == SIGN_UNKNOWN) 2259: { 2260: return FALSE; 2261: } 2262: if (!signature_params_build(cert->scheme, &sig_scheme)) 2263: { 2264: return FALSE; 2265: } 2266: 2267: if (!cert->public_key->get_encoding(cert->public_key, 2268: PUBKEY_SPKI_ASN1_DER, &key_info)) 2269: { 2270: chunk_free(&sig_scheme); 2271: return FALSE; 2272: } 2273: 2274: /* encode subjectAltNames */ 2275: subjectAltNames = x509_build_subjectAltNames(cert->subjectAltNames); 2276: 2277: crlDistributionPoints = x509_build_crlDistributionPoints(cert->crl_uris, 2278: OID_CRL_DISTRIBUTION_POINTS); 2279: 2280: /* encode OCSP URIs in authorityInfoAccess extension */ 2281: enumerator = cert->ocsp_uris->create_enumerator(cert->ocsp_uris); 2282: while (enumerator->enumerate(enumerator, &uri)) 2283: { 2284: chunk_t accessDescription; 2285: 2286: accessDescription = asn1_wrap(ASN1_SEQUENCE, "mm", 2287: asn1_build_known_oid(OID_OCSP), 2288: asn1_wrap(ASN1_CONTEXT_S_6, "c", 2289: chunk_create(uri, strlen(uri)))); 2290: authorityInfoAccess = chunk_cat("mm", authorityInfoAccess, 2291: accessDescription); 2292: } 2293: enumerator->destroy(enumerator); 2294: if (authorityInfoAccess.ptr) 2295: { 2296: authorityInfoAccess = asn1_wrap(ASN1_SEQUENCE, "mm", 2297: asn1_build_known_oid(OID_AUTHORITY_INFO_ACCESS), 2298: asn1_wrap(ASN1_OCTET_STRING, "m", 2299: asn1_wrap(ASN1_SEQUENCE, "m", authorityInfoAccess))); 2300: } 2301: 2302: /* build CA basicConstraint and keyUsage flags for CA certificates */ 2303: if (cert->flags & X509_CA) 2304: { 2305: chunk_t pathLenConstraint = chunk_empty; 2306: 2307: if (cert->pathLenConstraint != X509_NO_CONSTRAINT) 2308: { 2309: pathLenConstraint = asn1_integer("c", 2310: chunk_from_thing(cert->pathLenConstraint)); 2311: } 2312: basicConstraints = asn1_wrap(ASN1_SEQUENCE, "mmm", 2313: asn1_build_known_oid(OID_BASIC_CONSTRAINTS), 2314: asn1_wrap(ASN1_BOOLEAN, "c", 2315: chunk_from_chars(0xFF)), 2316: asn1_wrap(ASN1_OCTET_STRING, "m", 2317: asn1_wrap(ASN1_SEQUENCE, "mm", 2318: asn1_wrap(ASN1_BOOLEAN, "c", 2319: chunk_from_chars(0xFF)), 2320: pathLenConstraint))); 2321: /* set CertificateSign and implicitly CRLsign */ 2322: keyUsageBits = keyUsageCertSignCrlSign; 2323: } 2324: else if (cert->flags & X509_CRL_SIGN) 2325: { 2326: keyUsageBits = keyUsageCrlSign; 2327: } 2328: if (keyUsageBits.len) 2329: { 2330: keyUsage = asn1_wrap(ASN1_SEQUENCE, "mmm", 2331: asn1_build_known_oid(OID_KEY_USAGE), 2332: asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)), 2333: asn1_wrap(ASN1_OCTET_STRING, "m", 2334: asn1_wrap(ASN1_BIT_STRING, "c", keyUsageBits))); 2335: } 2336: 2337: /* add extendedKeyUsage flags */ 2338: if (cert->flags & X509_SERVER_AUTH) 2339: { 2340: serverAuth = asn1_build_known_oid(OID_SERVER_AUTH); 2341: } 2342: if (cert->flags & X509_CLIENT_AUTH) 2343: { 2344: clientAuth = asn1_build_known_oid(OID_CLIENT_AUTH); 2345: } 2346: if (cert->flags & X509_IKE_INTERMEDIATE) 2347: { 2348: ikeIntermediate = asn1_build_known_oid(OID_IKE_INTERMEDIATE); 2349: } 2350: if (cert->flags & X509_OCSP_SIGNER) 2351: { 2352: ocspSigning = asn1_build_known_oid(OID_OCSP_SIGNING); 2353: } 2354: if (cert->flags & X509_MS_SMARTCARD_LOGON) 2355: { 2356: msSmartcardLogon = asn1_build_known_oid(OID_MS_SMARTCARD_LOGON); 2357: } 2358: 2359: if (serverAuth.ptr || clientAuth.ptr || ikeIntermediate.ptr || 2360: ocspSigning.ptr || msSmartcardLogon.ptr) 2361: { 2362: extendedKeyUsage = asn1_wrap(ASN1_SEQUENCE, "mm", 2363: asn1_build_known_oid(OID_EXTENDED_KEY_USAGE), 2364: asn1_wrap(ASN1_OCTET_STRING, "m", 2365: asn1_wrap(ASN1_SEQUENCE, "mmmmm", 2366: serverAuth, clientAuth, ikeIntermediate, 2367: ocspSigning, msSmartcardLogon))); 2368: } 2369: 2370: /* add subjectKeyIdentifier to CA and OCSP signer certificates */ 2371: if (cert->flags & (X509_CA | X509_OCSP_SIGNER | X509_CRL_SIGN)) 2372: { 2373: chunk_t keyid; 2374: 2375: if (cert->public_key->get_fingerprint(cert->public_key, 2376: KEYID_PUBKEY_SHA1, &keyid)) 2377: { 2378: subjectKeyIdentifier = asn1_wrap(ASN1_SEQUENCE, "mm", 2379: asn1_build_known_oid(OID_SUBJECT_KEY_ID), 2380: asn1_wrap(ASN1_OCTET_STRING, "m", 2381: asn1_wrap(ASN1_OCTET_STRING, "c", keyid))); 2382: } 2383: } 2384: 2385: /* add the keyid authKeyIdentifier for non self-signed certificates */ 2386: if (sign_cert) 2387: { 2388: chunk_t keyid; 2389: 2390: if (sign_key->get_fingerprint(sign_key, KEYID_PUBKEY_SHA1, &keyid)) 2391: { 2392: authKeyIdentifier = asn1_wrap(ASN1_SEQUENCE, "mm", 2393: asn1_build_known_oid(OID_AUTHORITY_KEY_ID), 2394: asn1_wrap(ASN1_OCTET_STRING, "m", 2395: asn1_wrap(ASN1_SEQUENCE, "m", 2396: asn1_wrap(ASN1_CONTEXT_S_0, "c", keyid)))); 2397: } 2398: } 2399: 2400: if (cert->ipAddrBlocks->get_count(cert->ipAddrBlocks)) 2401: { 2402: chunk_t v4blocks = chunk_empty, v6blocks = chunk_empty, block; 2403: traffic_selector_t *ts; 2404: 2405: enumerator = cert->ipAddrBlocks->create_enumerator(cert->ipAddrBlocks); 2406: while (enumerator->enumerate(enumerator, &ts)) 2407: { 2408: switch (ts->get_type(ts)) 2409: { 2410: case TS_IPV4_ADDR_RANGE: 2411: block = generate_ts(ts); 2412: v4blocks = chunk_cat("mm", v4blocks, block); 2413: break; 2414: case TS_IPV6_ADDR_RANGE: 2415: block = generate_ts(ts); 2416: v6blocks = chunk_cat("mm", v6blocks, block); 2417: break; 2418: default: 2419: break; 2420: } 2421: } 2422: enumerator->destroy(enumerator); 2423: 2424: if (v4blocks.ptr) 2425: { 2426: v4blocks = asn1_wrap(ASN1_SEQUENCE, "mm", 2427: asn1_wrap(ASN1_OCTET_STRING, "c", 2428: chunk_from_chars(0x00,0x01)), 2429: asn1_wrap(ASN1_SEQUENCE, "m", v4blocks)); 2430: } 2431: if (v6blocks.ptr) 2432: { 2433: v6blocks = asn1_wrap(ASN1_SEQUENCE, "mm", 2434: asn1_wrap(ASN1_OCTET_STRING, "c", 2435: chunk_from_chars(0x00,0x02)), 2436: asn1_wrap(ASN1_SEQUENCE, "m", v6blocks)); 2437: } 2438: ipAddrBlocks = asn1_wrap(ASN1_SEQUENCE, "mm", 2439: asn1_build_known_oid(OID_IP_ADDR_BLOCKS), 2440: asn1_wrap(ASN1_OCTET_STRING, "m", 2441: asn1_wrap(ASN1_SEQUENCE, "mm", 2442: v4blocks, v6blocks))); 2443: cert->flags |= X509_IP_ADDR_BLOCKS; 2444: } 2445: 2446: if (cert->permitted_names->get_count(cert->permitted_names) || 2447: cert->excluded_names->get_count(cert->excluded_names)) 2448: { 2449: chunk_t permitted = chunk_empty, excluded = chunk_empty, subtree; 2450: identification_t *id; 2451: 2452: enumerator = create_name_constraint_enumerator(cert, TRUE); 2453: while (enumerator->enumerate(enumerator, &id)) 2454: { 2455: subtree = asn1_wrap(ASN1_SEQUENCE, "m", build_generalName(id)); 2456: permitted = chunk_cat("mm", permitted, subtree); 2457: } 2458: enumerator->destroy(enumerator); 2459: if (permitted.ptr) 2460: { 2461: permitted = asn1_wrap(ASN1_CONTEXT_C_0, "m", permitted); 2462: } 2463: 2464: enumerator = create_name_constraint_enumerator(cert, FALSE); 2465: while (enumerator->enumerate(enumerator, &id)) 2466: { 2467: subtree = asn1_wrap(ASN1_SEQUENCE, "m", build_generalName(id)); 2468: excluded = chunk_cat("mm", excluded, subtree); 2469: } 2470: enumerator->destroy(enumerator); 2471: if (excluded.ptr) 2472: { 2473: excluded = asn1_wrap(ASN1_CONTEXT_C_1, "m", excluded); 2474: } 2475: 2476: nameConstraints = asn1_wrap(ASN1_SEQUENCE, "mm", 2477: asn1_build_known_oid(OID_NAME_CONSTRAINTS), 2478: asn1_wrap(ASN1_OCTET_STRING, "m", 2479: asn1_wrap(ASN1_SEQUENCE, "mm", 2480: permitted, excluded))); 2481: } 2482: 2483: if (cert->cert_policies->get_count(cert->cert_policies)) 2484: { 2485: x509_cert_policy_t *policy; 2486: 2487: enumerator = create_cert_policy_enumerator(cert); 2488: while (enumerator->enumerate(enumerator, &policy)) 2489: { 2490: chunk_t chunk = chunk_empty, cps = chunk_empty, notice = chunk_empty; 2491: 2492: if (policy->cps_uri) 2493: { 2494: cps = asn1_wrap(ASN1_SEQUENCE, "mm", 2495: asn1_build_known_oid(OID_POLICY_QUALIFIER_CPS), 2496: asn1_wrap(ASN1_IA5STRING, "c", 2497: chunk_create(policy->cps_uri, 2498: strlen(policy->cps_uri)))); 2499: } 2500: if (policy->unotice_text) 2501: { 2502: notice = asn1_wrap(ASN1_SEQUENCE, "mm", 2503: asn1_build_known_oid(OID_POLICY_QUALIFIER_UNOTICE), 2504: asn1_wrap(ASN1_SEQUENCE, "m", 2505: asn1_wrap(ASN1_VISIBLESTRING, "c", 2506: chunk_create(policy->unotice_text, 2507: strlen(policy->unotice_text))))); 2508: } 2509: if (cps.len || notice.len) 2510: { 2511: chunk = asn1_wrap(ASN1_SEQUENCE, "mm", cps, notice); 2512: } 2513: chunk = asn1_wrap(ASN1_SEQUENCE, "mm", 2514: asn1_wrap(ASN1_OID, "c", policy->oid), chunk); 2515: certPolicies = chunk_cat("mm", certPolicies, chunk); 2516: } 2517: enumerator->destroy(enumerator); 2518: 2519: certPolicies = asn1_wrap(ASN1_SEQUENCE, "mm", 2520: asn1_build_known_oid(OID_CERTIFICATE_POLICIES), 2521: asn1_wrap(ASN1_OCTET_STRING, "m", 2522: asn1_wrap(ASN1_SEQUENCE, "m", certPolicies))); 2523: } 2524: 2525: if (cert->policy_mappings->get_count(cert->policy_mappings)) 2526: { 2527: x509_policy_mapping_t *mapping; 2528: 2529: enumerator = create_policy_mapping_enumerator(cert); 2530: while (enumerator->enumerate(enumerator, &mapping)) 2531: { 2532: chunk_t chunk; 2533: 2534: chunk = asn1_wrap(ASN1_SEQUENCE, "mm", 2535: asn1_wrap(ASN1_OID, "c", mapping->issuer), 2536: asn1_wrap(ASN1_OID, "c", mapping->subject)); 2537: policyMappings = chunk_cat("mm", policyMappings, chunk); 2538: } 2539: enumerator->destroy(enumerator); 2540: 2541: policyMappings = asn1_wrap(ASN1_SEQUENCE, "mm", 2542: asn1_build_known_oid(OID_POLICY_MAPPINGS), 2543: asn1_wrap(ASN1_OCTET_STRING, "m", 2544: asn1_wrap(ASN1_SEQUENCE, "m", policyMappings))); 2545: } 2546: 2547: if (cert->inhibit_mapping != X509_NO_CONSTRAINT || 2548: cert->require_explicit != X509_NO_CONSTRAINT) 2549: { 2550: chunk_t inhibit = chunk_empty, explicit = chunk_empty; 2551: 2552: if (cert->require_explicit != X509_NO_CONSTRAINT) 2553: { 2554: explicit = asn1_wrap(ASN1_CONTEXT_C_0, "m", 2555: asn1_integer("c", 2556: chunk_from_thing(cert->require_explicit))); 2557: } 2558: if (cert->inhibit_mapping != X509_NO_CONSTRAINT) 2559: { 2560: inhibit = asn1_wrap(ASN1_CONTEXT_C_1, "m", 2561: asn1_integer("c", 2562: chunk_from_thing(cert->inhibit_mapping))); 2563: } 2564: policyConstraints = asn1_wrap(ASN1_SEQUENCE, "mmm", 2565: asn1_build_known_oid(OID_POLICY_CONSTRAINTS), 2566: asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)), 2567: asn1_wrap(ASN1_OCTET_STRING, "m", 2568: asn1_wrap(ASN1_SEQUENCE, "mm", 2569: explicit, inhibit))); 2570: } 2571: 2572: if (cert->inhibit_any != X509_NO_CONSTRAINT) 2573: { 2574: inhibitAnyPolicy = asn1_wrap(ASN1_SEQUENCE, "mmm", 2575: asn1_build_known_oid(OID_INHIBIT_ANY_POLICY), 2576: asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)), 2577: asn1_wrap(ASN1_OCTET_STRING, "m", 2578: asn1_integer("c", 2579: chunk_from_thing(cert->inhibit_any)))); 2580: } 2581: 2582: if (cert->critical_extension_oid.len > 0) 2583: { 2584: criticalExtension = asn1_wrap(ASN1_SEQUENCE, "mmm", 2585: asn1_simple_object(ASN1_OID, cert->critical_extension_oid), 2586: asn1_simple_object(ASN1_BOOLEAN, chunk_from_chars(0xFF)), 2587: asn1_simple_object(ASN1_OCTET_STRING, chunk_empty)); 2588: } 2589: 2590: if (basicConstraints.ptr || subjectAltNames.ptr || authKeyIdentifier.ptr || 2591: crlDistributionPoints.ptr || nameConstraints.ptr || ipAddrBlocks.ptr) 2592: { 2593: extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m", 2594: asn1_wrap(ASN1_SEQUENCE, "mmmmmmmmmmmmmmm", 2595: basicConstraints, keyUsage, subjectKeyIdentifier, 2596: authKeyIdentifier, subjectAltNames, 2597: extendedKeyUsage, crlDistributionPoints, 2598: authorityInfoAccess, nameConstraints, certPolicies, 2599: policyMappings, policyConstraints, inhibitAnyPolicy, 2600: ipAddrBlocks, criticalExtension)); 2601: } 2602: 2603: cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmccmcmm", 2604: asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2), 2605: asn1_integer("c", cert->serialNumber), 2606: sig_scheme, 2607: issuer->get_encoding(issuer), 2608: asn1_wrap(ASN1_SEQUENCE, "mm", 2609: asn1_from_time(&cert->notBefore, ASN1_UTCTIME), 2610: asn1_from_time(&cert->notAfter, ASN1_UTCTIME)), 2611: subject->get_encoding(subject), 2612: key_info, extensions); 2613: 2614: if (!sign_key->sign(sign_key, cert->scheme->scheme, cert->scheme->params, 2615: cert->tbsCertificate, &cert->signature)) 2616: { 2617: chunk_free(&sig_scheme); 2618: return FALSE; 2619: } 2620: cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm", cert->tbsCertificate, 2621: sig_scheme, 2622: asn1_bitstring("c", cert->signature)); 2623: 2624: hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); 2625: if (!hasher || 2626: !hasher->allocate_hash(hasher, cert->encoding, &cert->encoding_hash)) 2627: { 2628: DESTROY_IF(hasher); 2629: return FALSE; 2630: } 2631: hasher->destroy(hasher); 2632: return TRUE; 2633: } 2634: 2635: /** 2636: * See header. 2637: */ 2638: x509_cert_t *x509_cert_load(certificate_type_t type, va_list args) 2639: { 2640: x509_flag_t flags = 0; 2641: chunk_t blob = chunk_empty; 2642: 2643: while (TRUE) 2644: { 2645: switch (va_arg(args, builder_part_t)) 2646: { 2647: case BUILD_BLOB_ASN1_DER: 2648: blob = va_arg(args, chunk_t); 2649: continue; 2650: case BUILD_X509_FLAG: 2651: flags |= va_arg(args, x509_flag_t); 2652: continue; 2653: case BUILD_END: 2654: break; 2655: default: 2656: return NULL; 2657: } 2658: break; 2659: } 2660: 2661: if (blob.ptr) 2662: { 2663: private_x509_cert_t *cert = create_empty(); 2664: 2665: cert->encoding = chunk_clone(blob); 2666: cert->parsed = TRUE; 2667: if (parse_certificate(cert)) 2668: { 2669: cert->flags |= flags; 2670: return &cert->public; 2671: } 2672: destroy(cert); 2673: } 2674: return NULL; 2675: } 2676: 2677: /** 2678: * See header. 2679: */ 2680: x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args) 2681: { 2682: private_x509_cert_t *cert; 2683: certificate_t *sign_cert = NULL; 2684: private_key_t *sign_key = NULL; 2685: hash_algorithm_t digest_alg = HASH_SHA256; 2686: u_int constraint; 2687: 2688: cert = create_empty(); 2689: while (TRUE) 2690: { 2691: switch (va_arg(args, builder_part_t)) 2692: { 2693: case BUILD_X509_FLAG: 2694: cert->flags |= va_arg(args, x509_flag_t); 2695: continue; 2696: case BUILD_SIGNING_KEY: 2697: sign_key = va_arg(args, private_key_t*); 2698: continue; 2699: case BUILD_SIGNING_CERT: 2700: sign_cert = va_arg(args, certificate_t*); 2701: continue; 2702: case BUILD_PUBLIC_KEY: 2703: cert->public_key = va_arg(args, public_key_t*); 2704: cert->public_key->get_ref(cert->public_key); 2705: continue; 2706: case BUILD_SUBJECT: 2707: cert->subject = va_arg(args, identification_t*); 2708: cert->subject = cert->subject->clone(cert->subject); 2709: continue; 2710: case BUILD_SUBJECT_ALTNAMES: 2711: { 2712: enumerator_t *enumerator; 2713: identification_t *id; 2714: linked_list_t *list; 2715: 2716: list = va_arg(args, linked_list_t*); 2717: enumerator = list->create_enumerator(list); 2718: while (enumerator->enumerate(enumerator, &id)) 2719: { 2720: cert->subjectAltNames->insert_last(cert->subjectAltNames, 2721: id->clone(id)); 2722: } 2723: enumerator->destroy(enumerator); 2724: continue; 2725: } 2726: case BUILD_CRL_DISTRIBUTION_POINTS: 2727: { 2728: enumerator_t *enumerator; 2729: linked_list_t *list; 2730: x509_cdp_t *in, *cdp; 2731: 2732: list = va_arg(args, linked_list_t*); 2733: enumerator = list->create_enumerator(list); 2734: while (enumerator->enumerate(enumerator, &in)) 2735: { 2736: INIT(cdp, 2737: .uri = strdup(in->uri), 2738: .issuer = in->issuer ? in->issuer->clone(in->issuer) : NULL, 2739: ); 2740: cert->crl_uris->insert_last(cert->crl_uris, cdp); 2741: } 2742: enumerator->destroy(enumerator); 2743: continue; 2744: } 2745: case BUILD_OCSP_ACCESS_LOCATIONS: 2746: { 2747: enumerator_t *enumerator; 2748: linked_list_t *list; 2749: char *uri; 2750: 2751: list = va_arg(args, linked_list_t*); 2752: enumerator = list->create_enumerator(list); 2753: while (enumerator->enumerate(enumerator, &uri)) 2754: { 2755: cert->ocsp_uris->insert_last(cert->ocsp_uris, strdup(uri)); 2756: } 2757: enumerator->destroy(enumerator); 2758: continue; 2759: } 2760: case BUILD_PATHLEN: 2761: constraint = va_arg(args, u_int); 2762: cert->pathLenConstraint = (constraint < 128) ? 2763: constraint : X509_NO_CONSTRAINT; 2764: continue; 2765: case BUILD_ADDRBLOCKS: 2766: { 2767: enumerator_t *enumerator; 2768: traffic_selector_t *ts; 2769: linked_list_t *list; 2770: 2771: list = va_arg(args, linked_list_t*); 2772: enumerator = list->create_enumerator(list); 2773: while (enumerator->enumerate(enumerator, &ts)) 2774: { 2775: cert->ipAddrBlocks->insert_last(cert->ipAddrBlocks, 2776: ts->clone(ts)); 2777: } 2778: enumerator->destroy(enumerator); 2779: continue; 2780: } 2781: case BUILD_PERMITTED_NAME_CONSTRAINTS: 2782: { 2783: enumerator_t *enumerator; 2784: linked_list_t *list; 2785: identification_t *constraint; 2786: 2787: list = va_arg(args, linked_list_t*); 2788: enumerator = list->create_enumerator(list); 2789: while (enumerator->enumerate(enumerator, &constraint)) 2790: { 2791: cert->permitted_names->insert_last(cert->permitted_names, 2792: constraint->clone(constraint)); 2793: } 2794: enumerator->destroy(enumerator); 2795: continue; 2796: } 2797: case BUILD_EXCLUDED_NAME_CONSTRAINTS: 2798: { 2799: enumerator_t *enumerator; 2800: linked_list_t *list; 2801: identification_t *constraint; 2802: 2803: list = va_arg(args, linked_list_t*); 2804: enumerator = list->create_enumerator(list); 2805: while (enumerator->enumerate(enumerator, &constraint)) 2806: { 2807: cert->excluded_names->insert_last(cert->excluded_names, 2808: constraint->clone(constraint)); 2809: } 2810: enumerator->destroy(enumerator); 2811: continue; 2812: } 2813: case BUILD_CERTIFICATE_POLICIES: 2814: { 2815: enumerator_t *enumerator; 2816: linked_list_t *list; 2817: x509_cert_policy_t *policy, *in; 2818: 2819: list = va_arg(args, linked_list_t*); 2820: enumerator = list->create_enumerator(list); 2821: while (enumerator->enumerate(enumerator, &in)) 2822: { 2823: INIT(policy, 2824: .oid = chunk_clone(in->oid), 2825: .cps_uri = strdupnull(in->cps_uri), 2826: .unotice_text = strdupnull(in->unotice_text), 2827: ); 2828: cert->cert_policies->insert_last(cert->cert_policies, policy); 2829: } 2830: enumerator->destroy(enumerator); 2831: continue; 2832: } 2833: case BUILD_POLICY_MAPPINGS: 2834: { 2835: enumerator_t *enumerator; 2836: linked_list_t *list; 2837: x509_policy_mapping_t* mapping, *in; 2838: 2839: list = va_arg(args, linked_list_t*); 2840: enumerator = list->create_enumerator(list); 2841: while (enumerator->enumerate(enumerator, &in)) 2842: { 2843: INIT(mapping, 2844: .issuer = chunk_clone(in->issuer), 2845: .subject = chunk_clone(in->subject), 2846: ); 2847: cert->policy_mappings->insert_last(cert->policy_mappings, 2848: mapping); 2849: } 2850: enumerator->destroy(enumerator); 2851: continue; 2852: } 2853: case BUILD_POLICY_REQUIRE_EXPLICIT: 2854: constraint = va_arg(args, u_int); 2855: cert->require_explicit = (constraint < 128) ? 2856: constraint : X509_NO_CONSTRAINT; 2857: continue; 2858: case BUILD_POLICY_INHIBIT_MAPPING: 2859: constraint = va_arg(args, u_int); 2860: cert->inhibit_mapping = (constraint < 128) ? 2861: constraint : X509_NO_CONSTRAINT; 2862: continue; 2863: case BUILD_POLICY_INHIBIT_ANY: 2864: constraint = va_arg(args, u_int); 2865: cert->inhibit_any = (constraint < 128) ? 2866: constraint : X509_NO_CONSTRAINT; 2867: continue; 2868: case BUILD_NOT_BEFORE_TIME: 2869: cert->notBefore = va_arg(args, time_t); 2870: continue; 2871: case BUILD_NOT_AFTER_TIME: 2872: cert->notAfter = va_arg(args, time_t); 2873: continue; 2874: case BUILD_SERIAL: 2875: cert->serialNumber = chunk_clone(va_arg(args, chunk_t)); 2876: continue; 2877: case BUILD_SIGNATURE_SCHEME: 2878: cert->scheme = va_arg(args, signature_params_t*); 2879: cert->scheme = signature_params_clone(cert->scheme); 2880: continue; 2881: case BUILD_DIGEST_ALG: 2882: digest_alg = va_arg(args, int); 2883: continue; 2884: case BUILD_CRITICAL_EXTENSION: 2885: cert->critical_extension_oid = chunk_clone(va_arg(args, chunk_t)); 2886: continue; 2887: case BUILD_END: 2888: break; 2889: default: 2890: destroy(cert); 2891: return NULL; 2892: } 2893: break; 2894: } 2895: 2896: if (sign_key && generate(cert, sign_cert, sign_key, digest_alg)) 2897: { 2898: return &cert->public; 2899: } 2900: destroy(cert); 2901: return NULL; 2902: }