Annotation of embedaddon/strongswan/src/libstrongswan/plugins/x509/x509_cert.c, revision 1.1.1.1
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>