e09c0447dbf428ed97c79cfd048d75d5a612bcb2
[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 x509_t *holder_cert;
133
134 /**
135 * Signer certificate
136 */
137 x509_t *signer_cert;
138
139 /**
140 * Signer private key;
141 */
142 private_key_t *signer_key;
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 = this->holder_cert;
295 certificate_t *cert = &x509->interface;
296
297 identification_t *issuer = cert->get_issuer(cert);
298 identification_t *subject = cert->get_subject(cert);
299
300 return asn1_wrap(ASN1_SEQUENCE, "mm",
301 asn1_wrap(ASN1_CONTEXT_C_0, "mm",
302 build_directoryName(ASN1_SEQUENCE, issuer->get_encoding(issuer)),
303 asn1_simple_object(ASN1_INTEGER, x509->get_serial(x509))
304 ),
305 build_directoryName(ASN1_CONTEXT_C_1, subject->get_encoding(subject)));
306 }
307
308 /**
309 * build v2Form
310 */
311 static chunk_t build_v2_form(private_x509_ac_t *this)
312 {
313 x509_t *x509 = this->signer_cert;
314 certificate_t *cert = &x509->interface;
315 identification_t *subject = cert->get_subject(cert);
316
317 return asn1_wrap(ASN1_CONTEXT_C_0, "m",
318 build_directoryName(ASN1_SEQUENCE, subject->get_encoding(subject)));
319 }
320
321 /**
322 * build attrCertValidityPeriod
323 */
324 static chunk_t build_attr_cert_validity(private_x509_ac_t *this)
325 {
326 return asn1_wrap(ASN1_SEQUENCE, "mm",
327 timetoasn1(&this->notBefore, ASN1_GENERALIZEDTIME),
328 timetoasn1(&this->notAfter, ASN1_GENERALIZEDTIME));
329 }
330
331
332 /**
333 * build attribute type
334 */
335 static chunk_t build_attribute_type(const chunk_t type, chunk_t content)
336 {
337 return asn1_wrap(ASN1_SEQUENCE, "cm",
338 type,
339 asn1_wrap(ASN1_SET, "m", content));
340 }
341
342 /**
343 * build attributes
344 */
345 static chunk_t build_attributes(private_x509_ac_t *this)
346 {
347 return asn1_wrap(ASN1_SEQUENCE, "m",
348 build_attribute_type(ASN1_group_oid, ietfAttr_list_encode(this->groups)));
349 }
350
351 /**
352 * build authorityKeyIdentifier
353 */
354 static chunk_t build_authorityKeyIdentifier(private_x509_ac_t *this)
355 {
356 x509_t *x509 = this->signer_cert;
357 certificate_t *cert = &x509->interface;
358 identification_t *issuer = cert->get_issuer(cert);
359 public_key_t *public = cert->get_public_key(cert);
360 chunk_t keyIdentifier;
361 chunk_t authorityCertIssuer;
362 chunk_t authorityCertSerialNumber;
363
364 if (public)
365 {
366 this->authKeyIdentifier = public->get_id(public, ID_PUBKEY_SHA1);
367 public->destroy(public);
368 keyIdentifier = this->authKeyIdentifier->get_encoding(this->authKeyIdentifier);
369 }
370 else
371 {
372 keyIdentifier = chunk_empty;
373 }
374
375 authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1,
376 issuer->get_encoding(issuer));
377
378 authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2,
379 x509->get_serial(x509));
380
381 return asn1_wrap(ASN1_SEQUENCE, "cm",
382 ASN1_authorityKeyIdentifier_oid,
383 asn1_wrap(ASN1_OCTET_STRING, "m",
384 asn1_wrap(ASN1_SEQUENCE, "mmm",
385 keyIdentifier,
386 authorityCertIssuer,
387 authorityCertSerialNumber
388 )
389 )
390 );
391 }
392
393 /**
394 * build extensions
395 */
396 static chunk_t build_extensions(private_x509_ac_t *this)
397 {
398 return asn1_wrap(ASN1_SEQUENCE, "mc",
399 build_authorityKeyID(this),
400 ASN1_noRevAvail_ext);
401 }
402
403 /**
404 * build attributeCertificateInfo
405 */
406 static chunk_t build_attr_cert_info(private_x509_ac_t *this)
407 {
408 return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm",
409 ASN1_INTEGER_1,
410 build_holder(this),
411 build_v2_form(this),
412 asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
413 asn1_simple_object(ASN1_INTEGER, this->serialNumber),
414 build_attr_cert_validity(this),
415 build_attributes(this),
416 build_extensions(this));
417 }
418
419
420 /**
421 * build an X.509 attribute certificate
422 */
423 static chunk_t build_ac(private_x509_ac_t *this)
424 {
425 chunk_t signatureValue;
426 chunk_t attributeCertificateInfo = build_attr_cert_info(this);
427 /*
428 signerkey->build_emsa_pkcs1_signature(signerkey, HASH_SHA1,
429 attributeCertificateInfo, &signatureValue);
430 */
431 return asn1_wrap(ASN1_SEQUENCE, "mcm",
432 attributeCertificateInfo,
433 asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
434 asn1_bitstring("m", signatureValue));
435 }
436
437 /**
438 * Implementation of certificate_t.get_type
439 */
440 static certificate_type_t get_type(private_x509_ac_t *this)
441 {
442 return CERT_X509_AC;
443 }
444
445 /**
446 * Implementation of certificate_t.get_subject
447 */
448 static identification_t* get_subject(private_x509_ac_t *this)
449 {
450 return this->entityName;
451 }
452
453 /**
454 * Implementation of certificate_t.get_issuer
455 */
456 static identification_t* get_issuer(private_x509_ac_t *this)
457 {
458 return this->issuerName;
459 }
460
461 /**
462 * Implementation of certificate_t.has_subject.
463 */
464 static id_match_t has_subject(private_x509_ac_t *this, identification_t *subject)
465 {
466 return ID_MATCH_NONE;
467 }
468
469 /**
470 * Implementation of certificate_t.has_issuer.
471 */
472 static id_match_t has_issuer(private_x509_ac_t *this, identification_t *issuer)
473 {
474 id_match_t match;
475
476 if (issuer->get_type(issuer) == ID_PUBKEY_SHA1)
477 {
478 if (this->authKeyIdentifier)
479 {
480 match = issuer->matches(issuer, this->authKeyIdentifier);
481 }
482 else
483 {
484 match = ID_MATCH_NONE;
485 }
486 }
487 else
488 {
489 match = this->issuerName->matches(this->issuerName, issuer);
490 }
491 return match;
492 }
493
494 /**
495 * Implementation of certificate_t.issued_by
496 */
497 static bool issued_by(private_x509_ac_t *this, certificate_t *issuer,
498 bool sigcheck)
499 {
500 public_key_t *key;
501 signature_scheme_t scheme;
502 bool valid;
503 x509_t *x509 = (x509_t*)issuer;
504
505 /* check if issuer is an X.509 AA certificate */
506 if (issuer->get_type(issuer) != CERT_X509)
507 {
508 return FALSE;
509 }
510 if (!(x509->get_flags(x509) & X509_AA))
511 {
512 return FALSE;
513 }
514
515 /* get the public key of the issuer */
516 key = issuer->get_public_key(issuer);
517
518 /* compare keyIdentifiers if available, otherwise use DNs */
519 if (this->authKeyIdentifier && key)
520 {
521 identification_t *subjectKeyIdentifier = key->get_id(key, ID_PUBKEY_SHA1);
522
523 if (!subjectKeyIdentifier->equals(subjectKeyIdentifier,
524 this->authKeyIdentifier))
525 {
526 return FALSE;
527 }
528 }
529 else
530 {
531 if (!this->issuerName->equals(this->issuerName, issuer->get_subject(issuer)))
532 {
533 return FALSE;
534 }
535 }
536
537 if (!sigcheck)
538 {
539 return TRUE;
540 }
541 /* TODO: generic OID to scheme mapper? */
542 switch (this->algorithm)
543 {
544 case OID_MD5_WITH_RSA:
545 scheme = SIGN_RSA_EMSA_PKCS1_MD5;
546 break;
547 case OID_SHA1_WITH_RSA:
548 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
549 break;
550 case OID_SHA256_WITH_RSA:
551 scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
552 break;
553 case OID_SHA384_WITH_RSA:
554 scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
555 break;
556 case OID_SHA512_WITH_RSA:
557 scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
558 break;
559 default:
560 return FALSE;
561 }
562 if (key == NULL)
563 {
564 return FALSE;
565 }
566 valid = key->verify(key, scheme, this->certificateInfo, this->signature);
567 key->destroy(key);
568 return valid;
569 }
570
571 /**
572 * Implementation of certificate_t.get_public_key.
573 */
574 static public_key_t* get_public_key(private_x509_ac_t *this)
575 {
576 return NULL;
577 }
578
579 /**
580 * Implementation of certificate_t.get_ref.
581 */
582 static private_x509_ac_t* get_ref(private_x509_ac_t *this)
583 {
584 ref_get(&this->ref);
585 return this;
586 }
587
588 /**
589 * Implementation of certificate_t.get_validity.
590 */
591 static bool get_validity(private_x509_ac_t *this, time_t *when,
592 time_t *not_before, time_t *not_after)
593 {
594 time_t t;
595
596 if (when)
597 {
598 t = *when;
599 }
600 else
601 {
602 t = time(NULL);
603 }
604 if (not_before)
605 {
606 *not_before = this->notBefore;
607 }
608 if (not_after)
609 {
610 *not_after = this->notAfter;
611 }
612 return (t >= this->notBefore && t <= this->notAfter);
613 }
614
615 /**
616 * Implementation of certificate_t.is_newer.
617 */
618 static bool is_newer(private_x509_ac_t *this, ac_t *that)
619 {
620 certificate_t *this_cert = &this->public.interface.certificate;
621 certificate_t *that_cert = &that->certificate;
622 time_t this_update, that_update, now = time(NULL);
623 bool new;
624
625 this_cert->get_validity(this_cert, &now, &this_update, NULL);
626 that_cert->get_validity(that_cert, &now, &that_update, NULL);
627 new = this_update > that_update;
628 DBG1(" attr cert from %#T is %s - existing attr_cert from %#T %s",
629 &this_update, FALSE, new ? "newer":"not newer",
630 &that_update, FALSE, new ? "replaced":"retained");
631 return new;
632 }
633
634 /**
635 * Implementation of certificate_t.get_encoding.
636 */
637 static chunk_t get_encoding(private_x509_ac_t *this)
638 {
639 return chunk_clone(this->encoding);
640 }
641
642 /**
643 * Implementation of certificate_t.equals.
644 */
645 static bool equals(private_x509_ac_t *this, certificate_t *other)
646 {
647 if ((certificate_t*)this == other)
648 {
649 return TRUE;
650 }
651 if (other->equals == (void*)equals)
652 { /* same implementation */
653 return chunk_equals(this->signature,
654 ((private_x509_ac_t*)other)->signature);
655 }
656 /* TODO: compare against other implementations */
657 return FALSE;
658 }
659
660 /**
661 * Implementation of x509_ac_t.destroy
662 */
663 static void destroy(private_x509_ac_t *this)
664 {
665 if (ref_put(&this->ref))
666 {
667 DESTROY_IF(this->holderIssuer);
668 DESTROY_IF(this->entityName);
669 DESTROY_IF(this->issuerName);
670 DESTROY_IF(this->authKeyIdentifier);
671 ietfAttr_list_destroy(this->charging);
672 ietfAttr_list_destroy(this->groups);
673 free(this->encoding.ptr);
674 free(this);
675 }
676 }
677
678 /**
679 * create an empty but initialized X.509 attribute certificate
680 */
681 static private_x509_ac_t *create_empty()
682 {
683 private_x509_ac_t *this = malloc_thing(private_x509_ac_t);
684
685 /* public functions */
686 this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
687 this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
688 this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
689 this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
690 this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
691 this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by;
692 this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
693 this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
694 this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
695 this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
696 this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
697 this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
698
699 /* initialize */
700 this->holderIssuer = NULL;
701 this->entityName = NULL;
702 this->issuerName = NULL;
703 this->authKeyIdentifier = NULL;
704 this->charging = linked_list_create();
705 this->groups = linked_list_create();
706
707 return this;
708 }
709
710 typedef struct private_builder_t private_builder_t;
711 /**
712 * Builder implementation for certificate loading
713 */
714 struct private_builder_t {
715 /** implements the builder interface */
716 builder_t public;
717 /** X.509 attribute certificate to build */
718 private_x509_ac_t *ac;
719 };
720
721 /**
722 * Implementation of builder_t.build
723 */
724 static x509_ac_t *build(private_builder_t *this)
725 {
726 private_x509_ac_t *ac;
727
728 ac = this->ac;
729 free(this);
730 if (ac->holder_cert && ac->signer_cert && ac->signer_key)
731 {
732 ac->encoding = build_ac(ac);
733 return &ac->public;
734 }
735 destroy(ac);
736 return NULL;
737 }
738
739 /**
740 * Implementation of builder_t.add
741 */
742 static void add(private_builder_t *this, builder_part_t part, ...)
743 {
744 va_list args;
745 certificate_t *cert;
746
747 va_start(args, part);
748 switch (part)
749 {
750 case BUILD_NOT_BEFORE_TIME:
751 this->ac->notBefore = *va_arg(args, time_t*);
752 break;
753 case BUILD_NOT_AFTER_TIME:
754 this->ac->notAfter = *va_arg(args, time_t*);
755 break;
756 case BUILD_CERT:
757 cert = va_arg(args, certificate_t*);
758 if (cert->get_type(cert) == CERT_X509)
759 {
760 this->ac->holder_cert = (x509_t*)cert;
761 }
762 else
763 {
764 cert->destroy(cert);
765 }
766 break;
767 case BUILD_SIGNING_CERT:
768 if (cert->get_type(cert) == CERT_X509)
769 {
770 this->ac->signer_cert = (x509_t*)cert;
771 }
772 else
773 {
774 cert->destroy(cert);
775 }
776 break;
777 case BUILD_SIGNING_KEY:
778 this->ac->signer_key = va_arg(args, private_key_t*);
779 break;
780 default:
781 DBG1("ignoring unsupported build part %N", builder_part_names, part);
782 break;
783 }
784 va_end(args);
785 }
786
787 /**
788 * Builder construction function
789 */
790 builder_t *x509_ac_builder(certificate_type_t type)
791 {
792 private_builder_t *this;
793
794 if (type != CERT_X509_AC)
795 {
796 return NULL;
797 }
798
799 this = malloc_thing(private_builder_t);
800
801 this->ac = create_empty();
802 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
803 this->public.build = (void*(*)(builder_t *this))build;
804
805 return &this->public;
806 }
807