added credential factory support for BULD_NOT_BEFORE_TIME and BUILD_NOT_AFTER_TIME
[strongswan.git] / src / libstrongswan / plugins / x509 / x509_ac.c
1 /*
2 * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
3 * Copyright (C) 2003 Martin Berner, Lukas Suter
4 * Copyright (C) 2002-2008 Andreas Steffen
5 *
6 * Hochschule fuer Technik Rapperswil
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 *
18 * $Id$
19 */
20
21 #include "x509_ac.h"
22 #include "ietf_attr_list.h"
23
24 #include <library.h>
25 #include <debug.h>
26 #include <asn1/oid.h>
27 #include <asn1/asn1.h>
28 #include <utils/identification.h>
29 #include <utils/linked_list.h>
30 #include <credentials/certificates/x509.h>
31
32 typedef struct private_x509_ac_t private_x509_ac_t;
33
34 /**
35 * private data of x509_ac_t object
36 */
37 struct private_x509_ac_t {
38
39 /**
40 * public functions
41 */
42 x509_ac_t public;
43
44 /**
45 * X.509 attribute certificate in DER format
46 */
47 chunk_t encoding;
48
49 /**
50 * X.509 attribute certificate body over which signature is computed
51 */
52 chunk_t certificateInfo;
53
54 /**
55 * Version of the X.509 attribute certificate
56 */
57 u_int version;
58
59 /**
60 * Serial number of the X.509 attribute certificate
61 */
62 chunk_t serialNumber;
63
64 /**
65 * ID representing the issuer of the holder certificate
66 */
67 identification_t *holderIssuer;
68
69 /**
70 * Serial number of the holder certificate
71 */
72 chunk_t holderSerial;
73
74 /**
75 * ID representing the holder
76 */
77 identification_t *entityName;
78
79 /**
80 * ID representing the attribute certificate issuer
81 */
82 identification_t *issuerName;
83
84 /**
85 * Signature algorithm
86 */
87 int algorithm;
88
89 /**
90 * Start time of certificate validity
91 */
92 time_t notBefore;
93
94 /**
95 * End time of certificate validity
96 */
97 time_t notAfter;
98
99 /**
100 * List of charging attributes
101 */
102 linked_list_t *charging;
103
104 /**
105 * List of groub attributes
106 */
107 linked_list_t *groups;
108
109 /**
110 * Authority Key Identifier
111 */
112 identification_t *authKeyIdentifier;
113
114 /**
115 * Authority Key Serial Number
116 */
117 chunk_t authKeySerialNumber;
118
119 /**
120 * No revocation information available
121 */
122 bool noRevAvail;
123
124 /**
125 * Signature
126 */
127 chunk_t signature;
128
129 /**
130 * Holder certificate
131 */
132 certificate_t *holderCert;
133
134 /**
135 * Signer certificate
136 */
137 certificate_t *signerCert;
138
139 /**
140 * Signer private key;
141 */
142 private_key_t *signerKey;
143
144 /**
145 * reference count
146 */
147 refcount_t ref;
148 };
149
150 static u_char ASN1_group_oid_str[] = {
151 0x06, 0x08,
152 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
153 };
154
155 static const chunk_t ASN1_group_oid = chunk_from_buf(ASN1_group_oid_str);
156
157 static u_char ASN1_authorityKeyIdentifier_oid_str[] = {
158 0x06, 0x03,
159 0x55, 0x1d, 0x23
160 };
161
162 static const chunk_t ASN1_authorityKeyIdentifier_oid =
163 chunk_from_buf(ASN1_authorityKeyIdentifier_oid_str);
164
165 static u_char ASN1_noRevAvail_ext_str[] = {
166 0x30, 0x09,
167 0x06, 0x03,
168 0x55, 0x1d, 0x38,
169 0x04, 0x02,
170 0x05, 0x00
171 };
172
173 static const chunk_t ASN1_noRevAvail_ext = chunk_from_buf(ASN1_noRevAvail_ext_str);
174
175 /**
176 * ASN.1 definition of roleSyntax
177 */
178 static const asn1Object_t roleSyntaxObjects[] =
179 {
180 { 0, "roleSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
181 { 1, "roleAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
182 ASN1_OBJ }, /* 1 */
183 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
184 { 1, "roleName", ASN1_CONTEXT_C_1, ASN1_OBJ } /* 3 */
185 };
186
187 #define ROLE_ROOF 4
188
189 /**
190 * ASN.1 definition of an X509 attribute certificate
191 */
192 static const asn1Object_t acObjects[] =
193 {
194 { 0, "AttributeCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
195 { 1, "AttributeCertificateInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
196 { 2, "version", ASN1_INTEGER, ASN1_DEF |
197 ASN1_BODY }, /* 2 */
198 { 2, "holder", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
199 { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */
200 { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
201 { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 6 */
202 { 4, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
203 ASN1_BODY }, /* 7 */
204 { 4, "end opt", ASN1_EOC, ASN1_END }, /* 8 */
205 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
206 { 3, "entityName", ASN1_CONTEXT_C_1, ASN1_OPT |
207 ASN1_OBJ }, /* 10 */
208 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
209 { 3, "objectDigestInfo", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 12 */
210 { 4, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 13*/
211 { 4, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
212 ASN1_BODY }, /* 14 */
213 { 4, "end opt", ASN1_EOC, ASN1_END }, /* 15*/
214 { 4, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 16 */
215 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 17 */
216 { 2, "v2Form", ASN1_CONTEXT_C_0, ASN1_NONE }, /* 18 */
217 { 3, "issuerName", ASN1_SEQUENCE, ASN1_OPT |
218 ASN1_OBJ }, /* 19 */
219 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
220 { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */
221 { 4, "issuerSerial", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
222 { 5, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 23 */
223 { 5, "serial", ASN1_INTEGER, ASN1_BODY }, /* 24 */
224 { 5, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
225 ASN1_BODY }, /* 25 */
226 { 5, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
227 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
228 { 3, "objectDigestInfo", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 28 */
229 { 4, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 29 */
230 { 5, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 30 */
231 { 5, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
232 ASN1_BODY }, /* 31 */
233 { 5, "end opt", ASN1_EOC, ASN1_END }, /* 32 */
234 { 5, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 33 */
235 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 34 */
236 { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 35 */
237 { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 36 */
238 { 2, "attrCertValidityPeriod", ASN1_SEQUENCE, ASN1_NONE }, /* 37 */
239 { 3, "notBeforeTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
240 { 3, "notAfterTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
241 { 2, "attributes", ASN1_SEQUENCE, ASN1_LOOP }, /* 40 */
242 { 3, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 41 */
243 { 4, "type", ASN1_OID, ASN1_BODY }, /* 42 */
244 { 4, "values", ASN1_SET, ASN1_LOOP }, /* 43 */
245 { 5, "value", ASN1_EOC, ASN1_RAW }, /* 44 */
246 { 4, "end loop", ASN1_EOC, ASN1_END }, /* 45 */
247 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 46 */
248 { 2, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 47 */
249 { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 48 */
250 { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 49 */
251 { 4, "critical", ASN1_BOOLEAN, ASN1_DEF |
252 ASN1_BODY }, /* 50 */
253 { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 51 */
254 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 52 */
255 { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 53 */
256 { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 54 */
257 };
258
259 #define AC_OBJ_CERTIFICATE 0
260 #define AC_OBJ_CERTIFICATE_INFO 1
261 #define AC_OBJ_VERSION 2
262 #define AC_OBJ_HOLDER_ISSUER 5
263 #define AC_OBJ_HOLDER_SERIAL 6
264 #define AC_OBJ_ENTITY_NAME 10
265 #define AC_OBJ_ISSUER_NAME 19
266 #define AC_OBJ_ISSUER 23
267 #define AC_OBJ_SIG_ALG 35
268 #define AC_OBJ_SERIAL_NUMBER 36
269 #define AC_OBJ_NOT_BEFORE 38
270 #define AC_OBJ_NOT_AFTER 39
271 #define AC_OBJ_ATTRIBUTE_TYPE 42
272 #define AC_OBJ_ATTRIBUTE_VALUE 44
273 #define AC_OBJ_EXTN_ID 49
274 #define AC_OBJ_CRITICAL 50
275 #define AC_OBJ_EXTN_VALUE 51
276 #define AC_OBJ_ALGORITHM 53
277 #define AC_OBJ_SIGNATURE 54
278 #define AC_OBJ_ROOF 55
279
280 /**
281 * build directoryName
282 */
283 static chunk_t build_directoryName(asn1_t tag, chunk_t name)
284 {
285 return asn1_wrap(tag, "m",
286 asn1_simple_object(ASN1_CONTEXT_C_4, name));
287 }
288
289 /**
290 * build holder
291 */
292 static chunk_t build_holder(private_x509_ac_t *this)
293 {
294 x509_t* x509 = (x509_t*)this->holderCert;
295 identification_t *issuer = this->holderCert->get_issuer(this->holderCert);
296 identification_t *subject = this->holderCert->get_subject(this->holderCert);
297
298 return asn1_wrap(ASN1_SEQUENCE, "mm",
299 asn1_wrap(ASN1_CONTEXT_C_0, "mm",
300 build_directoryName(ASN1_SEQUENCE, issuer->get_encoding(issuer)),
301 asn1_simple_object(ASN1_INTEGER, x509->get_serial(x509))
302 ),
303 build_directoryName(ASN1_CONTEXT_C_1, subject->get_encoding(subject)));
304 }
305
306 /**
307 * build v2Form
308 */
309 static chunk_t build_v2_form(private_x509_ac_t *this)
310 {
311 identification_t *subject = this->signerCert->get_subject(this->signerCert);
312
313 return asn1_wrap(ASN1_CONTEXT_C_0, "m",
314 build_directoryName(ASN1_SEQUENCE, subject->get_encoding(subject)));
315 }
316
317 /**
318 * build attrCertValidityPeriod
319 */
320 static chunk_t build_attr_cert_validity(private_x509_ac_t *this)
321 {
322 return asn1_wrap(ASN1_SEQUENCE, "mm",
323 timetoasn1(&this->notBefore, ASN1_GENERALIZEDTIME),
324 timetoasn1(&this->notAfter, ASN1_GENERALIZEDTIME));
325 }
326
327
328 /**
329 * build attribute type
330 */
331 static chunk_t build_attribute_type(const chunk_t type, chunk_t content)
332 {
333 return asn1_wrap(ASN1_SEQUENCE, "cm",
334 type,
335 asn1_wrap(ASN1_SET, "m", content));
336 }
337
338 /**
339 * build attributes
340 */
341 static chunk_t build_attributes(private_x509_ac_t *this)
342 {
343 return asn1_wrap(ASN1_SEQUENCE, "m",
344 build_attribute_type(ASN1_group_oid, ietfAttr_list_encode(this->groups)));
345 }
346
347 /**
348 * build authorityKeyIdentifier
349 */
350 static chunk_t build_authorityKeyIdentifier(private_x509_ac_t *this)
351 {
352 x509_t *x509 = (x509_t*)this->signerCert;
353 identification_t *issuer = this->signerCert->get_issuer(this->signerCert);
354 public_key_t *public = this->signerCert->get_public_key(this->signerCert);
355 chunk_t keyIdentifier;
356 chunk_t authorityCertIssuer;
357 chunk_t authorityCertSerialNumber;
358
359 if (public)
360 {
361 this->authKeyIdentifier = public->get_id(public, ID_PUBKEY_SHA1);
362 public->destroy(public);
363 keyIdentifier = this->authKeyIdentifier->get_encoding(this->authKeyIdentifier);
364 }
365 else
366 {
367 keyIdentifier = chunk_empty;
368 }
369
370 authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1,
371 issuer->get_encoding(issuer));
372
373 authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2,
374 x509->get_serial(x509));
375
376 return asn1_wrap(ASN1_SEQUENCE, "cm",
377 ASN1_authorityKeyIdentifier_oid,
378 asn1_wrap(ASN1_OCTET_STRING, "m",
379 asn1_wrap(ASN1_SEQUENCE, "mmm",
380 keyIdentifier,
381 authorityCertIssuer,
382 authorityCertSerialNumber
383 )
384 )
385 );
386 }
387
388 /**
389 * build extensions
390 */
391 static chunk_t build_extensions(private_x509_ac_t *this)
392 {
393 return asn1_wrap(ASN1_SEQUENCE, "mc",
394 build_authorityKeyID(this),
395 ASN1_noRevAvail_ext);
396 }
397
398 /**
399 * build attributeCertificateInfo
400 */
401 static chunk_t build_attr_cert_info(private_x509_ac_t *this)
402 {
403 return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm",
404 ASN1_INTEGER_1,
405 build_holder(this),
406 build_v2_form(this),
407 asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
408 asn1_simple_object(ASN1_INTEGER, this->serialNumber),
409 build_attr_cert_validity(this),
410 build_attributes(this),
411 build_extensions(this));
412 }
413
414
415 /**
416 * build an X.509 attribute certificate
417 */
418 static chunk_t build_ac(private_x509_ac_t *this)
419 {
420 chunk_t signatureValue;
421 chunk_t attributeCertificateInfo = build_attr_cert_info(this);
422 /*
423 signerkey->build_emsa_pkcs1_signature(signerkey, HASH_SHA1,
424 attributeCertificateInfo, &signatureValue);
425 */
426 return asn1_wrap(ASN1_SEQUENCE, "mcm",
427 attributeCertificateInfo,
428 asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
429 asn1_bitstring("m", signatureValue));
430 }
431
432 /**
433 * Implementation of certificate_t.get_type
434 */
435 static certificate_type_t get_type(private_x509_ac_t *this)
436 {
437 return CERT_X509_AC;
438 }
439
440 /**
441 * Implementation of certificate_t.get_subject
442 */
443 static identification_t* get_subject(private_x509_ac_t *this)
444 {
445 return this->entityName;
446 }
447
448 /**
449 * Implementation of certificate_t.get_issuer
450 */
451 static identification_t* get_issuer(private_x509_ac_t *this)
452 {
453 return this->issuerName;
454 }
455
456 /**
457 * Implementation of certificate_t.has_subject.
458 */
459 static id_match_t has_subject(private_x509_ac_t *this, identification_t *subject)
460 {
461 return ID_MATCH_NONE;
462 }
463
464 /**
465 * Implementation of certificate_t.has_issuer.
466 */
467 static id_match_t has_issuer(private_x509_ac_t *this, identification_t *issuer)
468 {
469 id_match_t match;
470
471 if (issuer->get_type(issuer) == ID_PUBKEY_SHA1)
472 {
473 if (this->authKeyIdentifier)
474 {
475 match = issuer->matches(issuer, this->authKeyIdentifier);
476 }
477 else
478 {
479 match = ID_MATCH_NONE;
480 }
481 }
482 else
483 {
484 match = this->issuerName->matches(this->issuerName, issuer);
485 }
486 return match;
487 }
488
489 /**
490 * Implementation of certificate_t.issued_by
491 */
492 static bool issued_by(private_x509_ac_t *this, certificate_t *issuer,
493 bool sigcheck)
494 {
495 public_key_t *key;
496 signature_scheme_t scheme;
497 bool valid;
498 x509_t *x509 = (x509_t*)issuer;
499
500 /* check if issuer is an X.509 AA certificate */
501 if (issuer->get_type(issuer) != CERT_X509)
502 {
503 return FALSE;
504 }
505 if (!(x509->get_flags(x509) & X509_AA))
506 {
507 return FALSE;
508 }
509
510 /* get the public key of the issuer */
511 key = issuer->get_public_key(issuer);
512
513 /* compare keyIdentifiers if available, otherwise use DNs */
514 if (this->authKeyIdentifier && key)
515 {
516 identification_t *subjectKeyIdentifier = key->get_id(key, ID_PUBKEY_SHA1);
517
518 if (!subjectKeyIdentifier->equals(subjectKeyIdentifier,
519 this->authKeyIdentifier))
520 {
521 return FALSE;
522 }
523 }
524 else
525 {
526 if (!this->issuerName->equals(this->issuerName, issuer->get_subject(issuer)))
527 {
528 return FALSE;
529 }
530 }
531
532 if (!sigcheck)
533 {
534 return TRUE;
535 }
536 /* TODO: generic OID to scheme mapper? */
537 switch (this->algorithm)
538 {
539 case OID_MD5_WITH_RSA:
540 scheme = SIGN_RSA_EMSA_PKCS1_MD5;
541 break;
542 case OID_SHA1_WITH_RSA:
543 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
544 break;
545 case OID_SHA256_WITH_RSA:
546 scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
547 break;
548 case OID_SHA384_WITH_RSA:
549 scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
550 break;
551 case OID_SHA512_WITH_RSA:
552 scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
553 break;
554 default:
555 return FALSE;
556 }
557 if (key == NULL)
558 {
559 return FALSE;
560 }
561 valid = key->verify(key, scheme, this->certificateInfo, this->signature);
562 key->destroy(key);
563 return valid;
564 }
565
566 /**
567 * Implementation of certificate_t.get_public_key.
568 */
569 static public_key_t* get_public_key(private_x509_ac_t *this)
570 {
571 return NULL;
572 }
573
574 /**
575 * Implementation of certificate_t.get_ref.
576 */
577 static private_x509_ac_t* get_ref(private_x509_ac_t *this)
578 {
579 ref_get(&this->ref);
580 return this;
581 }
582
583 /**
584 * Implementation of certificate_t.get_validity.
585 */
586 static bool get_validity(private_x509_ac_t *this, time_t *when,
587 time_t *not_before, time_t *not_after)
588 {
589 time_t t;
590
591 if (when)
592 {
593 t = *when;
594 }
595 else
596 {
597 t = time(NULL);
598 }
599 if (not_before)
600 {
601 *not_before = this->notBefore;
602 }
603 if (not_after)
604 {
605 *not_after = this->notAfter;
606 }
607 return (t >= this->notBefore && t <= this->notAfter);
608 }
609
610 /**
611 * Implementation of certificate_t.is_newer.
612 */
613 static bool is_newer(private_x509_ac_t *this, ac_t *that)
614 {
615 certificate_t *this_cert = &this->public.interface.certificate;
616 certificate_t *that_cert = &that->certificate;
617 time_t this_update, that_update, now = time(NULL);
618 bool new;
619
620 this_cert->get_validity(this_cert, &now, &this_update, NULL);
621 that_cert->get_validity(that_cert, &now, &that_update, NULL);
622 new = this_update > that_update;
623 DBG1(" attr cert from %#T is %s - existing attr_cert from %#T %s",
624 &this_update, FALSE, new ? "newer":"not newer",
625 &that_update, FALSE, new ? "replaced":"retained");
626 return new;
627 }
628
629 /**
630 * Implementation of certificate_t.get_encoding.
631 */
632 static chunk_t get_encoding(private_x509_ac_t *this)
633 {
634 return chunk_clone(this->encoding);
635 }
636
637 /**
638 * Implementation of certificate_t.equals.
639 */
640 static bool equals(private_x509_ac_t *this, certificate_t *other)
641 {
642 if ((certificate_t*)this == other)
643 {
644 return TRUE;
645 }
646 if (other->equals == (void*)equals)
647 { /* same implementation */
648 return chunk_equals(this->signature,
649 ((private_x509_ac_t*)other)->signature);
650 }
651 /* TODO: compare against other implementations */
652 return FALSE;
653 }
654
655 /**
656 * Implementation of x509_ac_t.destroy
657 */
658 static void destroy(private_x509_ac_t *this)
659 {
660 if (ref_put(&this->ref))
661 {
662 DESTROY_IF(this->holderIssuer);
663 DESTROY_IF(this->entityName);
664 DESTROY_IF(this->issuerName);
665 DESTROY_IF(this->authKeyIdentifier);
666 DESTROY_IF(this->holderCert);
667 DESTROY_IF(this->signerCert);
668 DESTROY_IF(this->signerKey);
669 ietfAttr_list_destroy(this->charging);
670 ietfAttr_list_destroy(this->groups);
671 free(this->encoding.ptr);
672 free(this);
673 }
674 }
675
676 /**
677 * create an empty but initialized X.509 attribute certificate
678 */
679 static private_x509_ac_t *create_empty()
680 {
681 private_x509_ac_t *this = malloc_thing(private_x509_ac_t);
682
683 /* public functions */
684 this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
685 this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
686 this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
687 this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
688 this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
689 this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by;
690 this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
691 this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
692 this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
693 this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
694 this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
695 this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
696
697 /* initialize */
698 this->holderIssuer = NULL;
699 this->entityName = NULL;
700 this->issuerName = NULL;
701 this->authKeyIdentifier = NULL;
702 this->holderCert = NULL;
703 this->signerCert = NULL;
704 this->signerKey = NULL;
705 this->charging = linked_list_create();
706 this->groups = linked_list_create();
707
708 return this;
709 }
710
711 typedef struct private_builder_t private_builder_t;
712 /**
713 * Builder implementation for certificate loading
714 */
715 struct private_builder_t {
716 /** implements the builder interface */
717 builder_t public;
718 /** X.509 attribute certificate to build */
719 private_x509_ac_t *ac;
720 };
721
722 /**
723 * Implementation of builder_t.build
724 */
725 static x509_ac_t *build(private_builder_t *this)
726 {
727 private_x509_ac_t *ac;
728
729 ac = this->ac;
730 free(this);
731 if (ac->holderCert && ac->signerCert && ac->signerKey)
732 {
733 ac->encoding = build_ac(ac);
734 return &ac->public;
735 }
736 destroy(ac);
737 return NULL;
738 }
739
740 /**
741 * Implementation of builder_t.add
742 */
743 static void add(private_builder_t *this, builder_part_t part, ...)
744 {
745 va_list args;
746 certificate_t *cert;
747
748 va_start(args, part);
749 switch (part)
750 {
751 case BUILD_NOT_BEFORE_TIME:
752 this->ac->notBefore = va_arg(args, time_t);
753 break;
754 case BUILD_NOT_AFTER_TIME:
755 this->ac->notAfter = va_arg(args, time_t);
756 break;
757 case BUILD_CERT:
758 cert = va_arg(args, certificate_t*);
759 if (cert->get_type(cert) == CERT_X509)
760 {
761 this->ac->holderCert = cert;
762 }
763 else
764 {
765 cert->destroy(cert);
766 }
767 break;
768 case BUILD_SIGNING_CERT:
769 if (cert->get_type(cert) == CERT_X509)
770 {
771 this->ac->signerCert = cert;
772 }
773 else
774 {
775 cert->destroy(cert);
776 }
777 break;
778 case BUILD_SIGNING_KEY:
779 this->ac->signerKey = va_arg(args, private_key_t*);
780 break;
781 default:
782 DBG1("ignoring unsupported build part %N", builder_part_names, part);
783 break;
784 }
785 va_end(args);
786 }
787
788 /**
789 * Builder construction function
790 */
791 builder_t *x509_ac_builder(certificate_type_t type)
792 {
793 private_builder_t *this;
794
795 if (type != CERT_X509_AC)
796 {
797 return NULL;
798 }
799
800 this = malloc_thing(private_builder_t);
801
802 this->ac = create_empty();
803 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
804 this->public.build = (void*(*)(builder_t *this))build;
805
806 return &this->public;
807 }
808