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