Added support for parsing NameConstraints in x509 plugin
[strongswan.git] / src / libstrongswan / plugins / x509 / x509_cert.c
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-2006 Andreas Steffen
6 * Copyright (C) 2006-2009 Martin Willi
7 * Copyright (C) 2008 Tobias Brunner
8 * 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 "x509_cert.h"
24
25 #include <sys/stat.h>
26 #include <time.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <stdio.h>
30
31 #include <library.h>
32 #include <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 <utils/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 crl_uri_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 exluced name constraints
141 */
142 linked_list_t *excluded_names;
143
144 /**
145 * certificate's embedded public key
146 */
147 public_key_t *public_key;
148
149 /**
150 * Subject Key Identifier
151 */
152 chunk_t subjectKeyIdentifier;
153
154 /**
155 * Authority Key Identifier
156 */
157 chunk_t authKeyIdentifier;
158
159 /**
160 * Authority Key Serial Number
161 */
162 chunk_t authKeySerialNumber;
163
164 /**
165 * Path Length Constraint
166 */
167 int pathLenConstraint;
168
169 /**
170 * x509 constraints and other flags
171 */
172 x509_flag_t flags;
173
174 /**
175 * Signature algorithm
176 */
177 int algorithm;
178
179 /**
180 * Signature
181 */
182 chunk_t signature;
183
184 /**
185 * Certificate parsed from blob/file?
186 */
187 bool parsed;
188
189 /**
190 * reference count
191 */
192 refcount_t ref;
193 };
194
195 static const chunk_t ASN1_subjectAltName_oid = chunk_from_chars(
196 0x06, 0x03, 0x55, 0x1D, 0x11
197 );
198
199 /**
200 * CRL URIs with associated issuer
201 */
202 typedef struct {
203 identification_t *issuer;
204 linked_list_t *uris;
205 } crl_uri_t;
206
207 /**
208 * Create a new issuer entry
209 */
210 static crl_uri_t *crl_uri_create(identification_t *issuer)
211 {
212 crl_uri_t *this;
213
214 INIT(this,
215 .issuer = issuer ? issuer->clone(issuer) : NULL,
216 .uris = linked_list_create(),
217 );
218 return this;
219 }
220
221 /**
222 * Destroy a CRL URI struct
223 */
224 static void crl_uri_destroy(crl_uri_t *this)
225 {
226 this->uris->destroy_function(this->uris, free);
227 DESTROY_IF(this->issuer);
228 free(this);
229 }
230
231 /**
232 * ASN.1 definition of a basicConstraints extension
233 */
234 static const asn1Object_t basicConstraintsObjects[] = {
235 { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
236 { 1, "CA", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 1 */
237 { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */
238 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
239 { 0, "exit", ASN1_EOC, ASN1_EXIT }
240 };
241 #define BASIC_CONSTRAINTS_CA 1
242 #define BASIC_CONSTRAINTS_PATH_LEN 2
243
244 /**
245 * Extracts the basicConstraints extension
246 */
247 static void parse_basicConstraints(chunk_t blob, int level0,
248 private_x509_cert_t *this)
249 {
250 asn1_parser_t *parser;
251 chunk_t object;
252 int objectID;
253 bool isCA = FALSE;
254
255 parser = asn1_parser_create(basicConstraintsObjects, blob);
256 parser->set_top_level(parser, level0);
257
258 while (parser->iterate(parser, &objectID, &object))
259 {
260 switch (objectID)
261 {
262 case BASIC_CONSTRAINTS_CA:
263 isCA = object.len && *object.ptr;
264 DBG2(DBG_LIB, " %s", isCA ? "TRUE" : "FALSE");
265 if (isCA)
266 {
267 this->flags |= X509_CA;
268 }
269 break;
270 case BASIC_CONSTRAINTS_PATH_LEN:
271 if (isCA)
272 {
273 if (object.len == 0)
274 {
275 this->pathLenConstraint = 0;
276 }
277 else if (object.len == 1)
278 {
279 this->pathLenConstraint = *object.ptr;
280 }
281 /* we ignore path length constraints > 127 */
282 }
283 break;
284 default:
285 break;
286 }
287 }
288 parser->destroy(parser);
289 }
290
291 /**
292 * ASN.1 definition of otherName
293 */
294 static const asn1Object_t otherNameObjects[] = {
295 {0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */
296 {0, "value", ASN1_CONTEXT_C_0, ASN1_BODY }, /* 1 */
297 {0, "exit", ASN1_EOC, ASN1_EXIT }
298 };
299 #define ON_OBJ_ID_TYPE 0
300 #define ON_OBJ_VALUE 1
301
302 /**
303 * Extracts an otherName
304 */
305 static bool parse_otherName(chunk_t *blob, int level0, id_type_t *type)
306 {
307 asn1_parser_t *parser;
308 chunk_t object;
309 int objectID;
310 int oid = OID_UNKNOWN;
311 bool success = FALSE;
312
313 parser = asn1_parser_create(otherNameObjects, *blob);
314 parser->set_top_level(parser, level0);
315
316 while (parser->iterate(parser, &objectID, &object))
317 {
318 switch (objectID)
319 {
320 case ON_OBJ_ID_TYPE:
321 oid = asn1_known_oid(object);
322 break;
323 case ON_OBJ_VALUE:
324 switch (oid)
325 {
326 case OID_XMPP_ADDR:
327 if (!asn1_parse_simple_object(&object, ASN1_UTF8STRING,
328 parser->get_level(parser)+1, "xmppAddr"))
329 {
330 goto end;
331 }
332 break;
333 case OID_USER_PRINCIPAL_NAME:
334 if (asn1_parse_simple_object(&object, ASN1_UTF8STRING,
335 parser->get_level(parser)+1, "msUPN"))
336 { /* we handle UPNs as RFC822 addr */
337 *blob = object;
338 *type = ID_RFC822_ADDR;
339 }
340 else
341 {
342 goto end;
343 }
344 break;
345 }
346 break;
347 default:
348 break;
349 }
350 }
351 success = parser->success(parser);
352
353 end:
354 parser->destroy(parser);
355 return success;
356 }
357
358 /**
359 * ASN.1 definition of generalName
360 */
361 static const asn1Object_t generalNameObjects[] = {
362 { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */
363 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
364 { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */
365 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
366 { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */
367 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
368 { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */
369 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
370 { 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT|ASN1_BODY }, /* 8 */
371 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
372 { 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT|ASN1_BODY }, /* 10 */
373 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
374 { 0, "URI", ASN1_CONTEXT_S_6, ASN1_OPT|ASN1_BODY }, /* 12 */
375 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */
376 { 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT|ASN1_BODY }, /* 14 */
377 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */
378 { 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT|ASN1_BODY }, /* 16 */
379 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 17 */
380 { 0, "exit", ASN1_EOC, ASN1_EXIT }
381 };
382 #define GN_OBJ_OTHER_NAME 0
383 #define GN_OBJ_RFC822_NAME 2
384 #define GN_OBJ_DNS_NAME 4
385 #define GN_OBJ_X400_ADDRESS 6
386 #define GN_OBJ_DIRECTORY_NAME 8
387 #define GN_OBJ_EDI_PARTY_NAME 10
388 #define GN_OBJ_URI 12
389 #define GN_OBJ_IP_ADDRESS 14
390 #define GN_OBJ_REGISTERED_ID 16
391
392 /**
393 * Extracts a generalName
394 */
395 static identification_t *parse_generalName(chunk_t blob, int level0)
396 {
397 asn1_parser_t *parser;
398 chunk_t object;
399 int objectID ;
400
401 identification_t *gn = NULL;
402
403 parser = asn1_parser_create(generalNameObjects, blob);
404 parser->set_top_level(parser, level0);
405
406 while (parser->iterate(parser, &objectID, &object))
407 {
408 id_type_t id_type = ID_ANY;
409
410 switch (objectID)
411 {
412 case GN_OBJ_RFC822_NAME:
413 id_type = ID_RFC822_ADDR;
414 break;
415 case GN_OBJ_DNS_NAME:
416 id_type = ID_FQDN;
417 break;
418 case GN_OBJ_URI:
419 id_type = ID_DER_ASN1_GN_URI;
420 break;
421 case GN_OBJ_DIRECTORY_NAME:
422 id_type = ID_DER_ASN1_DN;
423 break;
424 case GN_OBJ_IP_ADDRESS:
425 switch (object.len)
426 {
427 case 4:
428 id_type = ID_IPV4_ADDR;
429 break;
430 case 16:
431 id_type = ID_IPV6_ADDR;
432 break;
433 default:
434 break;
435 }
436 break;
437 case GN_OBJ_OTHER_NAME:
438 if (!parse_otherName(&object, parser->get_level(parser)+1,
439 &id_type))
440 {
441 goto end;
442 }
443 break;
444 case GN_OBJ_X400_ADDRESS:
445 case GN_OBJ_EDI_PARTY_NAME:
446 case GN_OBJ_REGISTERED_ID:
447 default:
448 break;
449 }
450 if (id_type != ID_ANY)
451 {
452 gn = identification_create_from_encoding(id_type, object);
453 DBG2(DBG_LIB, " '%Y'", gn);
454 goto end;
455 }
456 }
457
458 end:
459 parser->destroy(parser);
460 return gn;
461 }
462
463 /**
464 * ASN.1 definition of generalNames
465 */
466 static const asn1Object_t generalNamesObjects[] = {
467 { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
468 { 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */
469 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
470 { 0, "exit", ASN1_EOC, ASN1_EXIT }
471 };
472 #define GENERAL_NAMES_GN 1
473
474 /**
475 * Extracts one or several GNs and puts them into a chained list
476 */
477 void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list)
478 {
479 asn1_parser_t *parser;
480 chunk_t object;
481 int objectID;
482
483 parser = asn1_parser_create(generalNamesObjects, blob);
484 parser->set_top_level(parser, level0);
485 parser->set_flags(parser, implicit, FALSE);
486
487 while (parser->iterate(parser, &objectID, &object))
488 {
489 if (objectID == GENERAL_NAMES_GN)
490 {
491 identification_t *gn = parse_generalName(object,
492 parser->get_level(parser)+1);
493
494 if (gn)
495 {
496 list->insert_last(list, (void *)gn);
497 }
498 }
499 }
500 parser->destroy(parser);
501 }
502
503 /**
504 * ASN.1 definition of a authorityKeyIdentifier extension
505 */
506 static const asn1Object_t authKeyIdentifierObjects[] = {
507 { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
508 { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_BODY }, /* 1 */
509 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
510 { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */
511 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
512 { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */
513 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */
514 { 0, "exit", ASN1_EOC, ASN1_EXIT }
515 };
516 #define AUTH_KEY_ID_KEY_ID 1
517 #define AUTH_KEY_ID_CERT_ISSUER 3
518 #define AUTH_KEY_ID_CERT_SERIAL 5
519
520 /**
521 * Extracts an authoritykeyIdentifier
522 */
523 chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob, int level0,
524 chunk_t *authKeySerialNumber)
525 {
526 asn1_parser_t *parser;
527 chunk_t object;
528 int objectID;
529 chunk_t authKeyIdentifier = chunk_empty;
530
531 *authKeySerialNumber = chunk_empty;
532
533 parser = asn1_parser_create(authKeyIdentifierObjects, blob);
534 parser->set_top_level(parser, level0);
535
536 while (parser->iterate(parser, &objectID, &object))
537 {
538 switch (objectID)
539 {
540 case AUTH_KEY_ID_KEY_ID:
541 authKeyIdentifier = chunk_clone(object);
542 break;
543 case AUTH_KEY_ID_CERT_ISSUER:
544 /* TODO: x509_parse_generalNames(object, level+1, TRUE); */
545 break;
546 case AUTH_KEY_ID_CERT_SERIAL:
547 *authKeySerialNumber = object;
548 break;
549 default:
550 break;
551 }
552 }
553 parser->destroy(parser);
554 return authKeyIdentifier;
555 }
556
557 /**
558 * ASN.1 definition of a authorityInfoAccess extension
559 */
560 static const asn1Object_t authInfoAccessObjects[] = {
561 { 0, "authorityInfoAccess", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
562 { 1, "accessDescription", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
563 { 2, "accessMethod", ASN1_OID, ASN1_BODY }, /* 2 */
564 { 2, "accessLocation", ASN1_EOC, ASN1_RAW }, /* 3 */
565 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 4 */
566 { 0, "exit", ASN1_EOC, ASN1_EXIT }
567 };
568 #define AUTH_INFO_ACCESS_METHOD 2
569 #define AUTH_INFO_ACCESS_LOCATION 3
570
571 /**
572 * Extracts an authorityInfoAcess location
573 */
574 static void parse_authorityInfoAccess(chunk_t blob, int level0,
575 private_x509_cert_t *this)
576 {
577 asn1_parser_t *parser;
578 chunk_t object;
579 int objectID;
580 int accessMethod = OID_UNKNOWN;
581
582 parser = asn1_parser_create(authInfoAccessObjects, blob);
583 parser->set_top_level(parser, level0);
584
585 while (parser->iterate(parser, &objectID, &object))
586 {
587 switch (objectID)
588 {
589 case AUTH_INFO_ACCESS_METHOD:
590 accessMethod = asn1_known_oid(object);
591 break;
592 case AUTH_INFO_ACCESS_LOCATION:
593 {
594 switch (accessMethod)
595 {
596 case OID_OCSP:
597 case OID_CA_ISSUERS:
598 {
599 identification_t *id;
600 char *uri;
601
602 id = parse_generalName(object,
603 parser->get_level(parser)+1);
604 if (id == NULL)
605 {
606 /* parsing went wrong - abort */
607 goto end;
608 }
609 DBG2(DBG_LIB, " '%Y'", id);
610 if (accessMethod == OID_OCSP &&
611 asprintf(&uri, "%Y", id) > 0)
612 {
613 this->ocsp_uris->insert_last(this->ocsp_uris, uri);
614 }
615 id->destroy(id);
616 }
617 break;
618 default:
619 /* unkown accessMethod, ignoring */
620 break;
621 }
622 break;
623 }
624 default:
625 break;
626 }
627 }
628
629 end:
630 parser->destroy(parser);
631 }
632
633 /**
634 * Extract KeyUsage flags
635 */
636 static void parse_keyUsage(chunk_t blob, private_x509_cert_t *this)
637 {
638 enum {
639 KU_DIGITAL_SIGNATURE = 0,
640 KU_NON_REPUDIATION = 1,
641 KU_KEY_ENCIPHERMENT = 2,
642 KU_DATA_ENCIPHERMENT = 3,
643 KU_KEY_AGREEMENT = 4,
644 KU_KEY_CERT_SIGN = 5,
645 KU_CRL_SIGN = 6,
646 KU_ENCIPHER_ONLY = 7,
647 KU_DECIPHER_ONLY = 8,
648 };
649
650 if (asn1_unwrap(&blob, &blob) == ASN1_BIT_STRING && blob.len)
651 {
652 int bit, byte, unused = blob.ptr[0];
653
654 blob = chunk_skip(blob, 1);
655 for (byte = 0; byte < blob.len; byte++)
656 {
657 for (bit = 0; bit < 8; bit++)
658 {
659 if (byte == blob.len - 1 && bit > (7 - unused))
660 {
661 break;
662 }
663 if (blob.ptr[byte] & 1 << (7 - bit))
664 {
665 switch (byte * 8 + bit)
666 {
667 case KU_CRL_SIGN:
668 this->flags |= X509_CRL_SIGN;
669 break;
670 case KU_KEY_CERT_SIGN:
671 /* we use the caBasicConstraint, MUST be set */
672 case KU_DIGITAL_SIGNATURE:
673 case KU_NON_REPUDIATION:
674 case KU_KEY_ENCIPHERMENT:
675 case KU_DATA_ENCIPHERMENT:
676 case KU_KEY_AGREEMENT:
677 case KU_ENCIPHER_ONLY:
678 case KU_DECIPHER_ONLY:
679 break;
680 }
681 }
682 }
683 }
684 }
685 }
686
687 /**
688 * ASN.1 definition of a extendedKeyUsage extension
689 */
690 static const asn1Object_t extendedKeyUsageObjects[] = {
691 { 0, "extendedKeyUsage", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
692 { 1, "keyPurposeID", ASN1_OID, ASN1_BODY }, /* 1 */
693 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
694 { 0, "exit", ASN1_EOC, ASN1_EXIT }
695 };
696 #define EXT_KEY_USAGE_PURPOSE_ID 1
697
698 /**
699 * Extracts extendedKeyUsage OIDs
700 */
701 static void parse_extendedKeyUsage(chunk_t blob, int level0,
702 private_x509_cert_t *this)
703 {
704 asn1_parser_t *parser;
705 chunk_t object;
706 int objectID;
707
708 parser = asn1_parser_create(extendedKeyUsageObjects, blob);
709 parser->set_top_level(parser, level0);
710
711 while (parser->iterate(parser, &objectID, &object))
712 {
713 if (objectID == EXT_KEY_USAGE_PURPOSE_ID)
714 {
715 switch (asn1_known_oid(object))
716 {
717 case OID_SERVER_AUTH:
718 this->flags |= X509_SERVER_AUTH;
719 break;
720 case OID_CLIENT_AUTH:
721 this->flags |= X509_CLIENT_AUTH;
722 break;
723 case OID_OCSP_SIGNING:
724 this->flags |= X509_OCSP_SIGNER;
725 break;
726 default:
727 break;
728 }
729 }
730 }
731 parser->destroy(parser);
732 }
733
734 /**
735 * ASN.1 definition of crlDistributionPoints
736 */
737 static const asn1Object_t crlDistributionPointsObjects[] = {
738 { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
739 { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
740 { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 2 */
741 { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */
742 { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
743 { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */
744 { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
745 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
746 { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */
747 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
748 { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_OBJ }, /* 10 */
749 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
750 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
751 { 0, "exit", ASN1_EOC, ASN1_EXIT }
752 };
753 #define CRL_DIST_POINTS 1
754 #define CRL_DIST_POINTS_FULLNAME 3
755 #define CRL_DIST_POINTS_ISSUER 10
756
757 /**
758 * Extracts one or several crlDistributionPoints into a list
759 */
760 static void parse_crlDistributionPoints(chunk_t blob, int level0,
761 private_x509_cert_t *this)
762 {
763 asn1_parser_t *parser;
764 chunk_t object;
765 int objectID;
766 crl_uri_t *entry = NULL;
767 identification_t *id;
768 char *uri;
769 linked_list_t *list = linked_list_create();
770
771 parser = asn1_parser_create(crlDistributionPointsObjects, blob);
772 parser->set_top_level(parser, level0);
773
774 while (parser->iterate(parser, &objectID, &object))
775 {
776 switch (objectID)
777 {
778 case CRL_DIST_POINTS:
779 entry = crl_uri_create(NULL);
780 this->crl_uris->insert_last(this->crl_uris, entry);
781 break;
782 case CRL_DIST_POINTS_FULLNAME:
783 if (entry)
784 {
785 x509_parse_generalNames(object, parser->get_level(parser)+1,
786 TRUE, list);
787 while (list->remove_last(list, (void**)&id) == SUCCESS)
788 {
789 if (asprintf(&uri, "%Y", id) > 0)
790 {
791 entry->uris->insert_last(entry->uris, uri);
792 }
793 id->destroy(id);
794 }
795 }
796 break;
797 case CRL_DIST_POINTS_ISSUER:
798 if (entry)
799 {
800 x509_parse_generalNames(object, parser->get_level(parser)+1,
801 TRUE, list);
802 while (list->remove_last(list, (void**)&id) == SUCCESS)
803 {
804 if (!entry->issuer)
805 {
806 entry->issuer = id;
807 }
808 else
809 {
810 id->destroy(id);
811 }
812 }
813 }
814 break;
815 }
816 }
817 parser->destroy(parser);
818 list->destroy(list);
819 }
820
821 /**
822 * ASN.1 definition of nameConstraints
823 */
824 static const asn1Object_t nameConstraintsObjects[] = {
825 { 0, "nameConstraints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
826 { 1, "permittedSubtrees", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 1 */
827 { 2, "generalSubtree", ASN1_SEQUENCE, ASN1_BODY }, /* 2 */
828 { 1, "end loop", ASN1_EOC, ASN1_END }, /* 3 */
829 { 1, "excludedSubtrees", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_LOOP }, /* 4 */
830 { 2, "generalSubtree", ASN1_SEQUENCE, ASN1_BODY }, /* 5 */
831 { 1, "end loop", ASN1_EOC, ASN1_END }, /* 6 */
832 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 7 */
833 { 0, "exit", ASN1_EOC, ASN1_EXIT }
834 };
835 #define NAME_CONSTRAINT_PERMITTED 2
836 #define NAME_CONSTRAINT_EXCLUDED 5
837
838 /**
839 * Parse permitted/excluded nameConstraints
840 */
841 static void parse_nameConstraints(chunk_t blob, int level0,
842 private_x509_cert_t *this)
843 {
844 asn1_parser_t *parser;
845 identification_t *id;
846 chunk_t object;
847 int objectID;
848
849 parser = asn1_parser_create(nameConstraintsObjects, blob);
850 parser->set_top_level(parser, level0);
851
852 while (parser->iterate(parser, &objectID, &object))
853 {
854 switch (objectID)
855 {
856 case NAME_CONSTRAINT_PERMITTED:
857 id = parse_generalName(object, parser->get_level(parser) + 1);
858 if (id)
859 {
860 this->permitted_names->insert_last(this->permitted_names, id);
861 }
862 break;
863 case NAME_CONSTRAINT_EXCLUDED:
864 id = parse_generalName(object, parser->get_level(parser) + 1);
865 if (id)
866 {
867 this->excluded_names->insert_last(this->excluded_names, id);
868 }
869 break;
870 default:
871 break;
872 }
873 }
874 parser->destroy(parser);
875 }
876
877 /**
878 * ASN.1 definition of ipAddrBlocks according to RFC 3779
879 */
880 static const asn1Object_t ipAddrBlocksObjects[] = {
881 { 0, "ipAddrBlocks", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
882 { 1, "ipAddressFamily", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
883 { 2, "addressFamily", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
884 { 2, "inherit", ASN1_NULL, ASN1_OPT|ASN1_NONE }, /* 3 */
885 { 2, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
886 { 2, "addressesOrRanges", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 5 */
887 { 3, "addressPrefix", ASN1_BIT_STRING, ASN1_OPT|ASN1_BODY }, /* 6 */
888 { 3, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
889 { 3, "addressRange", ASN1_SEQUENCE, ASN1_OPT|ASN1_NONE }, /* 8 */
890 { 4, "min", ASN1_BIT_STRING, ASN1_BODY }, /* 9 */
891 { 4, "max", ASN1_BIT_STRING, ASN1_BODY }, /* 10 */
892 { 3, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
893 { 2, "end choice/loop", ASN1_EOC, ASN1_END }, /* 12 */
894 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 13 */
895 { 0, "exit", ASN1_EOC, ASN1_EXIT }
896 };
897 #define IP_ADDR_BLOCKS_FAMILY 2
898 #define IP_ADDR_BLOCKS_INHERIT 3
899 #define IP_ADDR_BLOCKS_PREFIX 6
900 #define IP_ADDR_BLOCKS_MIN 9
901 #define IP_ADDR_BLOCKS_MAX 10
902
903 static bool check_address_object(ts_type_t ts_type, chunk_t object)
904 {
905 switch (ts_type)
906 {
907 case TS_IPV4_ADDR_RANGE:
908 if (object.len > 5)
909 {
910 DBG1(DBG_LIB, "IPv4 address object is larger than 5 octets");
911 return FALSE;
912 }
913 break;
914 case TS_IPV6_ADDR_RANGE:
915 if (object.len > 17)
916 {
917 DBG1(DBG_LIB, "IPv6 address object is larger than 17 octets");
918 return FALSE;
919 }
920 break;
921 default:
922 DBG1(DBG_LIB, "unknown address family");
923 return FALSE;
924 }
925 if (object.len == 0)
926 {
927 DBG1(DBG_LIB, "An ASN.1 bit string must contain at least the "
928 "initial octet");
929 return FALSE;
930 }
931 if (object.len == 1 && object.ptr[0] != 0)
932 {
933 DBG1(DBG_LIB, "An empty ASN.1 bit string must contain a zero "
934 "initial octet");
935 return FALSE;
936 }
937 if (object.ptr[0] > 7)
938 {
939 DBG1(DBG_LIB, "number of unused bits is too large");
940 return FALSE;
941 }
942 return TRUE;
943 }
944
945 static void parse_ipAddrBlocks(chunk_t blob, int level0,
946 private_x509_cert_t *this)
947 {
948 asn1_parser_t *parser;
949 chunk_t object, min_object;
950 ts_type_t ts_type = 0;
951 traffic_selector_t *ts;
952 int objectID;
953
954 parser = asn1_parser_create(ipAddrBlocksObjects, blob);
955 parser->set_top_level(parser, level0);
956
957 while (parser->iterate(parser, &objectID, &object))
958 {
959 switch (objectID)
960 {
961 case IP_ADDR_BLOCKS_FAMILY:
962 ts_type = 0;
963 if (object.len == 2 && object.ptr[0] == 0)
964 {
965 if (object.ptr[1] == 1)
966 {
967 ts_type = TS_IPV4_ADDR_RANGE;
968 }
969 else if (object.ptr[1] == 2)
970 {
971 ts_type = TS_IPV6_ADDR_RANGE;
972 }
973 else
974 {
975 break;
976 }
977 DBG2(DBG_LIB, " %N", ts_type_name, ts_type);
978 }
979 break;
980 case IP_ADDR_BLOCKS_INHERIT:
981 DBG1(DBG_LIB, "inherit choice is not supported");
982 break;
983 case IP_ADDR_BLOCKS_PREFIX:
984 if (!check_address_object(ts_type, object))
985 {
986 goto end;
987 }
988 ts = traffic_selector_create_from_rfc3779_format(ts_type,
989 object, object);
990 DBG2(DBG_LIB, " %R", ts);
991 this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
992 break;
993 case IP_ADDR_BLOCKS_MIN:
994 if (!check_address_object(ts_type, object))
995 {
996 goto end;
997 }
998 min_object = object;
999 break;
1000 case IP_ADDR_BLOCKS_MAX:
1001 if (!check_address_object(ts_type, object))
1002 {
1003 goto end;
1004 }
1005 ts = traffic_selector_create_from_rfc3779_format(ts_type,
1006 min_object, object);
1007 DBG2(DBG_LIB, " %R", ts);
1008 this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
1009 break;
1010 default:
1011 break;
1012 }
1013 }
1014 this->flags |= X509_IP_ADDR_BLOCKS;
1015
1016 end:
1017 parser->destroy(parser);
1018 }
1019
1020 /**
1021 * ASN.1 definition of an X.509v3 x509_cert
1022 */
1023 static const asn1Object_t certObjects[] = {
1024 { 0, "x509", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
1025 { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
1026 { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
1027 { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
1028 { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
1029 { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */
1030 { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
1031 { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */
1032 { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */
1033 { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */
1034 { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
1035 { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_RAW }, /* 11 */
1036 { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
1037 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
1038 { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 14 */
1039 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
1040 { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 16 */
1041 { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 17 */
1042 { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 18 */
1043 { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 19 */
1044 { 5, "critical", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 20 */
1045 { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 21 */
1046 { 3, "end loop", ASN1_EOC, ASN1_END }, /* 22 */
1047 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 23 */
1048 { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 24 */
1049 { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 25 */
1050 { 0, "exit", ASN1_EOC, ASN1_EXIT }
1051 };
1052 #define X509_OBJ_TBS_CERTIFICATE 1
1053 #define X509_OBJ_VERSION 3
1054 #define X509_OBJ_SERIAL_NUMBER 4
1055 #define X509_OBJ_SIG_ALG 5
1056 #define X509_OBJ_ISSUER 6
1057 #define X509_OBJ_NOT_BEFORE 8
1058 #define X509_OBJ_NOT_AFTER 9
1059 #define X509_OBJ_SUBJECT 10
1060 #define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO 11
1061 #define X509_OBJ_OPTIONAL_EXTENSIONS 16
1062 #define X509_OBJ_EXTN_ID 19
1063 #define X509_OBJ_CRITICAL 20
1064 #define X509_OBJ_EXTN_VALUE 21
1065 #define X509_OBJ_ALGORITHM 24
1066 #define X509_OBJ_SIGNATURE 25
1067
1068 /**
1069 * Parses an X.509v3 certificate
1070 */
1071 static bool parse_certificate(private_x509_cert_t *this)
1072 {
1073 asn1_parser_t *parser;
1074 chunk_t object;
1075 int objectID;
1076 int extn_oid = OID_UNKNOWN;
1077 int sig_alg = OID_UNKNOWN;
1078 bool success = FALSE;
1079 bool critical = FALSE;
1080
1081 parser = asn1_parser_create(certObjects, this->encoding);
1082
1083 while (parser->iterate(parser, &objectID, &object))
1084 {
1085 u_int level = parser->get_level(parser)+1;
1086
1087 switch (objectID)
1088 {
1089 case X509_OBJ_TBS_CERTIFICATE:
1090 this->tbsCertificate = object;
1091 break;
1092 case X509_OBJ_VERSION:
1093 this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
1094 if (this->version < 1 || this->version > 3)
1095 {
1096 DBG1(DBG_LIB, "X.509v%d not supported", this->version);
1097 goto end;
1098 }
1099 else
1100 {
1101 DBG2(DBG_LIB, " X.509v%d", this->version);
1102 }
1103 break;
1104 case X509_OBJ_SERIAL_NUMBER:
1105 this->serialNumber = object;
1106 break;
1107 case X509_OBJ_SIG_ALG:
1108 sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
1109 break;
1110 case X509_OBJ_ISSUER:
1111 this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
1112 DBG2(DBG_LIB, " '%Y'", this->issuer);
1113 break;
1114 case X509_OBJ_NOT_BEFORE:
1115 this->notBefore = asn1_parse_time(object, level);
1116 break;
1117 case X509_OBJ_NOT_AFTER:
1118 this->notAfter = asn1_parse_time(object, level);
1119 break;
1120 case X509_OBJ_SUBJECT:
1121 this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
1122 DBG2(DBG_LIB, " '%Y'", this->subject);
1123 break;
1124 case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO:
1125 DBG2(DBG_LIB, "-- > --");
1126 this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
1127 KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
1128 DBG2(DBG_LIB, "-- < --");
1129 if (this->public_key == NULL)
1130 {
1131 goto end;
1132 }
1133 break;
1134 case X509_OBJ_OPTIONAL_EXTENSIONS:
1135 if (this->version != 3)
1136 {
1137 DBG1(DBG_LIB, "Only X.509v3 certificates have extensions");
1138 goto end;
1139 }
1140 break;
1141 case X509_OBJ_EXTN_ID:
1142 extn_oid = asn1_known_oid(object);
1143 break;
1144 case X509_OBJ_CRITICAL:
1145 critical = object.len && *object.ptr;
1146 DBG2(DBG_LIB, " %s", critical ? "TRUE" : "FALSE");
1147 break;
1148 case X509_OBJ_EXTN_VALUE:
1149 {
1150 switch (extn_oid)
1151 {
1152 case OID_SUBJECT_KEY_ID:
1153 if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
1154 level, "keyIdentifier"))
1155 {
1156 goto end;
1157 }
1158 this->subjectKeyIdentifier = object;
1159 break;
1160 case OID_SUBJECT_ALT_NAME:
1161 x509_parse_generalNames(object, level, FALSE,
1162 this->subjectAltNames);
1163 break;
1164 case OID_BASIC_CONSTRAINTS:
1165 parse_basicConstraints(object, level, this);
1166 break;
1167 case OID_CRL_DISTRIBUTION_POINTS:
1168 parse_crlDistributionPoints(object, level, this);
1169 break;
1170 case OID_AUTHORITY_KEY_ID:
1171 this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
1172 level, &this->authKeySerialNumber);
1173 break;
1174 case OID_AUTHORITY_INFO_ACCESS:
1175 parse_authorityInfoAccess(object, level, this);
1176 break;
1177 case OID_KEY_USAGE:
1178 parse_keyUsage(object, this);
1179 break;
1180 case OID_EXTENDED_KEY_USAGE:
1181 parse_extendedKeyUsage(object, level, this);
1182 break;
1183 case OID_IP_ADDR_BLOCKS:
1184 parse_ipAddrBlocks(object, level, this);
1185 break;
1186 case OID_NAME_CONSTRAINTS:
1187 parse_nameConstraints(object, level, this);
1188 break;
1189 case OID_NS_REVOCATION_URL:
1190 case OID_NS_CA_REVOCATION_URL:
1191 case OID_NS_CA_POLICY_URL:
1192 case OID_NS_COMMENT:
1193 if (!asn1_parse_simple_object(&object, ASN1_IA5STRING,
1194 level, oid_names[extn_oid].name))
1195 {
1196 goto end;
1197 }
1198 break;
1199 default:
1200 if (critical && lib->settings->get_bool(lib->settings,
1201 "libstrongswan.plugins.x509.enforce_critical", FALSE))
1202 {
1203 DBG1(DBG_LIB, "critical %s extension not supported",
1204 (extn_oid == OID_UNKNOWN) ? "unknown" :
1205 (char*)oid_names[extn_oid].name);
1206 goto end;
1207 }
1208 break;
1209 }
1210 break;
1211 }
1212 case X509_OBJ_ALGORITHM:
1213 this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
1214 if (this->algorithm != sig_alg)
1215 {
1216 DBG1(DBG_LIB, " signature algorithms do not agree");
1217 goto end;
1218 }
1219 break;
1220 case X509_OBJ_SIGNATURE:
1221 this->signature = object;
1222 break;
1223 default:
1224 break;
1225 }
1226 }
1227 success = parser->success(parser);
1228
1229 end:
1230 parser->destroy(parser);
1231 if (success)
1232 {
1233 hasher_t *hasher;
1234
1235 /* check if the certificate is self-signed */
1236 if (this->public.interface.interface.issued_by(
1237 &this->public.interface.interface,
1238 &this->public.interface.interface))
1239 {
1240 this->flags |= X509_SELF_SIGNED;
1241 }
1242 /* create certificate hash */
1243 hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
1244 if (hasher == NULL)
1245 {
1246 DBG1(DBG_LIB, " unable to create hash of certificate, SHA1 not supported");
1247 return NULL;
1248 }
1249 hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash);
1250 hasher->destroy(hasher);
1251 }
1252 return success;
1253 }
1254
1255 METHOD(certificate_t, get_type, certificate_type_t,
1256 private_x509_cert_t *this)
1257 {
1258 return CERT_X509;
1259 }
1260
1261 METHOD(certificate_t, get_subject, identification_t*,
1262 private_x509_cert_t *this)
1263 {
1264 return this->subject;
1265 }
1266
1267 METHOD(certificate_t, get_issuer, identification_t*,
1268 private_x509_cert_t *this)
1269 {
1270 return this->issuer;
1271 }
1272
1273 METHOD(certificate_t, has_subject, id_match_t,
1274 private_x509_cert_t *this, identification_t *subject)
1275 {
1276 identification_t *current;
1277 enumerator_t *enumerator;
1278 id_match_t match, best;
1279 chunk_t encoding;
1280
1281 if (subject->get_type(subject) == ID_KEY_ID)
1282 {
1283 encoding = subject->get_encoding(subject);
1284
1285 if (this->encoding_hash.len &&
1286 chunk_equals(this->encoding_hash, encoding))
1287 {
1288 return ID_MATCH_PERFECT;
1289 }
1290 if (this->subjectKeyIdentifier.len &&
1291 chunk_equals(this->subjectKeyIdentifier, encoding))
1292 {
1293 return ID_MATCH_PERFECT;
1294 }
1295 if (this->public_key &&
1296 this->public_key->has_fingerprint(this->public_key, encoding))
1297 {
1298 return ID_MATCH_PERFECT;
1299 }
1300 }
1301 best = this->subject->matches(this->subject, subject);
1302 enumerator = this->subjectAltNames->create_enumerator(this->subjectAltNames);
1303 while (enumerator->enumerate(enumerator, &current))
1304 {
1305 match = current->matches(current, subject);
1306 if (match > best)
1307 {
1308 best = match;
1309 }
1310 }
1311 enumerator->destroy(enumerator);
1312 return best;
1313 }
1314
1315 METHOD(certificate_t, has_issuer, id_match_t,
1316 private_x509_cert_t *this, identification_t *issuer)
1317 {
1318 /* issuerAltNames currently not supported */
1319 return this->issuer->matches(this->issuer, issuer);
1320 }
1321
1322 METHOD(certificate_t, issued_by, bool,
1323 private_x509_cert_t *this, certificate_t *issuer)
1324 {
1325 public_key_t *key;
1326 signature_scheme_t scheme;
1327 bool valid;
1328 x509_t *x509 = (x509_t*)issuer;
1329
1330 if (&this->public.interface.interface == issuer)
1331 {
1332 if (this->flags & X509_SELF_SIGNED)
1333 {
1334 return TRUE;
1335 }
1336 }
1337 else
1338 {
1339 if (issuer->get_type(issuer) != CERT_X509)
1340 {
1341 return FALSE;
1342 }
1343 if (!(x509->get_flags(x509) & X509_CA))
1344 {
1345 return FALSE;
1346 }
1347 }
1348 if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
1349 {
1350 return FALSE;
1351 }
1352
1353 /* determine signature scheme */
1354 scheme = signature_scheme_from_oid(this->algorithm);
1355 if (scheme == SIGN_UNKNOWN)
1356 {
1357 return FALSE;
1358 }
1359 /* get the public key of the issuer */
1360 key = issuer->get_public_key(issuer);
1361 if (!key)
1362 {
1363 return FALSE;
1364 }
1365 valid = key->verify(key, scheme, this->tbsCertificate, this->signature);
1366 key->destroy(key);
1367 return valid;
1368 }
1369
1370 METHOD(certificate_t, get_public_key, public_key_t*,
1371 private_x509_cert_t *this)
1372 {
1373 this->public_key->get_ref(this->public_key);
1374 return this->public_key;
1375 }
1376
1377 METHOD(certificate_t, get_ref, certificate_t*,
1378 private_x509_cert_t *this)
1379 {
1380 ref_get(&this->ref);
1381 return &this->public.interface.interface;
1382 }
1383
1384 METHOD(certificate_t, get_validity, bool,
1385 private_x509_cert_t *this, time_t *when, time_t *not_before,
1386 time_t *not_after)
1387 {
1388 time_t t = when ? *when : time(NULL);
1389
1390 if (not_before)
1391 {
1392 *not_before = this->notBefore;
1393 }
1394 if (not_after)
1395 {
1396 *not_after = this->notAfter;
1397 }
1398 return (t >= this->notBefore && t <= this->notAfter);
1399 }
1400
1401 METHOD(certificate_t, get_encoding, bool,
1402 private_x509_cert_t *this, cred_encoding_type_t type, chunk_t *encoding)
1403 {
1404 if (type == CERT_ASN1_DER)
1405 {
1406 *encoding = chunk_clone(this->encoding);
1407 return TRUE;
1408 }
1409 return lib->encoding->encode(lib->encoding, type, NULL, encoding,
1410 CRED_PART_X509_ASN1_DER, this->encoding, CRED_PART_END);
1411 }
1412
1413 METHOD(certificate_t, equals, bool,
1414 private_x509_cert_t *this, certificate_t *other)
1415 {
1416 chunk_t encoding;
1417 bool equal;
1418
1419 if (this == (private_x509_cert_t*)other)
1420 {
1421 return TRUE;
1422 }
1423 if (other->get_type(other) != CERT_X509)
1424 {
1425 return FALSE;
1426 }
1427 if (other->equals == (void*)equals)
1428 { /* skip allocation if we have the same implementation */
1429 return chunk_equals(this->encoding, ((private_x509_cert_t*)other)->encoding);
1430 }
1431 if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
1432 {
1433 return FALSE;
1434 }
1435 equal = chunk_equals(this->encoding, encoding);
1436 free(encoding.ptr);
1437 return equal;
1438 }
1439
1440 METHOD(x509_t, get_flags, x509_flag_t,
1441 private_x509_cert_t *this)
1442 {
1443 return this->flags;
1444 }
1445
1446 METHOD(x509_t, get_serial, chunk_t,
1447 private_x509_cert_t *this)
1448 {
1449 return this->serialNumber;
1450 }
1451
1452 METHOD(x509_t, get_subjectKeyIdentifier, chunk_t,
1453 private_x509_cert_t *this)
1454 {
1455 if (this->subjectKeyIdentifier.ptr)
1456 {
1457 return this->subjectKeyIdentifier;
1458 }
1459 else
1460 {
1461 chunk_t fingerprint;
1462
1463 if (this->public_key->get_fingerprint(this->public_key,
1464 KEYID_PUBKEY_SHA1, &fingerprint))
1465 {
1466 return fingerprint;
1467 }
1468 else
1469 {
1470 return chunk_empty;
1471 }
1472 }
1473 }
1474
1475 METHOD(x509_t, get_authKeyIdentifier, chunk_t,
1476 private_x509_cert_t *this)
1477 {
1478 return this->authKeyIdentifier;
1479 }
1480
1481 METHOD(x509_t, get_pathLenConstraint, int,
1482 private_x509_cert_t *this)
1483 {
1484 return this->pathLenConstraint;
1485 }
1486
1487 METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*,
1488 private_x509_cert_t *this)
1489 {
1490 return this->subjectAltNames->create_enumerator(this->subjectAltNames);
1491 }
1492
1493 METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*,
1494 private_x509_cert_t *this)
1495 {
1496 return this->ocsp_uris->create_enumerator(this->ocsp_uris);
1497 }
1498
1499 /**
1500 * Convert enumerator value from entry to (uri, issuer)
1501 */
1502 static bool crl_enum_filter(identification_t *issuer_in,
1503 char **uri_in, char **uri_out,
1504 void *none_in, identification_t **issuer_out)
1505 {
1506 *uri_out = *uri_in;
1507 if (issuer_out)
1508 {
1509 *issuer_out = issuer_in;
1510 }
1511 return TRUE;
1512 }
1513
1514 /**
1515 * Create inner enumerator over URIs
1516 */
1517 static enumerator_t *crl_enum_create(crl_uri_t *entry)
1518 {
1519 return enumerator_create_filter(entry->uris->create_enumerator(entry->uris),
1520 (void*)crl_enum_filter, entry->issuer, NULL);
1521 }
1522
1523 METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*,
1524 private_x509_cert_t *this)
1525 {
1526 return enumerator_create_nested(
1527 this->crl_uris->create_enumerator(this->crl_uris),
1528 (void*)crl_enum_create, NULL, NULL);
1529 }
1530
1531 METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*,
1532 private_x509_cert_t *this)
1533 {
1534 return this->ipAddrBlocks->create_enumerator(this->ipAddrBlocks);
1535 }
1536
1537 METHOD(x509_t, create_name_constraint_enumerator, enumerator_t*,
1538 private_x509_cert_t *this, bool perm)
1539 {
1540 if (perm)
1541 {
1542 return this->permitted_names->create_enumerator(this->permitted_names);
1543 }
1544 return this->excluded_names->create_enumerator(this->excluded_names);
1545 }
1546
1547 METHOD(certificate_t, destroy, void,
1548 private_x509_cert_t *this)
1549 {
1550 if (ref_put(&this->ref))
1551 {
1552 this->subjectAltNames->destroy_offset(this->subjectAltNames,
1553 offsetof(identification_t, destroy));
1554 this->crl_uris->destroy_function(this->crl_uris, (void*)crl_uri_destroy);
1555 this->ocsp_uris->destroy_function(this->ocsp_uris, free);
1556 this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks,
1557 offsetof(traffic_selector_t, destroy));
1558 this->permitted_names->destroy_offset(this->permitted_names,
1559 offsetof(identification_t, destroy));
1560 this->excluded_names->destroy_offset(this->excluded_names,
1561 offsetof(identification_t, destroy));
1562 DESTROY_IF(this->issuer);
1563 DESTROY_IF(this->subject);
1564 DESTROY_IF(this->public_key);
1565 chunk_free(&this->authKeyIdentifier);
1566 chunk_free(&this->encoding);
1567 chunk_free(&this->encoding_hash);
1568 if (!this->parsed)
1569 { /* only parsed certificates point these fields to "encoded" */
1570 chunk_free(&this->signature);
1571 chunk_free(&this->serialNumber);
1572 chunk_free(&this->tbsCertificate);
1573 }
1574 free(this);
1575 }
1576 }
1577
1578 /**
1579 * create an empty but initialized X.509 certificate
1580 */
1581 static private_x509_cert_t* create_empty(void)
1582 {
1583 private_x509_cert_t *this;
1584
1585 INIT(this,
1586 .public = {
1587 .interface = {
1588 .interface = {
1589 .get_type = _get_type,
1590 .get_subject = _get_subject,
1591 .get_issuer = _get_issuer,
1592 .has_subject = _has_subject,
1593 .has_issuer = _has_issuer,
1594 .issued_by = _issued_by,
1595 .get_public_key = _get_public_key,
1596 .get_validity = _get_validity,
1597 .get_encoding = _get_encoding,
1598 .equals = _equals,
1599 .get_ref = _get_ref,
1600 .destroy = _destroy,
1601 },
1602 .get_flags = _get_flags,
1603 .get_serial = _get_serial,
1604 .get_subjectKeyIdentifier = _get_subjectKeyIdentifier,
1605 .get_authKeyIdentifier = _get_authKeyIdentifier,
1606 .get_pathLenConstraint = _get_pathLenConstraint,
1607 .create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
1608 .create_crl_uri_enumerator = _create_crl_uri_enumerator,
1609 .create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator,
1610 .create_ipAddrBlock_enumerator = _create_ipAddrBlock_enumerator,
1611 .create_name_constraint_enumerator = _create_name_constraint_enumerator,
1612 },
1613 },
1614 .version = 1,
1615 .subjectAltNames = linked_list_create(),
1616 .crl_uris = linked_list_create(),
1617 .ocsp_uris = linked_list_create(),
1618 .ipAddrBlocks = linked_list_create(),
1619 .permitted_names = linked_list_create(),
1620 .excluded_names = linked_list_create(),
1621 .pathLenConstraint = X509_NO_PATH_LEN_CONSTRAINT,
1622 .ref = 1,
1623 );
1624 return this;
1625 }
1626
1627 /**
1628 * Build a generalName from an id
1629 */
1630 chunk_t build_generalName(identification_t *id)
1631 {
1632 int context;
1633
1634 switch (id->get_type(id))
1635 {
1636 case ID_RFC822_ADDR:
1637 context = ASN1_CONTEXT_S_1;
1638 break;
1639 case ID_FQDN:
1640 context = ASN1_CONTEXT_S_2;
1641 break;
1642 case ID_DER_ASN1_DN:
1643 context = ASN1_CONTEXT_C_4;
1644 break;
1645 case ID_IPV4_ADDR:
1646 case ID_IPV6_ADDR:
1647 context = ASN1_CONTEXT_S_7;
1648 break;
1649 default:
1650 DBG1(DBG_LIB, "encoding %N as generalName not supported",
1651 id_type_names, id->get_type(id));
1652 return chunk_empty;
1653 }
1654 return asn1_wrap(context, "c", id->get_encoding(id));
1655 }
1656
1657 /**
1658 * Encode a linked list of subjectAltNames
1659 */
1660 chunk_t x509_build_subjectAltNames(linked_list_t *list)
1661 {
1662 chunk_t subjectAltNames = chunk_empty, name;
1663 enumerator_t *enumerator;
1664 identification_t *id;
1665
1666 if (list->get_count(list) == 0)
1667 {
1668 return chunk_empty;
1669 }
1670
1671 enumerator = list->create_enumerator(list);
1672 while (enumerator->enumerate(enumerator, &id))
1673 {
1674 name = build_generalName(id);
1675 subjectAltNames = chunk_cat("mm", subjectAltNames, name);
1676 }
1677 enumerator->destroy(enumerator);
1678
1679 return asn1_wrap(ASN1_SEQUENCE, "mm",
1680 asn1_build_known_oid(OID_SUBJECT_ALT_NAME),
1681 asn1_wrap(ASN1_OCTET_STRING, "m",
1682 asn1_wrap(ASN1_SEQUENCE, "m", subjectAltNames)
1683 )
1684 );
1685 }
1686
1687 /**
1688 * Generate and sign a new certificate
1689 */
1690 static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
1691 private_key_t *sign_key, int digest_alg)
1692 {
1693 chunk_t extensions = chunk_empty, extendedKeyUsage = chunk_empty;
1694 chunk_t serverAuth = chunk_empty, clientAuth = chunk_empty;
1695 chunk_t ocspSigning = chunk_empty;
1696 chunk_t basicConstraints = chunk_empty;
1697 chunk_t keyUsage = chunk_empty, keyUsageBits = chunk_empty;
1698 chunk_t subjectAltNames = chunk_empty;
1699 chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty;
1700 chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
1701 identification_t *issuer, *subject;
1702 crl_uri_t *entry;
1703 chunk_t key_info;
1704 signature_scheme_t scheme;
1705 hasher_t *hasher;
1706 enumerator_t *enumerator, *uris;
1707 char *uri;
1708
1709 subject = cert->subject;
1710 if (sign_cert)
1711 {
1712 issuer = sign_cert->get_subject(sign_cert);
1713 if (!cert->public_key)
1714 {
1715 return FALSE;
1716 }
1717 }
1718 else
1719 { /* self signed */
1720 issuer = subject;
1721 if (!cert->public_key)
1722 {
1723 cert->public_key = sign_key->get_public_key(sign_key);
1724 }
1725 cert->flags |= X509_SELF_SIGNED;
1726 }
1727 cert->issuer = issuer->clone(issuer);
1728 if (!cert->notBefore)
1729 {
1730 cert->notBefore = time(NULL);
1731 }
1732 if (!cert->notAfter)
1733 { /* defaults to 1 year from now */
1734 cert->notAfter = cert->notBefore + 60 * 60 * 24 * 365;
1735 }
1736
1737 /* select signature scheme */
1738 cert->algorithm = hasher_signature_algorithm_to_oid(digest_alg,
1739 sign_key->get_type(sign_key));
1740 if (cert->algorithm == OID_UNKNOWN)
1741 {
1742 return FALSE;
1743 }
1744 scheme = signature_scheme_from_oid(cert->algorithm);
1745
1746 if (!cert->public_key->get_encoding(cert->public_key,
1747 PUBKEY_SPKI_ASN1_DER, &key_info))
1748 {
1749 return FALSE;
1750 }
1751
1752 /* encode subjectAltNames */
1753 subjectAltNames = x509_build_subjectAltNames(cert->subjectAltNames);
1754
1755 /* encode CRL distribution points extension */
1756 enumerator = cert->crl_uris->create_enumerator(cert->crl_uris);
1757 while (enumerator->enumerate(enumerator, &entry))
1758 {
1759 chunk_t distributionPoint, gn;
1760 chunk_t crlIssuer = chunk_empty, gns = chunk_empty;
1761
1762 if (entry->issuer)
1763 {
1764 crlIssuer = asn1_wrap(ASN1_CONTEXT_C_2, "m",
1765 build_generalName(entry->issuer));
1766 }
1767 uris = entry->uris->create_enumerator(entry->uris);
1768 while (uris->enumerate(uris, &uri))
1769 {
1770 gn = asn1_wrap(ASN1_CONTEXT_S_6, "c", chunk_create(uri, strlen(uri)));
1771 gns = chunk_cat("mm", gns, gn);
1772 }
1773 uris->destroy(uris);
1774
1775 distributionPoint = asn1_wrap(ASN1_SEQUENCE, "mm",
1776 asn1_wrap(ASN1_CONTEXT_C_0, "m",
1777 asn1_wrap(ASN1_CONTEXT_C_0, "m", gns)),
1778 crlIssuer);
1779 crlDistributionPoints = chunk_cat("mm", crlDistributionPoints,
1780 distributionPoint);
1781 }
1782 enumerator->destroy(enumerator);
1783 if (crlDistributionPoints.ptr)
1784 {
1785 crlDistributionPoints = asn1_wrap(ASN1_SEQUENCE, "mm",
1786 asn1_build_known_oid(OID_CRL_DISTRIBUTION_POINTS),
1787 asn1_wrap(ASN1_OCTET_STRING, "m",
1788 asn1_wrap(ASN1_SEQUENCE, "m", crlDistributionPoints)));
1789 }
1790
1791 /* encode OCSP URIs in authorityInfoAccess extension */
1792 enumerator = cert->ocsp_uris->create_enumerator(cert->ocsp_uris);
1793 while (enumerator->enumerate(enumerator, &uri))
1794 {
1795 chunk_t accessDescription;
1796
1797 accessDescription = asn1_wrap(ASN1_SEQUENCE, "mm",
1798 asn1_build_known_oid(OID_OCSP),
1799 asn1_wrap(ASN1_CONTEXT_S_6, "c",
1800 chunk_create(uri, strlen(uri))));
1801 authorityInfoAccess = chunk_cat("mm", authorityInfoAccess,
1802 accessDescription);
1803 }
1804 enumerator->destroy(enumerator);
1805 if (authorityInfoAccess.ptr)
1806 {
1807 authorityInfoAccess = asn1_wrap(ASN1_SEQUENCE, "mm",
1808 asn1_build_known_oid(OID_AUTHORITY_INFO_ACCESS),
1809 asn1_wrap(ASN1_OCTET_STRING, "m",
1810 asn1_wrap(ASN1_SEQUENCE, "m", authorityInfoAccess)));
1811 }
1812
1813 /* build CA basicConstraint and keyUsage flags for CA certificates */
1814 if (cert->flags & X509_CA)
1815 {
1816 chunk_t pathLenConstraint = chunk_empty;
1817
1818 if (cert->pathLenConstraint != X509_NO_PATH_LEN_CONSTRAINT)
1819 {
1820 char pathlen = (char)cert->pathLenConstraint;
1821
1822 pathLenConstraint = asn1_integer("c", chunk_from_thing(pathlen));
1823 }
1824 basicConstraints = asn1_wrap(ASN1_SEQUENCE, "mmm",
1825 asn1_build_known_oid(OID_BASIC_CONSTRAINTS),
1826 asn1_wrap(ASN1_BOOLEAN, "c",
1827 chunk_from_chars(0xFF)),
1828 asn1_wrap(ASN1_OCTET_STRING, "m",
1829 asn1_wrap(ASN1_SEQUENCE, "mm",
1830 asn1_wrap(ASN1_BOOLEAN, "c",
1831 chunk_from_chars(0xFF)),
1832 pathLenConstraint)));
1833 /* set CertificateSign and implicitly CRLsign */
1834 keyUsageBits = chunk_from_chars(0x01, 0x06);
1835 }
1836 else if (cert->flags & X509_CRL_SIGN)
1837 {
1838 keyUsageBits = chunk_from_chars(0x01, 0x02);
1839 }
1840 if (keyUsageBits.len)
1841 {
1842 keyUsage = asn1_wrap(ASN1_SEQUENCE, "mmm",
1843 asn1_build_known_oid(OID_KEY_USAGE),
1844 asn1_wrap(ASN1_BOOLEAN, "c", chunk_from_chars(0xFF)),
1845 asn1_wrap(ASN1_OCTET_STRING, "m",
1846 asn1_wrap(ASN1_BIT_STRING, "c", keyUsageBits)));
1847 }
1848
1849 /* add serverAuth extendedKeyUsage flag */
1850 if (cert->flags & X509_SERVER_AUTH)
1851 {
1852 serverAuth = asn1_build_known_oid(OID_SERVER_AUTH);
1853 }
1854 if (cert->flags & X509_CLIENT_AUTH)
1855 {
1856 clientAuth = asn1_build_known_oid(OID_CLIENT_AUTH);
1857 }
1858
1859 /* add ocspSigning extendedKeyUsage flag */
1860 if (cert->flags & X509_OCSP_SIGNER)
1861 {
1862 ocspSigning = asn1_build_known_oid(OID_OCSP_SIGNING);
1863 }
1864
1865 if (serverAuth.ptr || clientAuth.ptr || ocspSigning.ptr)
1866 {
1867 extendedKeyUsage = asn1_wrap(ASN1_SEQUENCE, "mm",
1868 asn1_build_known_oid(OID_EXTENDED_KEY_USAGE),
1869 asn1_wrap(ASN1_OCTET_STRING, "m",
1870 asn1_wrap(ASN1_SEQUENCE, "mmm",
1871 serverAuth, clientAuth, ocspSigning)));
1872 }
1873
1874 /* add subjectKeyIdentifier to CA and OCSP signer certificates */
1875 if (cert->flags & (X509_CA | X509_OCSP_SIGNER | X509_CRL_SIGN))
1876 {
1877 chunk_t keyid;
1878
1879 if (cert->public_key->get_fingerprint(cert->public_key,
1880 KEYID_PUBKEY_SHA1, &keyid))
1881 {
1882 subjectKeyIdentifier = asn1_wrap(ASN1_SEQUENCE, "mm",
1883 asn1_build_known_oid(OID_SUBJECT_KEY_ID),
1884 asn1_wrap(ASN1_OCTET_STRING, "m",
1885 asn1_wrap(ASN1_OCTET_STRING, "c", keyid)));
1886 }
1887 }
1888
1889 /* add the keyid authKeyIdentifier for non self-signed certificates */
1890 if (sign_key)
1891 {
1892 chunk_t keyid;
1893
1894 if (sign_key->get_fingerprint(sign_key, KEYID_PUBKEY_SHA1, &keyid))
1895 {
1896 authKeyIdentifier = asn1_wrap(ASN1_SEQUENCE, "mm",
1897 asn1_build_known_oid(OID_AUTHORITY_KEY_ID),
1898 asn1_wrap(ASN1_OCTET_STRING, "m",
1899 asn1_wrap(ASN1_SEQUENCE, "m",
1900 asn1_wrap(ASN1_CONTEXT_S_0, "c", keyid))));
1901 }
1902 }
1903 if (basicConstraints.ptr || subjectAltNames.ptr || authKeyIdentifier.ptr ||
1904 crlDistributionPoints.ptr)
1905 {
1906 extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m",
1907 asn1_wrap(ASN1_SEQUENCE, "mmmmmmmm",
1908 basicConstraints, keyUsage, subjectKeyIdentifier,
1909 authKeyIdentifier, subjectAltNames,
1910 extendedKeyUsage, crlDistributionPoints,
1911 authorityInfoAccess));
1912 }
1913
1914 cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm",
1915 asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2),
1916 asn1_integer("c", cert->serialNumber),
1917 asn1_algorithmIdentifier(cert->algorithm),
1918 issuer->get_encoding(issuer),
1919 asn1_wrap(ASN1_SEQUENCE, "mm",
1920 asn1_from_time(&cert->notBefore, ASN1_UTCTIME),
1921 asn1_from_time(&cert->notAfter, ASN1_UTCTIME)),
1922 subject->get_encoding(subject),
1923 key_info, extensions);
1924
1925 if (!sign_key->sign(sign_key, scheme, cert->tbsCertificate, &cert->signature))
1926 {
1927 return FALSE;
1928 }
1929 cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm", cert->tbsCertificate,
1930 asn1_algorithmIdentifier(cert->algorithm),
1931 asn1_bitstring("c", cert->signature));
1932
1933 hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
1934 if (!hasher)
1935 {
1936 return FALSE;
1937 }
1938 hasher->allocate_hash(hasher, cert->encoding, &cert->encoding_hash);
1939 hasher->destroy(hasher);
1940 return TRUE;
1941 }
1942
1943 /**
1944 * See header.
1945 */
1946 x509_cert_t *x509_cert_load(certificate_type_t type, va_list args)
1947 {
1948 x509_flag_t flags = 0;
1949 chunk_t blob = chunk_empty;
1950
1951 while (TRUE)
1952 {
1953 switch (va_arg(args, builder_part_t))
1954 {
1955 case BUILD_BLOB_ASN1_DER:
1956 blob = va_arg(args, chunk_t);
1957 continue;
1958 case BUILD_X509_FLAG:
1959 flags |= va_arg(args, x509_flag_t);
1960 continue;
1961 case BUILD_END:
1962 break;
1963 default:
1964 return NULL;
1965 }
1966 break;
1967 }
1968
1969 if (blob.ptr)
1970 {
1971 private_x509_cert_t *cert = create_empty();
1972
1973 cert->encoding = chunk_clone(blob);
1974 cert->parsed = TRUE;
1975 if (parse_certificate(cert))
1976 {
1977 cert->flags |= flags;
1978 return &cert->public;
1979 }
1980 destroy(cert);
1981 }
1982 return NULL;
1983 }
1984
1985 /**
1986 * See header.
1987 */
1988 x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
1989 {
1990 private_x509_cert_t *cert;
1991 certificate_t *sign_cert = NULL;
1992 private_key_t *sign_key = NULL;
1993 identification_t *crl_issuer = NULL;
1994 hash_algorithm_t digest_alg = HASH_SHA1;
1995
1996 cert = create_empty();
1997 while (TRUE)
1998 {
1999 switch (va_arg(args, builder_part_t))
2000 {
2001 case BUILD_X509_FLAG:
2002 cert->flags |= va_arg(args, x509_flag_t);
2003 continue;
2004 case BUILD_SIGNING_KEY:
2005 sign_key = va_arg(args, private_key_t*);
2006 continue;
2007 case BUILD_SIGNING_CERT:
2008 sign_cert = va_arg(args, certificate_t*);
2009 continue;
2010 case BUILD_PUBLIC_KEY:
2011 cert->public_key = va_arg(args, public_key_t*);
2012 cert->public_key->get_ref(cert->public_key);
2013 continue;
2014 case BUILD_SUBJECT:
2015 cert->subject = va_arg(args, identification_t*);
2016 cert->subject = cert->subject->clone(cert->subject);
2017 continue;
2018 case BUILD_SUBJECT_ALTNAMES:
2019 {
2020 enumerator_t *enumerator;
2021 identification_t *id;
2022 linked_list_t *list;
2023
2024 list = va_arg(args, linked_list_t*);
2025 enumerator = list->create_enumerator(list);
2026 while (enumerator->enumerate(enumerator, &id))
2027 {
2028 cert->subjectAltNames->insert_last(cert->subjectAltNames,
2029 id->clone(id));
2030 }
2031 enumerator->destroy(enumerator);
2032 continue;
2033 }
2034 case BUILD_CRL_DISTRIBUTION_POINTS:
2035 {
2036 enumerator_t *enumerator;
2037 linked_list_t *list;
2038 crl_uri_t *entry;
2039 char *uri;
2040
2041 list = va_arg(args, linked_list_t*);
2042 if (list->get_count(list))
2043 {
2044 entry = crl_uri_create(crl_issuer);
2045 enumerator = list->create_enumerator(list);
2046 while (enumerator->enumerate(enumerator, &uri))
2047 {
2048 entry->uris->insert_last(entry->uris, strdup(uri));
2049 }
2050 enumerator->destroy(enumerator);
2051 cert->crl_uris->insert_last(cert->crl_uris, entry);
2052 }
2053 continue;
2054 }
2055 case BUILD_CRL_ISSUER:
2056 {
2057 crl_issuer = va_arg(args, identification_t*);
2058 continue;
2059 }
2060 case BUILD_OCSP_ACCESS_LOCATIONS:
2061 {
2062 enumerator_t *enumerator;
2063 linked_list_t *list;
2064 char *uri;
2065
2066 list = va_arg(args, linked_list_t*);
2067 enumerator = list->create_enumerator(list);
2068 while (enumerator->enumerate(enumerator, &uri))
2069 {
2070 cert->ocsp_uris->insert_last(cert->ocsp_uris, strdup(uri));
2071 }
2072 enumerator->destroy(enumerator);
2073 continue;
2074 }
2075 case BUILD_PATHLEN:
2076 cert->pathLenConstraint = va_arg(args, int);
2077 if (cert->pathLenConstraint < 0 || cert->pathLenConstraint > 127)
2078 {
2079 cert->pathLenConstraint = X509_NO_PATH_LEN_CONSTRAINT;
2080 }
2081 continue;
2082 case BUILD_NOT_BEFORE_TIME:
2083 cert->notBefore = va_arg(args, time_t);
2084 continue;
2085 case BUILD_NOT_AFTER_TIME:
2086 cert->notAfter = va_arg(args, time_t);
2087 continue;
2088 case BUILD_SERIAL:
2089 cert->serialNumber = chunk_clone(va_arg(args, chunk_t));
2090 continue;
2091 case BUILD_DIGEST_ALG:
2092 digest_alg = va_arg(args, int);
2093 continue;
2094 case BUILD_END:
2095 break;
2096 default:
2097 destroy(cert);
2098 return NULL;
2099 }
2100 break;
2101 }
2102
2103 if (sign_key && generate(cert, sign_cert, sign_key, digest_alg))
2104 {
2105 return &cert->public;
2106 }
2107 destroy(cert);
2108 return NULL;
2109 }
2110