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