42dbc94c239eeccbe39e9f50c6e8dba9827a2fae
[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 bool sigcheck)
719 {
720 public_key_t *key;
721 signature_scheme_t scheme;
722 bool valid;
723 x509_t *x509 = (x509_t*)issuer;
724
725 /* check if issuer is an X.509 AA certificate */
726 if (issuer->get_type(issuer) != CERT_X509)
727 {
728 return FALSE;
729 }
730 if (!(x509->get_flags(x509) & X509_AA))
731 {
732 return FALSE;
733 }
734
735 /* get the public key of the issuer */
736 key = issuer->get_public_key(issuer);
737
738 /* compare keyIdentifiers if available, otherwise use DNs */
739 if (this->authKeyIdentifier && key)
740 {
741 identification_t *subjectKeyIdentifier = key->get_id(key, ID_PUBKEY_SHA1);
742
743 if (!subjectKeyIdentifier->equals(subjectKeyIdentifier,
744 this->authKeyIdentifier))
745 {
746 return FALSE;
747 }
748 }
749 else
750 {
751 if (!this->issuerName->equals(this->issuerName, issuer->get_subject(issuer)))
752 {
753 return FALSE;
754 }
755 }
756
757 if (!sigcheck)
758 {
759 return TRUE;
760 }
761 /* TODO: generic OID to scheme mapper? */
762 switch (this->algorithm)
763 {
764 case OID_MD5_WITH_RSA:
765 scheme = SIGN_RSA_EMSA_PKCS1_MD5;
766 break;
767 case OID_SHA1_WITH_RSA:
768 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
769 break;
770 case OID_SHA256_WITH_RSA:
771 scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
772 break;
773 case OID_SHA384_WITH_RSA:
774 scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
775 break;
776 case OID_SHA512_WITH_RSA:
777 scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
778 break;
779 default:
780 return FALSE;
781 }
782 if (key == NULL)
783 {
784 return FALSE;
785 }
786 valid = key->verify(key, scheme, this->certificateInfo, this->signature);
787 key->destroy(key);
788 return valid;
789 }
790
791 /**
792 * Implementation of certificate_t.get_public_key.
793 */
794 static public_key_t* get_public_key(private_x509_ac_t *this)
795 {
796 return NULL;
797 }
798
799 /**
800 * Implementation of certificate_t.get_ref.
801 */
802 static private_x509_ac_t* get_ref(private_x509_ac_t *this)
803 {
804 ref_get(&this->ref);
805 return this;
806 }
807
808 /**
809 * Implementation of certificate_t.get_validity.
810 */
811 static bool get_validity(private_x509_ac_t *this, time_t *when,
812 time_t *not_before, time_t *not_after)
813 {
814 time_t t;
815
816 if (when)
817 {
818 t = *when;
819 }
820 else
821 {
822 t = time(NULL);
823 }
824 if (not_before)
825 {
826 *not_before = this->notBefore;
827 }
828 if (not_after)
829 {
830 *not_after = this->notAfter;
831 }
832 return (t >= this->notBefore && t <= this->notAfter);
833 }
834
835 /**
836 * Implementation of certificate_t.is_newer.
837 */
838 static bool is_newer(private_x509_ac_t *this, ac_t *that)
839 {
840 certificate_t *this_cert = &this->public.interface.certificate;
841 certificate_t *that_cert = &that->certificate;
842 time_t this_update, that_update, now = time(NULL);
843 bool new;
844
845 this_cert->get_validity(this_cert, &now, &this_update, NULL);
846 that_cert->get_validity(that_cert, &now, &that_update, NULL);
847 new = this_update > that_update;
848 DBG1(" attr cert from %#T is %s - existing attr_cert from %#T %s",
849 &this_update, FALSE, new ? "newer":"not newer",
850 &that_update, FALSE, new ? "replaced":"retained");
851 return new;
852 }
853
854 /**
855 * Implementation of certificate_t.get_encoding.
856 */
857 static chunk_t get_encoding(private_x509_ac_t *this)
858 {
859 return chunk_clone(this->encoding);
860 }
861
862 /**
863 * Implementation of certificate_t.equals.
864 */
865 static bool equals(private_x509_ac_t *this, certificate_t *other)
866 {
867 if ((certificate_t*)this == other)
868 {
869 return TRUE;
870 }
871 if (other->equals == (void*)equals)
872 { /* same implementation */
873 return chunk_equals(this->signature,
874 ((private_x509_ac_t*)other)->signature);
875 }
876 /* TODO: compare against other implementations */
877 return FALSE;
878 }
879
880 /**
881 * Implementation of x509_ac_t.destroy
882 */
883 static void destroy(private_x509_ac_t *this)
884 {
885 if (ref_put(&this->ref))
886 {
887 DESTROY_IF(this->holderIssuer);
888 DESTROY_IF(this->entityName);
889 DESTROY_IF(this->issuerName);
890 DESTROY_IF(this->authKeyIdentifier);
891 DESTROY_IF(this->holderCert);
892 DESTROY_IF(this->signerCert);
893 DESTROY_IF(this->signerKey);
894
895 ietfAttr_list_destroy(this->charging);
896 ietfAttr_list_destroy(this->groups);
897 free(this->encoding.ptr);
898 free(this);
899 }
900 }
901
902 /**
903 * create an empty but initialized X.509 attribute certificate
904 */
905 static private_x509_ac_t *create_empty(void)
906 {
907 private_x509_ac_t *this = malloc_thing(private_x509_ac_t);
908
909 /* public functions */
910 this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
911 this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
912 this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
913 this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
914 this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
915 this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by;
916 this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
917 this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
918 this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
919 this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
920 this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
921 this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
922 this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
923
924 /* initialize */
925 this->encoding = chunk_empty;
926 this->holderIssuer = NULL;
927 this->entityName = NULL;
928 this->issuerName = NULL;
929 this->authKeyIdentifier = NULL;
930 this->holderCert = NULL;
931 this->signerCert = NULL;
932 this->signerKey = NULL;
933 this->charging = linked_list_create();
934 this->groups = linked_list_create();
935 this->ref = 1;
936
937 return this;
938 }
939
940 /**
941 * create X.509 attribute certificate from a chunk
942 */
943 static private_x509_ac_t* create_from_chunk(chunk_t chunk)
944 {
945 private_x509_ac_t *this = create_empty();
946
947 this->encoding = chunk;
948 if (!parse_certificate(this))
949 {
950 destroy(this);
951 return NULL;
952 }
953 return this;
954 }
955
956 /**
957 * create X.509 crl from a file
958 */
959 static private_x509_ac_t* create_from_file(char *path)
960 {
961 bool pgp = FALSE;
962 chunk_t chunk;
963 private_x509_ac_t *this;
964
965 if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
966 {
967 return NULL;
968 }
969
970 this = create_from_chunk(chunk);
971
972 if (this == NULL)
973 {
974 DBG1(" could not parse loaded attribute certificate file '%s'", path);
975 return NULL;
976 }
977 DBG1(" loaded attribute certificate file '%s'", path);
978 return this;
979 }
980
981 typedef struct private_builder_t private_builder_t;
982 /**
983 * Builder implementation for certificate loading
984 */
985 struct private_builder_t {
986 /** implements the builder interface */
987 builder_t public;
988 /** X.509 attribute certificate to build */
989 private_x509_ac_t *ac;
990 };
991
992 /**
993 * Implementation of builder_t.build
994 */
995 static private_x509_ac_t* build(private_builder_t *this)
996 {
997 private_x509_ac_t *ac = this->ac;
998
999 free(this);
1000
1001 /* synthesis if TRUE or analysis if FALSE */
1002 if (ac->encoding.ptr == NULL)
1003 {
1004 if (ac->holderCert && ac->signerCert && ac->signerKey)
1005 {
1006 ac->encoding = build_ac(ac);
1007 return ac;
1008 }
1009 destroy(ac);
1010 return NULL;
1011 }
1012 else
1013 {
1014 return NULL;
1015 }
1016 }
1017
1018 /**
1019 * Implementation of builder_t.add
1020 */
1021 static void add(private_builder_t *this, builder_part_t part, ...)
1022 {
1023 va_list args;
1024 certificate_t *cert;
1025
1026 va_start(args, part);
1027 switch (part)
1028 {
1029 case BUILD_FROM_FILE:
1030 if (this->ac)
1031 {
1032 destroy(this->ac);
1033 }
1034 this->ac = create_from_file(va_arg(args, char*));
1035 break;
1036 case BUILD_BLOB_ASN1_DER:
1037 if (this->ac)
1038 {
1039 destroy(this->ac);
1040 }
1041 this->ac = create_from_chunk(va_arg(args, chunk_t));
1042 break;
1043 case BUILD_NOT_BEFORE_TIME:
1044 this->ac->notBefore = va_arg(args, time_t);
1045 break;
1046 case BUILD_NOT_AFTER_TIME:
1047 this->ac->notAfter = va_arg(args, time_t);
1048 break;
1049 case BUILD_SERIAL:
1050 this->ac->serialNumber = va_arg(args, chunk_t);
1051 break;
1052 case BUILD_IETF_GROUP_ATTR:
1053 ietfAttr_list_create_from_string(va_arg(args, char*),
1054 this->ac->groups);
1055 break;
1056 case BUILD_CERT:
1057 cert = va_arg(args, certificate_t*);
1058 if (cert->get_type(cert) == CERT_X509)
1059 {
1060 this->ac->holderCert = cert;
1061 }
1062 else
1063 {
1064 cert->destroy(cert);
1065 }
1066 break;
1067 case BUILD_SIGNING_CERT:
1068 cert = va_arg(args, certificate_t*);
1069 if (cert->get_type(cert) == CERT_X509)
1070 {
1071 this->ac->signerCert = cert;
1072 }
1073 else
1074 {
1075 cert->destroy(cert);
1076 }
1077 break;
1078 case BUILD_SIGNING_KEY:
1079 this->ac->signerKey = va_arg(args, private_key_t*);
1080 break;
1081 default:
1082 DBG1("ignoring unsupported build part %N", builder_part_names, part);
1083 break;
1084 }
1085 va_end(args);
1086 }
1087
1088 /**
1089 * Builder construction function
1090 */
1091 builder_t *x509_ac_builder(certificate_type_t type)
1092 {
1093 private_builder_t *this;
1094
1095 if (type != CERT_X509_AC)
1096 {
1097 return NULL;
1098 }
1099
1100 this = malloc_thing(private_builder_t);
1101
1102 this->ac = create_empty();
1103 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
1104 this->public.build = (void*(*)(builder_t *this))build;
1105
1106 return &this->public;
1107 }
1108