caching of ocsp responses (experimental), no crl caching yet
[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 <asn1/pem.h>
29 #include <utils/identification.h>
30 #include <utils/linked_list.h>
31 #include <credentials/certificates/x509.h>
32
33 extern identification_t* x509_parse_authorityKeyIdentifier(chunk_t blob,
34 int level0, chunk_t *authKeySerialNumber);
35
36 typedef struct private_x509_ac_t private_x509_ac_t;
37
38 /**
39 * private data of x509_ac_t object
40 */
41 struct private_x509_ac_t {
42
43 /**
44 * public functions
45 */
46 x509_ac_t public;
47
48 /**
49 * X.509 attribute certificate encoding in ASN.1 DER format
50 */
51 chunk_t encoding;
52
53 /**
54 * X.509 attribute certificate body over which signature is computed
55 */
56 chunk_t certificateInfo;
57
58 /**
59 * Version of the X.509 attribute certificate
60 */
61 u_int version;
62
63 /**
64 * Serial number of the X.509 attribute certificate
65 */
66 chunk_t serialNumber;
67
68 /**
69 * ID representing the issuer of the holder certificate
70 */
71 identification_t *holderIssuer;
72
73 /**
74 * Serial number of the holder certificate
75 */
76 chunk_t holderSerial;
77
78 /**
79 * ID representing the holder
80 */
81 identification_t *entityName;
82
83 /**
84 * ID representing the attribute certificate issuer
85 */
86 identification_t *issuerName;
87
88 /**
89 * Start time of certificate validity
90 */
91 time_t notBefore;
92
93 /**
94 * End time of certificate validity
95 */
96 time_t notAfter;
97
98 /**
99 * List of charging attributes
100 */
101 linked_list_t *charging;
102
103 /**
104 * List of groub attributes
105 */
106 linked_list_t *groups;
107
108 /**
109 * Authority Key Identifier
110 */
111 identification_t *authKeyIdentifier;
112
113 /**
114 * Authority Key Serial Number
115 */
116 chunk_t authKeySerialNumber;
117
118 /**
119 * No revocation information available
120 */
121 bool noRevAvail;
122
123 /**
124 * Signature algorithm
125 */
126 int algorithm;
127
128 /**
129 * Signature
130 */
131 chunk_t signature;
132
133 /**
134 * Holder certificate
135 */
136 certificate_t *holderCert;
137
138 /**
139 * Signer certificate
140 */
141 certificate_t *signerCert;
142
143 /**
144 * Signer private key;
145 */
146 private_key_t *signerKey;
147
148 /**
149 * reference count
150 */
151 refcount_t ref;
152 };
153
154 static u_char ASN1_group_oid_str[] = {
155 0x06, 0x08,
156 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
157 };
158
159 static const chunk_t ASN1_group_oid = chunk_from_buf(ASN1_group_oid_str);
160
161 static u_char ASN1_authorityKeyIdentifier_oid_str[] = {
162 0x06, 0x03,
163 0x55, 0x1d, 0x23
164 };
165
166 static const chunk_t ASN1_authorityKeyIdentifier_oid =
167 chunk_from_buf(ASN1_authorityKeyIdentifier_oid_str);
168
169 static u_char ASN1_noRevAvail_ext_str[] = {
170 0x30, 0x09,
171 0x06, 0x03,
172 0x55, 0x1d, 0x38,
173 0x04, 0x02,
174 0x05, 0x00
175 };
176
177 static const chunk_t ASN1_noRevAvail_ext = chunk_from_buf(ASN1_noRevAvail_ext_str);
178
179 /**
180 * ASN.1 definition of roleSyntax
181 */
182 static const asn1Object_t roleSyntaxObjects[] =
183 {
184 { 0, "roleSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
185 { 1, "roleAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
186 ASN1_OBJ }, /* 1 */
187 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
188 { 1, "roleName", ASN1_CONTEXT_C_1, ASN1_OBJ } /* 3 */
189 };
190
191 #define ROLE_ROOF 4
192
193 /**
194 * ASN.1 definition of an X509 attribute certificate
195 */
196 static const asn1Object_t acObjects[] =
197 {
198 { 0, "AttributeCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
199 { 1, "AttributeCertificateInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
200 { 2, "version", ASN1_INTEGER, ASN1_DEF |
201 ASN1_BODY }, /* 2 */
202 { 2, "holder", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
203 { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */
204 { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
205 { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 6 */
206 { 4, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
207 ASN1_BODY }, /* 7 */
208 { 4, "end opt", ASN1_EOC, ASN1_END }, /* 8 */
209 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
210 { 3, "entityName", ASN1_CONTEXT_C_1, ASN1_OPT |
211 ASN1_OBJ }, /* 10 */
212 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
213 { 3, "objectDigestInfo", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 12 */
214 { 4, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 13*/
215 { 4, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
216 ASN1_BODY }, /* 14 */
217 { 4, "end opt", ASN1_EOC, ASN1_END }, /* 15*/
218 { 4, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 16 */
219 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 17 */
220 { 2, "v2Form", ASN1_CONTEXT_C_0, ASN1_NONE }, /* 18 */
221 { 3, "issuerName", ASN1_SEQUENCE, ASN1_OPT |
222 ASN1_OBJ }, /* 19 */
223 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
224 { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */
225 { 4, "issuerSerial", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
226 { 5, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 23 */
227 { 5, "serial", ASN1_INTEGER, ASN1_BODY }, /* 24 */
228 { 5, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
229 ASN1_BODY }, /* 25 */
230 { 5, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
231 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
232 { 3, "objectDigestInfo", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 28 */
233 { 4, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 29 */
234 { 5, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 30 */
235 { 5, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
236 ASN1_BODY }, /* 31 */
237 { 5, "end opt", ASN1_EOC, ASN1_END }, /* 32 */
238 { 5, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 33 */
239 { 3, "end opt", ASN1_EOC, ASN1_END }, /* 34 */
240 { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 35 */
241 { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 36 */
242 { 2, "attrCertValidityPeriod", ASN1_SEQUENCE, ASN1_NONE }, /* 37 */
243 { 3, "notBeforeTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
244 { 3, "notAfterTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
245 { 2, "attributes", ASN1_SEQUENCE, ASN1_LOOP }, /* 40 */
246 { 3, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 41 */
247 { 4, "type", ASN1_OID, ASN1_BODY }, /* 42 */
248 { 4, "values", ASN1_SET, ASN1_LOOP }, /* 43 */
249 { 5, "value", ASN1_EOC, ASN1_RAW }, /* 44 */
250 { 4, "end loop", ASN1_EOC, ASN1_END }, /* 45 */
251 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 46 */
252 { 2, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 47 */
253 { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 48 */
254 { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 49 */
255 { 4, "critical", ASN1_BOOLEAN, ASN1_DEF |
256 ASN1_BODY }, /* 50 */
257 { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 51 */
258 { 2, "end loop", ASN1_EOC, ASN1_END }, /* 52 */
259 { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 53 */
260 { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 54 */
261 };
262
263 #define AC_OBJ_CERTIFICATE_INFO 1
264 #define AC_OBJ_VERSION 2
265 #define AC_OBJ_HOLDER_ISSUER 5
266 #define AC_OBJ_HOLDER_SERIAL 6
267 #define AC_OBJ_ENTITY_NAME 10
268 #define AC_OBJ_ISSUER_NAME 19
269 #define AC_OBJ_ISSUER 23
270 #define AC_OBJ_SIG_ALG 35
271 #define AC_OBJ_SERIAL_NUMBER 36
272 #define AC_OBJ_NOT_BEFORE 38
273 #define AC_OBJ_NOT_AFTER 39
274 #define AC_OBJ_ATTRIBUTE_TYPE 42
275 #define AC_OBJ_ATTRIBUTE_VALUE 44
276 #define AC_OBJ_EXTN_ID 49
277 #define AC_OBJ_CRITICAL 50
278 #define AC_OBJ_EXTN_VALUE 51
279 #define AC_OBJ_ALGORITHM 53
280 #define AC_OBJ_SIGNATURE 54
281 #define AC_OBJ_ROOF 55
282
283 /**
284 * declaration of function implemented in x509_cert.c
285 */
286 extern void x509_parse_generalNames(chunk_t blob, int level0, bool implicit,
287 linked_list_t *list);
288 /**
289 * parses a directoryName
290 */
291 static bool parse_directoryName(chunk_t blob, int level, bool implicit, identification_t **name)
292 {
293 bool has_directoryName;
294 linked_list_t *list = linked_list_create();
295
296 x509_parse_generalNames(blob, level, implicit, list);
297 has_directoryName = list->get_count(list) > 0;
298
299 if (has_directoryName)
300 {
301 iterator_t *iterator = list->create_iterator(list, TRUE);
302 identification_t *directoryName;
303 bool first = TRUE;
304
305 while (iterator->iterate(iterator, (void**)&directoryName))
306 {
307 if (first)
308 {
309 *name = directoryName;
310 first = FALSE;
311 }
312 else
313 {
314 DBG1("more than one directory name - first selected");
315 directoryName->destroy(directoryName);
316 }
317 }
318 iterator->destroy(iterator);
319 }
320 else
321 {
322 DBG1("no directoryName found");
323 }
324
325 list->destroy(list);
326 return has_directoryName;
327 }
328
329 /**
330 * parses roleSyntax
331 */
332 static void parse_roleSyntax(chunk_t blob, int level0)
333 {
334 asn1_ctx_t ctx;
335 chunk_t object;
336 u_int level;
337 int objectID = 0;
338
339 asn1_init(&ctx, blob, level0, FALSE, FALSE);
340 while (objectID < ROLE_ROOF)
341 {
342 if (!extract_object(roleSyntaxObjects, &objectID, &object, &level, &ctx))
343 {
344 return;
345 }
346
347 switch (objectID)
348 {
349 default:
350 break;
351 }
352 objectID++;
353 }
354 }
355
356 /**
357 * Parses an X.509 attribute certificate
358 */
359 static bool parse_certificate(private_x509_ac_t *this)
360 {
361 asn1_ctx_t ctx;
362 bool critical;
363 chunk_t object;
364 u_int level;
365 int objectID = 0;
366 int type = OID_UNKNOWN;
367 int extn_oid = OID_UNKNOWN;
368 int sig_alg = OID_UNKNOWN;
369
370 asn1_init(&ctx, this->encoding, 0, FALSE, FALSE);
371 while (objectID < AC_OBJ_ROOF)
372 {
373 if (!extract_object(acObjects, &objectID, &object, &level, &ctx))
374 {
375 return FALSE;
376 }
377
378 /* those objects which will parsed further need the next higher level */
379 level++;
380
381 switch (objectID)
382 {
383 case AC_OBJ_CERTIFICATE_INFO:
384 this->certificateInfo = object;
385 break;
386 case AC_OBJ_VERSION:
387 this->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
388 DBG2(" v%d", this->version);
389 if (this->version != 2)
390 {
391 DBG1("v%d attribute certificates are not supported", this->version);
392 return FALSE;
393 }
394 break;
395 case AC_OBJ_HOLDER_ISSUER:
396 if (!parse_directoryName(object, level, FALSE, &this->holderIssuer))
397 {
398 return FALSE;
399 }
400 break;
401 case AC_OBJ_HOLDER_SERIAL:
402 this->holderSerial = object;
403 break;
404 case AC_OBJ_ENTITY_NAME:
405 if (!parse_directoryName(object, level, TRUE, &this->entityName))
406 {
407 return FALSE;
408 }
409 break;
410 case AC_OBJ_ISSUER_NAME:
411 if (!parse_directoryName(object, level, FALSE, &this->issuerName))
412 {
413 return FALSE;
414 }
415 break;
416 case AC_OBJ_SIG_ALG:
417 sig_alg = parse_algorithmIdentifier(object, level, NULL);
418 break;
419 case AC_OBJ_SERIAL_NUMBER:
420 this->serialNumber = object;
421 break;
422 case AC_OBJ_NOT_BEFORE:
423 this->notBefore = asn1totime(&object, ASN1_GENERALIZEDTIME);
424 break;
425 case AC_OBJ_NOT_AFTER:
426 this->notAfter = asn1totime(&object, ASN1_GENERALIZEDTIME);
427 break;
428 case AC_OBJ_ATTRIBUTE_TYPE:
429 type = known_oid(object);
430 break;
431 case AC_OBJ_ATTRIBUTE_VALUE:
432 {
433 switch (type)
434 {
435 case OID_AUTHENTICATION_INFO:
436 DBG2(" need to parse authenticationInfo");
437 break;
438 case OID_ACCESS_IDENTITY:
439 DBG2(" need to parse accessIdentity");
440 break;
441 case OID_CHARGING_IDENTITY:
442 ietfAttr_list_create_from_chunk(object, this->charging, level);
443 break;
444 case OID_GROUP:
445 ietfAttr_list_create_from_chunk(object, this->groups, level);
446 break;
447 case OID_ROLE:
448 parse_roleSyntax(object, level);
449 break;
450 default:
451 break;
452 }
453 }
454 break;
455 case AC_OBJ_EXTN_ID:
456 extn_oid = known_oid(object);
457 break;
458 case AC_OBJ_CRITICAL:
459 critical = object.len && *object.ptr;
460 DBG2(" %s",(critical)?"TRUE":"FALSE");
461 break;
462 case AC_OBJ_EXTN_VALUE:
463 {
464 switch (extn_oid)
465 {
466 case OID_CRL_DISTRIBUTION_POINTS:
467 DBG2(" need to parse crlDistributionPoints");
468 break;
469 case OID_AUTHORITY_KEY_ID:
470 this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
471 level, &this->authKeySerialNumber);
472 break;
473 break;
474 case OID_TARGET_INFORMATION:
475 DBG2(" need to parse targetInformation");
476 break;
477 case OID_NO_REV_AVAIL:
478 this->noRevAvail = TRUE;
479 break;
480 default:
481 break;
482 }
483 }
484 break;
485 case AC_OBJ_ALGORITHM:
486 this->algorithm = parse_algorithmIdentifier(object, level, NULL);
487 if (this->algorithm != sig_alg)
488 {
489 DBG1(" signature algorithms do not agree");
490 return FALSE;
491 }
492 break;
493 case AC_OBJ_SIGNATURE:
494 this->signature = object;
495 break;
496 default:
497 break;
498 }
499 objectID++;
500 }
501 return TRUE;
502 }
503
504 /**
505 * build directoryName
506 */
507 static chunk_t build_directoryName(asn1_t tag, chunk_t name)
508 {
509 return asn1_wrap(tag, "m",
510 asn1_simple_object(ASN1_CONTEXT_C_4, name));
511 }
512
513 /**
514 * build holder
515 */
516 static chunk_t build_holder(private_x509_ac_t *this)
517 {
518 x509_t* x509 = (x509_t*)this->holderCert;
519 identification_t *issuer = this->holderCert->get_issuer(this->holderCert);
520 identification_t *subject = this->holderCert->get_subject(this->holderCert);
521
522 return asn1_wrap(ASN1_SEQUENCE, "mm",
523 asn1_wrap(ASN1_CONTEXT_C_0, "mm",
524 build_directoryName(ASN1_SEQUENCE, issuer->get_encoding(issuer)),
525 asn1_simple_object(ASN1_INTEGER, x509->get_serial(x509))
526 ),
527 build_directoryName(ASN1_CONTEXT_C_1, subject->get_encoding(subject)));
528 }
529
530 /**
531 * build v2Form
532 */
533 static chunk_t build_v2_form(private_x509_ac_t *this)
534 {
535 identification_t *subject = this->signerCert->get_subject(this->signerCert);
536
537 return asn1_wrap(ASN1_CONTEXT_C_0, "m",
538 build_directoryName(ASN1_SEQUENCE, subject->get_encoding(subject)));
539 }
540
541 /**
542 * build attrCertValidityPeriod
543 */
544 static chunk_t build_attr_cert_validity(private_x509_ac_t *this)
545 {
546 return asn1_wrap(ASN1_SEQUENCE, "mm",
547 timetoasn1(&this->notBefore, ASN1_GENERALIZEDTIME),
548 timetoasn1(&this->notAfter, ASN1_GENERALIZEDTIME));
549 }
550
551
552 /**
553 * build attribute type
554 */
555 static chunk_t build_attribute_type(const chunk_t type, chunk_t content)
556 {
557 return asn1_wrap(ASN1_SEQUENCE, "cm",
558 type,
559 asn1_wrap(ASN1_SET, "m", content));
560 }
561
562 /**
563 * build attributes
564 */
565 static chunk_t build_attributes(private_x509_ac_t *this)
566 {
567 return asn1_wrap(ASN1_SEQUENCE, "m",
568 build_attribute_type(ASN1_group_oid, ietfAttr_list_encode(this->groups)));
569 }
570
571 /**
572 * build authorityKeyIdentifier
573 */
574 static chunk_t build_authorityKeyIdentifier(private_x509_ac_t *this)
575 {
576 chunk_t keyIdentifier;
577 chunk_t authorityCertIssuer;
578 chunk_t authorityCertSerialNumber;
579 x509_t *x509 = (x509_t*)this->signerCert;
580 identification_t *issuer = this->signerCert->get_issuer(this->signerCert);
581 public_key_t *public = this->signerCert->get_public_key(this->signerCert);
582
583 if (public)
584 {
585 identification_t *keyid = public->get_id(public, ID_PUBKEY_SHA1);
586
587 this->authKeyIdentifier = keyid = keyid->clone(keyid);
588 keyIdentifier = keyid->get_encoding(keyid);
589 public->destroy(public);
590 }
591 else
592 {
593 keyIdentifier = chunk_empty;
594 }
595 authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1,
596 issuer->get_encoding(issuer));
597 authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2,
598 x509->get_serial(x509));
599 return asn1_wrap(ASN1_SEQUENCE, "cm",
600 ASN1_authorityKeyIdentifier_oid,
601 asn1_wrap(ASN1_OCTET_STRING, "m",
602 asn1_wrap(ASN1_SEQUENCE, "cmm",
603 keyIdentifier,
604 authorityCertIssuer,
605 authorityCertSerialNumber
606 )
607 )
608 );
609 }
610
611 /**
612 * build extensions
613 */
614 static chunk_t build_extensions(private_x509_ac_t *this)
615 {
616 return asn1_wrap(ASN1_SEQUENCE, "mc",
617 build_authorityKeyIdentifier(this),
618 ASN1_noRevAvail_ext);
619 }
620
621 /**
622 * build attributeCertificateInfo
623 */
624 static chunk_t build_attr_cert_info(private_x509_ac_t *this)
625 {
626 return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm",
627 ASN1_INTEGER_1,
628 build_holder(this),
629 build_v2_form(this),
630 asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
631 asn1_simple_object(ASN1_INTEGER, this->serialNumber),
632 build_attr_cert_validity(this),
633 build_attributes(this),
634 build_extensions(this));
635 }
636
637
638 /**
639 * build an X.509 attribute certificate
640 */
641 static chunk_t build_ac(private_x509_ac_t *this)
642 {
643 chunk_t signatureValue;
644 chunk_t attributeCertificateInfo;
645
646 attributeCertificateInfo = build_attr_cert_info(this);
647
648 this->signerKey->sign(this->signerKey, SIGN_RSA_EMSA_PKCS1_SHA1,
649 attributeCertificateInfo, &signatureValue);
650
651 return asn1_wrap(ASN1_SEQUENCE, "mcm",
652 attributeCertificateInfo,
653 asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
654 asn1_bitstring("m", signatureValue));
655 }
656
657 /**
658 * Implementation of certificate_t.get_type
659 */
660 static certificate_type_t get_type(private_x509_ac_t *this)
661 {
662 return CERT_X509_AC;
663 }
664
665 /**
666 * Implementation of certificate_t.get_subject
667 */
668 static identification_t* get_subject(private_x509_ac_t *this)
669 {
670 return this->entityName;
671 }
672
673 /**
674 * Implementation of certificate_t.get_issuer
675 */
676 static identification_t* get_issuer(private_x509_ac_t *this)
677 {
678 return this->issuerName;
679 }
680
681 /**
682 * Implementation of certificate_t.has_subject.
683 */
684 static id_match_t has_subject(private_x509_ac_t *this, identification_t *subject)
685 {
686 return ID_MATCH_NONE;
687 }
688
689 /**
690 * Implementation of certificate_t.has_issuer.
691 */
692 static id_match_t has_issuer(private_x509_ac_t *this, identification_t *issuer)
693 {
694 id_match_t match;
695
696 if (issuer->get_type(issuer) == ID_PUBKEY_SHA1)
697 {
698 if (this->authKeyIdentifier)
699 {
700 match = issuer->matches(issuer, this->authKeyIdentifier);
701 }
702 else
703 {
704 match = ID_MATCH_NONE;
705 }
706 }
707 else
708 {
709 match = this->issuerName->matches(this->issuerName, issuer);
710 }
711 return match;
712 }
713
714 /**
715 * Implementation of certificate_t.issued_by
716 */
717 static bool issued_by(private_x509_ac_t *this, certificate_t *issuer)
718 {
719 public_key_t *key;
720 signature_scheme_t scheme;
721 bool valid;
722 x509_t *x509 = (x509_t*)issuer;
723
724 /* check if issuer is an X.509 AA certificate */
725 if (issuer->get_type(issuer) != CERT_X509)
726 {
727 return FALSE;
728 }
729 if (!(x509->get_flags(x509) & X509_AA))
730 {
731 return FALSE;
732 }
733
734 /* get the public key of the issuer */
735 key = issuer->get_public_key(issuer);
736
737 /* compare keyIdentifiers if available, otherwise use DNs */
738 if (this->authKeyIdentifier && key)
739 {
740 identification_t *subjectKeyIdentifier = key->get_id(key, ID_PUBKEY_SHA1);
741
742 if (!subjectKeyIdentifier->equals(subjectKeyIdentifier,
743 this->authKeyIdentifier))
744 {
745 return FALSE;
746 }
747 }
748 else
749 {
750 if (!this->issuerName->equals(this->issuerName, issuer->get_subject(issuer)))
751 {
752 return FALSE;
753 }
754 }
755 /* TODO: generic OID to scheme mapper? */
756 switch (this->algorithm)
757 {
758 case OID_MD5_WITH_RSA:
759 scheme = SIGN_RSA_EMSA_PKCS1_MD5;
760 break;
761 case OID_SHA1_WITH_RSA:
762 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
763 break;
764 case OID_SHA256_WITH_RSA:
765 scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
766 break;
767 case OID_SHA384_WITH_RSA:
768 scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
769 break;
770 case OID_SHA512_WITH_RSA:
771 scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
772 break;
773 default:
774 return FALSE;
775 }
776 if (key == NULL)
777 {
778 return FALSE;
779 }
780 valid = key->verify(key, scheme, this->certificateInfo, this->signature);
781 key->destroy(key);
782 return valid;
783 }
784
785 /**
786 * Implementation of certificate_t.get_public_key.
787 */
788 static public_key_t* get_public_key(private_x509_ac_t *this)
789 {
790 return NULL;
791 }
792
793 /**
794 * Implementation of certificate_t.get_ref.
795 */
796 static private_x509_ac_t* get_ref(private_x509_ac_t *this)
797 {
798 ref_get(&this->ref);
799 return this;
800 }
801
802 /**
803 * Implementation of certificate_t.get_validity.
804 */
805 static bool get_validity(private_x509_ac_t *this, time_t *when,
806 time_t *not_before, time_t *not_after)
807 {
808 time_t t;
809
810 if (when)
811 {
812 t = *when;
813 }
814 else
815 {
816 t = time(NULL);
817 }
818 if (not_before)
819 {
820 *not_before = this->notBefore;
821 }
822 if (not_after)
823 {
824 *not_after = this->notAfter;
825 }
826 return (t >= this->notBefore && t <= this->notAfter);
827 }
828
829 /**
830 * Implementation of certificate_t.is_newer.
831 */
832 static bool is_newer(private_x509_ac_t *this, ac_t *that)
833 {
834 certificate_t *this_cert = &this->public.interface.certificate;
835 certificate_t *that_cert = &that->certificate;
836 time_t this_update, that_update, now = time(NULL);
837 bool new;
838
839 this_cert->get_validity(this_cert, &now, &this_update, NULL);
840 that_cert->get_validity(that_cert, &now, &that_update, NULL);
841 new = this_update > that_update;
842 DBG1(" attr cert from %#T is %s - existing attr_cert from %#T %s",
843 &this_update, FALSE, new ? "newer":"not newer",
844 &that_update, FALSE, new ? "replaced":"retained");
845 return new;
846 }
847
848 /**
849 * Implementation of certificate_t.get_encoding.
850 */
851 static chunk_t get_encoding(private_x509_ac_t *this)
852 {
853 return chunk_clone(this->encoding);
854 }
855
856 /**
857 * Implementation of certificate_t.equals.
858 */
859 static bool equals(private_x509_ac_t *this, certificate_t *other)
860 {
861 if ((certificate_t*)this == other)
862 {
863 return TRUE;
864 }
865 if (other->equals == (void*)equals)
866 { /* same implementation */
867 return chunk_equals(this->signature,
868 ((private_x509_ac_t*)other)->signature);
869 }
870 /* TODO: compare against other implementations */
871 return FALSE;
872 }
873
874 /**
875 * Implementation of x509_ac_t.destroy
876 */
877 static void destroy(private_x509_ac_t *this)
878 {
879 if (ref_put(&this->ref))
880 {
881 DESTROY_IF(this->holderIssuer);
882 DESTROY_IF(this->entityName);
883 DESTROY_IF(this->issuerName);
884 DESTROY_IF(this->authKeyIdentifier);
885 DESTROY_IF(this->holderCert);
886 DESTROY_IF(this->signerCert);
887 DESTROY_IF(this->signerKey);
888
889 ietfAttr_list_destroy(this->charging);
890 ietfAttr_list_destroy(this->groups);
891 free(this->encoding.ptr);
892 free(this);
893 }
894 }
895
896 /**
897 * create an empty but initialized X.509 attribute certificate
898 */
899 static private_x509_ac_t *create_empty(void)
900 {
901 private_x509_ac_t *this = malloc_thing(private_x509_ac_t);
902
903 /* public functions */
904 this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
905 this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
906 this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
907 this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
908 this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
909 this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
910 this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
911 this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
912 this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
913 this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
914 this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
915 this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
916 this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
917
918 /* initialize */
919 this->encoding = chunk_empty;
920 this->holderIssuer = NULL;
921 this->entityName = NULL;
922 this->issuerName = NULL;
923 this->authKeyIdentifier = NULL;
924 this->holderCert = NULL;
925 this->signerCert = NULL;
926 this->signerKey = NULL;
927 this->charging = linked_list_create();
928 this->groups = linked_list_create();
929 this->ref = 1;
930
931 return this;
932 }
933
934 /**
935 * create X.509 attribute certificate from a chunk
936 */
937 static private_x509_ac_t* create_from_chunk(chunk_t chunk)
938 {
939 private_x509_ac_t *this = create_empty();
940
941 this->encoding = chunk;
942 if (!parse_certificate(this))
943 {
944 destroy(this);
945 return NULL;
946 }
947 return this;
948 }
949
950 /**
951 * create X.509 crl from a file
952 */
953 static private_x509_ac_t* create_from_file(char *path)
954 {
955 bool pgp = FALSE;
956 chunk_t chunk;
957 private_x509_ac_t *this;
958
959 if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
960 {
961 return NULL;
962 }
963
964 this = create_from_chunk(chunk);
965
966 if (this == NULL)
967 {
968 DBG1(" could not parse loaded attribute certificate file '%s'", path);
969 return NULL;
970 }
971 DBG1(" loaded attribute certificate file '%s'", path);
972 return this;
973 }
974
975 typedef struct private_builder_t private_builder_t;
976 /**
977 * Builder implementation for certificate loading
978 */
979 struct private_builder_t {
980 /** implements the builder interface */
981 builder_t public;
982 /** X.509 attribute certificate to build */
983 private_x509_ac_t *ac;
984 };
985
986 /**
987 * Implementation of builder_t.build
988 */
989 static private_x509_ac_t* build(private_builder_t *this)
990 {
991 private_x509_ac_t *ac = this->ac;
992
993 free(this);
994
995 /* synthesis if TRUE or analysis if FALSE */
996 if (ac->encoding.ptr == NULL)
997 {
998 if (ac->holderCert && ac->signerCert && ac->signerKey)
999 {
1000 ac->encoding = build_ac(ac);
1001 return ac;
1002 }
1003 destroy(ac);
1004 return NULL;
1005 }
1006 else
1007 {
1008 return NULL;
1009 }
1010 }
1011
1012 /**
1013 * Implementation of builder_t.add
1014 */
1015 static void add(private_builder_t *this, builder_part_t part, ...)
1016 {
1017 va_list args;
1018 certificate_t *cert;
1019
1020 va_start(args, part);
1021 switch (part)
1022 {
1023 case BUILD_FROM_FILE:
1024 if (this->ac)
1025 {
1026 destroy(this->ac);
1027 }
1028 this->ac = create_from_file(va_arg(args, char*));
1029 break;
1030 case BUILD_BLOB_ASN1_DER:
1031 if (this->ac)
1032 {
1033 destroy(this->ac);
1034 }
1035 this->ac = create_from_chunk(va_arg(args, chunk_t));
1036 break;
1037 case BUILD_NOT_BEFORE_TIME:
1038 this->ac->notBefore = va_arg(args, time_t);
1039 break;
1040 case BUILD_NOT_AFTER_TIME:
1041 this->ac->notAfter = va_arg(args, time_t);
1042 break;
1043 case BUILD_SERIAL:
1044 this->ac->serialNumber = va_arg(args, chunk_t);
1045 break;
1046 case BUILD_IETF_GROUP_ATTR:
1047 ietfAttr_list_create_from_string(va_arg(args, char*),
1048 this->ac->groups);
1049 break;
1050 case BUILD_CERT:
1051 cert = va_arg(args, certificate_t*);
1052 if (cert->get_type(cert) == CERT_X509)
1053 {
1054 this->ac->holderCert = cert;
1055 }
1056 else
1057 {
1058 cert->destroy(cert);
1059 }
1060 break;
1061 case BUILD_SIGNING_CERT:
1062 cert = va_arg(args, certificate_t*);
1063 if (cert->get_type(cert) == CERT_X509)
1064 {
1065 this->ac->signerCert = cert;
1066 }
1067 else
1068 {
1069 cert->destroy(cert);
1070 }
1071 break;
1072 case BUILD_SIGNING_KEY:
1073 this->ac->signerKey = va_arg(args, private_key_t*);
1074 break;
1075 default:
1076 DBG1("ignoring unsupported build part %N", builder_part_names, part);
1077 break;
1078 }
1079 va_end(args);
1080 }
1081
1082 /**
1083 * Builder construction function
1084 */
1085 builder_t *x509_ac_builder(certificate_type_t type)
1086 {
1087 private_builder_t *this;
1088
1089 if (type != CERT_X509_AC)
1090 {
1091 return NULL;
1092 }
1093
1094 this = malloc_thing(private_builder_t);
1095
1096 this->ac = create_empty();
1097 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
1098 this->public.build = (void*(*)(builder_t *this))build;
1099
1100 return &this->public;
1101 }
1102