Return to x509_crl.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / x509 |
1.1 misho 1: /* 2: * Copyright (C) 2014-2017 Tobias Brunner 3: * Copyright (C) 2008-2009 Martin Willi 4: * Copyright (C) 2017 Andreas Steffen 5: * HSR Hochschule fuer Technik Rapperswil 6: * 7: * This program is free software; you can redistribute it and/or modify it 8: * under the terms of the GNU General Public License as published by the 9: * Free Software Foundation; either version 2 of the License, or (at your 10: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 11: * 12: * This program is distributed in the hope that it will be useful, but 13: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15: * for more details. 16: */ 17: 18: #include "x509_crl.h" 19: 20: typedef struct private_x509_crl_t private_x509_crl_t; 21: typedef struct revoked_t revoked_t; 22: 23: #include <time.h> 24: 25: #include <utils/debug.h> 26: #include <library.h> 27: #include <asn1/oid.h> 28: #include <asn1/asn1.h> 29: #include <asn1/asn1_parser.h> 30: #include <credentials/certificates/x509.h> 31: #include <credentials/keys/private_key.h> 32: #include <collections/linked_list.h> 33: 34: /** 35: * entry for a revoked certificate 36: */ 37: struct revoked_t { 38: /** 39: * serial of the revoked certificate 40: */ 41: chunk_t serial; 42: 43: /** 44: * date of revocation 45: */ 46: time_t date; 47: 48: /** 49: * reason for revocation 50: */ 51: crl_reason_t reason; 52: }; 53: 54: /** 55: * private data of x509_crl 56: */ 57: struct private_x509_crl_t { 58: 59: /** 60: * public functions 61: */ 62: x509_crl_t public; 63: 64: /** 65: * X.509 crl encoding in ASN.1 DER format 66: */ 67: chunk_t encoding; 68: 69: /** 70: * X.509 crl body over which signature is computed 71: */ 72: chunk_t tbsCertList; 73: 74: /** 75: * Version of the X.509 crl 76: */ 77: u_int version; 78: 79: /** 80: * ID representing the crl issuer 81: */ 82: identification_t *issuer; 83: 84: /** 85: * CRL number 86: */ 87: chunk_t crlNumber; 88: 89: /** 90: * Time when the crl was generated 91: */ 92: time_t thisUpdate; 93: 94: /** 95: * Time when an update crl will be available 96: */ 97: time_t nextUpdate; 98: 99: /** 100: * list of revoked certificates as revoked_t 101: */ 102: linked_list_t *revoked; 103: 104: /** 105: * List of Freshest CRL distribution points 106: */ 107: linked_list_t *crl_uris; 108: 109: /** 110: * Authority Key Identifier 111: */ 112: chunk_t authKeyIdentifier; 113: 114: /** 115: * Authority Key Serial Number 116: */ 117: chunk_t authKeySerialNumber; 118: 119: /** 120: * Optional OID of an [unsupported] critical extension 121: */ 122: chunk_t critical_extension_oid; 123: 124: /** 125: * Number of BaseCRL, if a delta CRL 126: */ 127: chunk_t baseCrlNumber; 128: 129: /** 130: * Signature scheme 131: */ 132: signature_params_t *scheme; 133: 134: /** 135: * Signature 136: */ 137: chunk_t signature; 138: 139: /** 140: * has this CRL been generated 141: */ 142: bool generated; 143: 144: /** 145: * reference counter 146: */ 147: refcount_t ref; 148: }; 149: 150: /** 151: * from x509_cert 152: */ 153: extern chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob, int level0, 154: chunk_t *authKeySerialNumber); 155: 156: /** 157: * from x509_cert 158: */ 159: extern bool x509_parse_crlDistributionPoints(chunk_t blob, int level0, 160: linked_list_t *list); 161: 162: /** 163: * from x509_cert 164: */ 165: extern chunk_t x509_build_crlDistributionPoints(linked_list_t *list, int extn); 166: 167: /** 168: * ASN.1 definition of an X.509 certificate revocation list 169: */ 170: static const asn1Object_t crlObjects[] = { 171: { 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */ 172: { 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */ 173: { 2, "version", ASN1_INTEGER, ASN1_OPT | 174: ASN1_BODY }, /* 2 */ 175: { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */ 176: { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 4 */ 177: { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */ 178: { 2, "thisUpdate", ASN1_EOC, ASN1_RAW }, /* 6 */ 179: { 2, "nextUpdate", ASN1_EOC, ASN1_RAW }, /* 7 */ 180: { 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT | 181: ASN1_LOOP }, /* 8 */ 182: { 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 9 */ 183: { 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 10 */ 184: { 4, "revocationDate", ASN1_EOC, ASN1_RAW }, /* 11 */ 185: { 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT | 186: ASN1_LOOP }, /* 12 */ 187: { 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */ 188: { 6, "extnID", ASN1_OID, ASN1_BODY }, /* 14 */ 189: { 6, "critical", ASN1_BOOLEAN, ASN1_DEF | 190: ASN1_BODY }, /* 15 */ 191: { 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */ 192: { 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 17 */ 193: { 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 18 */ 194: { 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 19 */ 195: { 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */ 196: { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */ 197: { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */ 198: { 5, "critical", ASN1_BOOLEAN, ASN1_DEF | 199: ASN1_BODY }, /* 23 */ 200: { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */ 201: { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */ 202: { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */ 203: { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */ 204: { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 28 */ 205: { 0, "exit", ASN1_EOC, ASN1_EXIT } 206: }; 207: #define CRL_OBJ_TBS_CERT_LIST 1 208: #define CRL_OBJ_VERSION 2 209: #define CRL_OBJ_SIG_ALG 4 210: #define CRL_OBJ_ISSUER 5 211: #define CRL_OBJ_THIS_UPDATE 6 212: #define CRL_OBJ_NEXT_UPDATE 7 213: #define CRL_OBJ_USER_CERTIFICATE 10 214: #define CRL_OBJ_REVOCATION_DATE 11 215: #define CRL_OBJ_CRL_ENTRY_EXTN_ID 14 216: #define CRL_OBJ_CRL_ENTRY_CRITICAL 15 217: #define CRL_OBJ_CRL_ENTRY_EXTN_VALUE 16 218: #define CRL_OBJ_EXTN_ID 22 219: #define CRL_OBJ_CRITICAL 23 220: #define CRL_OBJ_EXTN_VALUE 24 221: #define CRL_OBJ_ALGORITHM 27 222: #define CRL_OBJ_SIGNATURE 28 223: 224: /** 225: * Parses an X.509 Certificate Revocation List (CRL) 226: */ 227: static bool parse(private_x509_crl_t *this) 228: { 229: asn1_parser_t *parser; 230: chunk_t object; 231: chunk_t extnID = chunk_empty; 232: chunk_t userCertificate = chunk_empty; 233: int objectID; 234: signature_params_t sig_alg = {}; 235: bool success = FALSE; 236: bool critical = FALSE; 237: revoked_t *revoked = NULL; 238: 239: parser = asn1_parser_create(crlObjects, this->encoding); 240: 241: while (parser->iterate(parser, &objectID, &object)) 242: { 243: u_int level = parser->get_level(parser)+1; 244: 245: switch (objectID) 246: { 247: case CRL_OBJ_TBS_CERT_LIST: 248: this->tbsCertList = object; 249: break; 250: case CRL_OBJ_VERSION: 251: this->version = (object.len) ? (1+(u_int)*object.ptr) : 1; 252: DBG2(DBG_ASN, " v%d", this->version); 253: break; 254: case CRL_OBJ_SIG_ALG: 255: if (!signature_params_parse(object, level, &sig_alg)) 256: { 257: DBG1(DBG_ASN, " unable to parse signature algorithm"); 258: goto end; 259: } 260: break; 261: case CRL_OBJ_ISSUER: 262: this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object); 263: DBG2(DBG_ASN, " '%Y'", this->issuer); 264: break; 265: case CRL_OBJ_THIS_UPDATE: 266: this->thisUpdate = asn1_parse_time(object, level); 267: break; 268: case CRL_OBJ_NEXT_UPDATE: 269: this->nextUpdate = asn1_parse_time(object, level); 270: break; 271: case CRL_OBJ_USER_CERTIFICATE: 272: userCertificate = object; 273: break; 274: case CRL_OBJ_REVOCATION_DATE: 275: revoked = malloc_thing(revoked_t); 276: revoked->serial = chunk_clone(userCertificate); 277: revoked->date = asn1_parse_time(object, level); 278: revoked->reason = CRL_REASON_UNSPECIFIED; 279: this->revoked->insert_last(this->revoked, (void *)revoked); 280: break; 281: case CRL_OBJ_CRL_ENTRY_EXTN_ID: 282: case CRL_OBJ_EXTN_ID: 283: extnID = object; 284: break; 285: case CRL_OBJ_CRL_ENTRY_CRITICAL: 286: case CRL_OBJ_CRITICAL: 287: critical = object.len && *object.ptr; 288: DBG2(DBG_ASN, " %s", critical ? "TRUE" : "FALSE"); 289: break; 290: case CRL_OBJ_CRL_ENTRY_EXTN_VALUE: 291: case CRL_OBJ_EXTN_VALUE: 292: { 293: int extn_oid = asn1_known_oid(extnID); 294: 295: switch (extn_oid) 296: { 297: case OID_CRL_REASON_CODE: 298: if (revoked) 299: { 300: if (object.len && *object.ptr == ASN1_ENUMERATED && 301: asn1_length(&object) == 1) 302: { 303: revoked->reason = *object.ptr; 304: } 305: DBG2(DBG_ASN, " '%N'", crl_reason_names, 306: revoked->reason); 307: } 308: break; 309: case OID_AUTHORITY_KEY_ID: 310: chunk_free(&this->authKeyIdentifier); 311: this->authKeyIdentifier = 312: x509_parse_authorityKeyIdentifier( 313: object, level, &this->authKeySerialNumber); 314: break; 315: case OID_CRL_NUMBER: 316: if (!asn1_parse_simple_object(&object, ASN1_INTEGER, 317: level, "crlNumber")) 318: { 319: goto end; 320: } 321: this->crlNumber = object; 322: break; 323: case OID_FRESHEST_CRL: 324: if (!x509_parse_crlDistributionPoints(object, level, 325: this->crl_uris)) 326: { 327: goto end; 328: } 329: break; 330: case OID_DELTA_CRL_INDICATOR: 331: if (!asn1_parse_simple_object(&object, ASN1_INTEGER, 332: level, "deltaCrlIndicator")) 333: { 334: goto end; 335: } 336: this->baseCrlNumber = object; 337: break; 338: case OID_ISSUING_DIST_POINT: 339: /* TODO support of IssuingDistributionPoints */ 340: break; 341: default: 342: if (critical && lib->settings->get_bool(lib->settings, 343: "%s.x509.enforce_critical", TRUE, lib->ns)) 344: { 345: DBG1(DBG_ASN, "critical '%s' extension not supported", 346: (extn_oid == OID_UNKNOWN) ? "unknown" : 347: (char*)oid_names[extn_oid].name); 348: goto end; 349: } 350: break; 351: } 352: break; 353: } 354: case CRL_OBJ_ALGORITHM: 355: { 356: INIT(this->scheme); 357: if (!signature_params_parse(object, level, this->scheme)) 358: { 359: DBG1(DBG_ASN, " unable to parse signature algorithm"); 360: goto end; 361: } 362: if (!signature_params_equal(this->scheme, &sig_alg)) 363: { 364: DBG1(DBG_ASN, " signature algorithms do not agree"); 365: goto end; 366: } 367: break; 368: } 369: case CRL_OBJ_SIGNATURE: 370: this->signature = chunk_skip(object, 1); 371: break; 372: default: 373: break; 374: } 375: } 376: success = parser->success(parser); 377: 378: end: 379: parser->destroy(parser); 380: signature_params_clear(&sig_alg); 381: return success; 382: } 383: 384: CALLBACK(filter, bool, 385: void *data, enumerator_t *orig, va_list args) 386: { 387: revoked_t *revoked; 388: crl_reason_t *reason; 389: chunk_t *serial; 390: time_t *date; 391: 392: VA_ARGS_VGET(args, serial, date, reason); 393: 394: if (orig->enumerate(orig, &revoked)) 395: { 396: if (serial) 397: { 398: *serial = revoked->serial; 399: } 400: if (date) 401: { 402: *date = revoked->date; 403: } 404: if (reason) 405: { 406: *reason = revoked->reason; 407: } 408: return TRUE; 409: } 410: return FALSE; 411: } 412: 413: METHOD(crl_t, get_serial, chunk_t, 414: private_x509_crl_t *this) 415: { 416: return this->crlNumber; 417: } 418: 419: METHOD(crl_t, get_authKeyIdentifier, chunk_t, 420: private_x509_crl_t *this) 421: { 422: return this->authKeyIdentifier; 423: } 424: 425: METHOD(crl_t, is_delta_crl, bool, 426: private_x509_crl_t *this, chunk_t *base_crl) 427: { 428: if (this->baseCrlNumber.len) 429: { 430: if (base_crl) 431: { 432: *base_crl = this->baseCrlNumber; 433: } 434: return TRUE; 435: } 436: return FALSE; 437: } 438: 439: METHOD(crl_t, create_delta_crl_uri_enumerator, enumerator_t*, 440: private_x509_crl_t *this) 441: { 442: return this->crl_uris->create_enumerator(this->crl_uris); 443: } 444: 445: METHOD(crl_t, create_enumerator, enumerator_t*, 446: private_x509_crl_t *this) 447: { 448: return enumerator_create_filter( 449: this->revoked->create_enumerator(this->revoked), 450: filter, NULL, NULL); 451: } 452: 453: METHOD(certificate_t, get_type, certificate_type_t, 454: private_x509_crl_t *this) 455: { 456: return CERT_X509_CRL; 457: } 458: 459: METHOD(certificate_t, get_issuer, identification_t*, 460: private_x509_crl_t *this) 461: { 462: return this->issuer; 463: } 464: 465: METHOD(certificate_t, has_issuer, id_match_t, 466: private_x509_crl_t *this, identification_t *issuer) 467: { 468: if (issuer->get_type(issuer) == ID_KEY_ID && this->authKeyIdentifier.ptr && 469: chunk_equals(this->authKeyIdentifier, issuer->get_encoding(issuer))) 470: { 471: return ID_MATCH_PERFECT; 472: } 473: return this->issuer->matches(this->issuer, issuer); 474: } 475: 476: METHOD(certificate_t, issued_by, bool, 477: private_x509_crl_t *this, certificate_t *issuer, 478: signature_params_t **scheme) 479: { 480: public_key_t *key; 481: bool valid; 482: x509_t *x509 = (x509_t*)issuer; 483: chunk_t keyid = chunk_empty; 484: 485: /* check if issuer is an X.509 CA certificate */ 486: if (issuer->get_type(issuer) != CERT_X509) 487: { 488: return FALSE; 489: } 490: if (!(x509->get_flags(x509) & (X509_CA | X509_CRL_SIGN))) 491: { 492: return FALSE; 493: } 494: 495: /* compare keyIdentifiers if available, otherwise use DNs */ 496: if (this->authKeyIdentifier.ptr) 497: { 498: keyid = x509->get_subjectKeyIdentifier(x509); 499: if (keyid.len && !chunk_equals(keyid, this->authKeyIdentifier)) 500: { 501: return FALSE; 502: } 503: } 504: if (!keyid.len) 505: { 506: if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer))) 507: { 508: return FALSE; 509: } 510: } 511: 512: key = issuer->get_public_key(issuer); 513: if (!key) 514: { 515: return FALSE; 516: } 517: valid = key->verify(key, this->scheme->scheme, this->scheme->params, 518: this->tbsCertList, this->signature); 519: key->destroy(key); 520: if (valid && scheme) 521: { 522: *scheme = signature_params_clone(this->scheme); 523: } 524: return valid; 525: } 526: 527: METHOD(certificate_t, get_public_key, public_key_t*, 528: private_x509_crl_t *this) 529: { 530: return NULL; 531: } 532: 533: METHOD(certificate_t, get_ref, certificate_t*, 534: private_x509_crl_t *this) 535: { 536: ref_get(&this->ref); 537: return &this->public.crl.certificate; 538: } 539: 540: METHOD(certificate_t, get_validity, bool, 541: private_x509_crl_t *this, time_t *when, 542: time_t *not_before, time_t *not_after) 543: { 544: time_t t = when ? *when : time(NULL); 545: 546: if (not_before) 547: { 548: *not_before = this->thisUpdate; 549: } 550: if (not_after) 551: { 552: *not_after = this->nextUpdate; 553: } 554: return (t >= this->thisUpdate && t <= this->nextUpdate); 555: } 556: 557: METHOD(certificate_t, get_encoding, bool, 558: private_x509_crl_t *this, cred_encoding_type_t type, chunk_t *encoding) 559: { 560: if (type == CERT_ASN1_DER) 561: { 562: *encoding = chunk_clone(this->encoding); 563: return TRUE; 564: } 565: return lib->encoding->encode(lib->encoding, type, NULL, encoding, 566: CRED_PART_X509_CRL_ASN1_DER, this->encoding, CRED_PART_END); 567: } 568: 569: METHOD(certificate_t, equals, bool, 570: private_x509_crl_t *this, certificate_t *other) 571: { 572: chunk_t encoding; 573: bool equal; 574: 575: if ((certificate_t*)this == other) 576: { 577: return TRUE; 578: } 579: if (other->equals == (void*)equals) 580: { /* skip allocation if we have the same implementation */ 581: return chunk_equals(this->encoding, ((private_x509_crl_t*)other)->encoding); 582: } 583: if (!other->get_encoding(other, CERT_ASN1_DER, &encoding)) 584: { 585: return FALSE; 586: } 587: equal = chunk_equals(this->encoding, encoding); 588: free(encoding.ptr); 589: return equal; 590: } 591: 592: /** 593: * Destroy a revoked_t entry 594: */ 595: static void revoked_destroy(revoked_t *revoked) 596: { 597: free(revoked->serial.ptr); 598: free(revoked); 599: } 600: 601: METHOD(certificate_t, destroy, void, 602: private_x509_crl_t *this) 603: { 604: if (ref_put(&this->ref)) 605: { 606: this->revoked->destroy_function(this->revoked, (void*)revoked_destroy); 607: this->crl_uris->destroy_function(this->crl_uris, 608: (void*)x509_cdp_destroy); 609: signature_params_destroy(this->scheme); 610: DESTROY_IF(this->issuer); 611: free(this->authKeyIdentifier.ptr); 612: free(this->encoding.ptr); 613: free(this->critical_extension_oid.ptr); 614: if (this->generated) 615: { 616: free(this->crlNumber.ptr); 617: free(this->baseCrlNumber.ptr); 618: free(this->signature.ptr); 619: free(this->tbsCertList.ptr); 620: } 621: free(this); 622: } 623: } 624: 625: /** 626: * create an empty but initialized X.509 crl 627: */ 628: static private_x509_crl_t* create_empty(void) 629: { 630: private_x509_crl_t *this; 631: 632: INIT(this, 633: .public = { 634: .crl = { 635: .certificate = { 636: .get_type = _get_type, 637: .get_subject = _get_issuer, 638: .get_issuer = _get_issuer, 639: .has_subject = _has_issuer, 640: .has_issuer = _has_issuer, 641: .issued_by = _issued_by, 642: .get_public_key = _get_public_key, 643: .get_validity = _get_validity, 644: .get_encoding = _get_encoding, 645: .equals = _equals, 646: .get_ref = _get_ref, 647: .destroy = _destroy, 648: }, 649: .get_serial = _get_serial, 650: .get_authKeyIdentifier = _get_authKeyIdentifier, 651: .is_delta_crl = _is_delta_crl, 652: .create_delta_crl_uri_enumerator = _create_delta_crl_uri_enumerator, 653: .create_enumerator = _create_enumerator, 654: }, 655: }, 656: .revoked = linked_list_create(), 657: .crl_uris = linked_list_create(), 658: .ref = 1, 659: ); 660: return this; 661: } 662: 663: /** 664: * See header. 665: */ 666: x509_crl_t *x509_crl_load(certificate_type_t type, va_list args) 667: { 668: chunk_t blob = chunk_empty; 669: 670: while (TRUE) 671: { 672: switch (va_arg(args, builder_part_t)) 673: { 674: case BUILD_BLOB_ASN1_DER: 675: blob = va_arg(args, chunk_t); 676: continue; 677: case BUILD_END: 678: break; 679: default: 680: return NULL; 681: } 682: break; 683: } 684: if (blob.ptr) 685: { 686: private_x509_crl_t *crl = create_empty(); 687: 688: crl->encoding = chunk_clone(blob); 689: if (parse(crl)) 690: { 691: return &crl->public; 692: } 693: destroy(crl); 694: } 695: return NULL; 696: }; 697: 698: /** 699: * Read certificate status from enumerator, copy to crl 700: */ 701: static void read_revoked(private_x509_crl_t *crl, enumerator_t *enumerator) 702: { 703: revoked_t *revoked; 704: chunk_t serial; 705: time_t date; 706: crl_reason_t reason; 707: 708: while (enumerator->enumerate(enumerator, &serial, &date, &reason)) 709: { 710: INIT(revoked, 711: .serial = chunk_clone(serial), 712: .date = date, 713: .reason = reason, 714: ); 715: crl->revoked->insert_last(crl->revoked, revoked); 716: } 717: } 718: 719: /** 720: * Generate CRL encoding, sign CRL 721: */ 722: static bool generate(private_x509_crl_t *this, certificate_t *cert, 723: private_key_t *key, hash_algorithm_t digest_alg) 724: { 725: chunk_t extensions = chunk_empty, certList = chunk_empty, serial; 726: chunk_t crlDistributionPoints = chunk_empty, baseCrlNumber = chunk_empty; 727: chunk_t sig_scheme = chunk_empty, criticalExtension = chunk_empty; 728: enumerator_t *enumerator; 729: crl_reason_t reason; 730: time_t date; 731: x509_t *x509; 732: 733: x509 = (x509_t*)cert; 734: 735: this->issuer = cert->get_subject(cert); 736: this->issuer = this->issuer->clone(this->issuer); 737: 738: this->authKeyIdentifier = chunk_clone(x509->get_subjectKeyIdentifier(x509)); 739: 740: /* select signature scheme, if not already specified */ 741: if (!this->scheme) 742: { 743: INIT(this->scheme, 744: .scheme = signature_scheme_from_oid( 745: hasher_signature_algorithm_to_oid(digest_alg, 746: key->get_type(key))), 747: ); 748: } 749: if (this->scheme->scheme == SIGN_UNKNOWN) 750: { 751: return FALSE; 752: } 753: if (!signature_params_build(this->scheme, &sig_scheme)) 754: { 755: return FALSE; 756: } 757: 758: enumerator = create_enumerator(this); 759: while (enumerator->enumerate(enumerator, &serial, &date, &reason)) 760: { 761: chunk_t revoked, entry_ext = chunk_empty; 762: 763: if (reason != CRL_REASON_UNSPECIFIED) 764: { 765: entry_ext = asn1_wrap(ASN1_SEQUENCE, "m", 766: asn1_wrap(ASN1_SEQUENCE, "mm", 767: asn1_build_known_oid(OID_CRL_REASON_CODE), 768: asn1_wrap(ASN1_OCTET_STRING, "m", 769: asn1_wrap(ASN1_ENUMERATED, "c", 770: chunk_from_chars(reason))))); 771: } 772: revoked = asn1_wrap(ASN1_SEQUENCE, "mmm", 773: asn1_integer("c", serial), 774: asn1_from_time(&date, ASN1_UTCTIME), 775: entry_ext); 776: certList = chunk_cat("mm", certList, revoked); 777: } 778: enumerator->destroy(enumerator); 779: 780: crlDistributionPoints = x509_build_crlDistributionPoints(this->crl_uris, 781: OID_FRESHEST_CRL); 782: 783: if (this->baseCrlNumber.len) 784: { 785: baseCrlNumber = asn1_wrap(ASN1_SEQUENCE, "mmm", 786: asn1_build_known_oid(OID_DELTA_CRL_INDICATOR), 787: asn1_wrap(ASN1_BOOLEAN, "c", 788: chunk_from_chars(0xFF)), 789: asn1_wrap(ASN1_OCTET_STRING, "m", 790: asn1_integer("c", this->baseCrlNumber))); 791: } 792: 793: if (this->critical_extension_oid.len > 0) 794: { 795: criticalExtension = asn1_wrap(ASN1_SEQUENCE, "mmm", 796: asn1_simple_object(ASN1_OID, this->critical_extension_oid), 797: asn1_simple_object(ASN1_BOOLEAN, chunk_from_chars(0xFF)), 798: asn1_simple_object(ASN1_OCTET_STRING, chunk_empty)); 799: } 800: 801: extensions = asn1_wrap(ASN1_CONTEXT_C_0, "m", 802: asn1_wrap(ASN1_SEQUENCE, "mmmmm", 803: asn1_wrap(ASN1_SEQUENCE, "mm", 804: asn1_build_known_oid(OID_AUTHORITY_KEY_ID), 805: asn1_wrap(ASN1_OCTET_STRING, "m", 806: asn1_wrap(ASN1_SEQUENCE, "m", 807: asn1_wrap(ASN1_CONTEXT_S_0, "c", 808: this->authKeyIdentifier)))), 809: asn1_wrap(ASN1_SEQUENCE, "mm", 810: asn1_build_known_oid(OID_CRL_NUMBER), 811: asn1_wrap(ASN1_OCTET_STRING, "m", 812: asn1_integer("c", this->crlNumber))), 813: crlDistributionPoints, baseCrlNumber, 814: criticalExtension)); 815: 816: this->tbsCertList = asn1_wrap(ASN1_SEQUENCE, "cccmmmm", 817: ASN1_INTEGER_1, 818: sig_scheme, 819: this->issuer->get_encoding(this->issuer), 820: asn1_from_time(&this->thisUpdate, ASN1_UTCTIME), 821: asn1_from_time(&this->nextUpdate, ASN1_UTCTIME), 822: asn1_wrap(ASN1_SEQUENCE, "m", certList), 823: extensions); 824: 825: if (!key->sign(key, this->scheme->scheme, this->scheme->params, 826: this->tbsCertList, &this->signature)) 827: { 828: chunk_free(&sig_scheme); 829: return FALSE; 830: } 831: this->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm", 832: this->tbsCertList, 833: sig_scheme, 834: asn1_bitstring("c", this->signature)); 835: return TRUE; 836: } 837: 838: /** 839: * See header. 840: */ 841: x509_crl_t *x509_crl_gen(certificate_type_t type, va_list args) 842: { 843: hash_algorithm_t digest_alg = HASH_SHA1; 844: private_x509_crl_t *crl; 845: certificate_t *cert = NULL; 846: private_key_t *key = NULL; 847: 848: crl = create_empty(); 849: crl->generated = TRUE; 850: while (TRUE) 851: { 852: builder_part_t part = va_arg(args, builder_part_t); 853: 854: switch (part) 855: { 856: case BUILD_SIGNING_KEY: 857: key = va_arg(args, private_key_t*); 858: continue; 859: case BUILD_SIGNING_CERT: 860: cert = va_arg(args, certificate_t*); 861: continue; 862: case BUILD_NOT_BEFORE_TIME: 863: crl->thisUpdate = va_arg(args, time_t); 864: continue; 865: case BUILD_NOT_AFTER_TIME: 866: crl->nextUpdate = va_arg(args, time_t); 867: continue; 868: case BUILD_SERIAL: 869: crl->crlNumber = va_arg(args, chunk_t); 870: crl->crlNumber = chunk_clone(crl->crlNumber); 871: continue; 872: case BUILD_SIGNATURE_SCHEME: 873: crl->scheme = va_arg(args, signature_params_t*); 874: crl->scheme = signature_params_clone(crl->scheme); 875: continue; 876: case BUILD_DIGEST_ALG: 877: digest_alg = va_arg(args, int); 878: continue; 879: case BUILD_REVOKED_ENUMERATOR: 880: read_revoked(crl, va_arg(args, enumerator_t*)); 881: continue; 882: case BUILD_BASE_CRL: 883: crl->baseCrlNumber = va_arg(args, chunk_t); 884: crl->baseCrlNumber = chunk_clone(crl->baseCrlNumber); 885: break; 886: case BUILD_CRL_DISTRIBUTION_POINTS: 887: { 888: enumerator_t *enumerator; 889: linked_list_t *list; 890: x509_cdp_t *in, *cdp; 891: 892: list = va_arg(args, linked_list_t*); 893: enumerator = list->create_enumerator(list); 894: while (enumerator->enumerate(enumerator, &in)) 895: { 896: INIT(cdp, 897: .uri = strdup(in->uri), 898: .issuer = in->issuer ? in->issuer->clone(in->issuer) : NULL, 899: ); 900: crl->crl_uris->insert_last(crl->crl_uris, cdp); 901: } 902: enumerator->destroy(enumerator); 903: continue; 904: } 905: case BUILD_CRITICAL_EXTENSION: 906: crl->critical_extension_oid = chunk_clone(va_arg(args, chunk_t)); 907: continue; 908: case BUILD_END: 909: break; 910: default: 911: destroy(crl); 912: return NULL; 913: } 914: break; 915: } 916: 917: if (key && cert && cert->get_type(cert) == CERT_X509 && 918: generate(crl, cert, key, digest_alg)) 919: { 920: return &crl->public; 921: } 922: destroy(crl); 923: return NULL; 924: }