2 * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
3 * Copyright (C) 2003 Martin Berner, Lukas Suter
4 * Copyright (C) 2002-2008 Andreas Steffen
6 * Hochschule fuer Technik Rapperswil
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>.
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
22 #include "ietf_attr_list.h"
29 #include <asn1/asn1.h>
30 #include <asn1/asn1_parser.h>
32 #include <utils/identification.h>
33 #include <utils/linked_list.h>
34 #include <credentials/certificates/x509.h>
36 extern identification_t
* x509_parse_authorityKeyIdentifier(chunk_t blob
,
37 int level0
, chunk_t
*authKeySerialNumber
);
39 typedef struct private_x509_ac_t private_x509_ac_t
;
42 * private data of x509_ac_t object
44 struct private_x509_ac_t
{
52 * X.509 attribute certificate encoding in ASN.1 DER format
57 * X.509 attribute certificate body over which signature is computed
59 chunk_t certificateInfo
;
62 * Version of the X.509 attribute certificate
67 * Serial number of the X.509 attribute certificate
72 * ID representing the issuer of the holder certificate
74 identification_t
*holderIssuer
;
77 * Serial number of the holder certificate
82 * ID representing the holder
84 identification_t
*entityName
;
87 * ID representing the attribute certificate issuer
89 identification_t
*issuerName
;
92 * Start time of certificate validity
97 * End time of certificate validity
102 * List of charging attributes
104 linked_list_t
*charging
;
107 * List of groub attributes
109 linked_list_t
*groups
;
112 * Authority Key Identifier
114 identification_t
*authKeyIdentifier
;
117 * Authority Key Serial Number
119 chunk_t authKeySerialNumber
;
122 * No revocation information available
127 * Signature algorithm
139 certificate_t
*holderCert
;
144 certificate_t
*signerCert
;
147 * Signer private key;
149 private_key_t
*signerKey
;
157 static u_char ASN1_group_oid_str
[] = {
159 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
162 static const chunk_t ASN1_group_oid
= chunk_from_buf(ASN1_group_oid_str
);
164 static u_char ASN1_authorityKeyIdentifier_oid_str
[] = {
169 static const chunk_t ASN1_authorityKeyIdentifier_oid
=
170 chunk_from_buf(ASN1_authorityKeyIdentifier_oid_str
);
172 static u_char ASN1_noRevAvail_ext_str
[] = {
180 static const chunk_t ASN1_noRevAvail_ext
= chunk_from_buf(ASN1_noRevAvail_ext_str
);
183 * declaration of function implemented in x509_cert.c
185 extern void x509_parse_generalNames(chunk_t blob
, int level0
, bool implicit
,
186 linked_list_t
*list
);
188 * parses a directoryName
190 static bool parse_directoryName(chunk_t blob
, int level
, bool implicit
, identification_t
**name
)
192 bool has_directoryName
;
193 linked_list_t
*list
= linked_list_create();
195 x509_parse_generalNames(blob
, level
, implicit
, list
);
196 has_directoryName
= list
->get_count(list
) > 0;
198 if (has_directoryName
)
200 iterator_t
*iterator
= list
->create_iterator(list
, TRUE
);
201 identification_t
*directoryName
;
204 while (iterator
->iterate(iterator
, (void**)&directoryName
))
208 *name
= directoryName
;
213 DBG1("more than one directory name - first selected");
214 directoryName
->destroy(directoryName
);
217 iterator
->destroy(iterator
);
221 DBG1("no directoryName found");
225 return has_directoryName
;
229 * ASN.1 definition of roleSyntax
231 static const asn1Object_t roleSyntaxObjects
[] =
233 { 0, "roleSyntax", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
234 { 1, "roleAuthority", ASN1_CONTEXT_C_0
, ASN1_OPT
|
236 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 2 */
237 { 1, "roleName", ASN1_CONTEXT_C_1
, ASN1_OBJ
}, /* 3 */
238 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
244 static void parse_roleSyntax(chunk_t blob
, int level0
)
246 asn1_parser_t
*parser
;
250 parser
= asn1_parser_create(roleSyntaxObjects
, blob
);
251 parser
->set_top_level(parser
, level0
);
253 while (parser
->iterate(parser
, &objectID
, &object
))
261 parser
->destroy(parser
);
265 * ASN.1 definition of an X509 attribute certificate
267 static const asn1Object_t acObjects
[] =
269 { 0, "AttributeCertificate", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 0 */
270 { 1, "AttributeCertificateInfo", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 1 */
271 { 2, "version", ASN1_INTEGER
, ASN1_DEF
|
273 { 2, "holder", ASN1_SEQUENCE
, ASN1_NONE
}, /* 3 */
274 { 3, "baseCertificateID", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 4 */
275 { 4, "issuer", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 5 */
276 { 4, "serial", ASN1_INTEGER
, ASN1_BODY
}, /* 6 */
277 { 4, "issuerUID", ASN1_BIT_STRING
, ASN1_OPT
|
279 { 4, "end opt", ASN1_EOC
, ASN1_END
}, /* 8 */
280 { 3, "end opt", ASN1_EOC
, ASN1_END
}, /* 9 */
281 { 3, "entityName", ASN1_CONTEXT_C_1
, ASN1_OPT
|
283 { 3, "end opt", ASN1_EOC
, ASN1_END
}, /* 11 */
284 { 3, "objectDigestInfo", ASN1_CONTEXT_C_2
, ASN1_OPT
}, /* 12 */
285 { 4, "digestedObjectType", ASN1_ENUMERATED
, ASN1_BODY
}, /* 13 */
286 { 4, "otherObjectTypeID", ASN1_OID
, ASN1_OPT
|
287 ASN1_BODY
}, /* 14 */
288 { 4, "end opt", ASN1_EOC
, ASN1_END
}, /* 15 */
289 { 4, "digestAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 16 */
290 { 3, "end opt", ASN1_EOC
, ASN1_END
}, /* 17 */
291 { 2, "v2Form", ASN1_CONTEXT_C_0
, ASN1_NONE
}, /* 18 */
292 { 3, "issuerName", ASN1_SEQUENCE
, ASN1_OPT
|
294 { 3, "end opt", ASN1_EOC
, ASN1_END
}, /* 20 */
295 { 3, "baseCertificateID", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 21 */
296 { 4, "issuerSerial", ASN1_SEQUENCE
, ASN1_NONE
}, /* 22 */
297 { 5, "issuer", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 23 */
298 { 5, "serial", ASN1_INTEGER
, ASN1_BODY
}, /* 24 */
299 { 5, "issuerUID", ASN1_BIT_STRING
, ASN1_OPT
|
300 ASN1_BODY
}, /* 25 */
301 { 5, "end opt", ASN1_EOC
, ASN1_END
}, /* 26 */
302 { 3, "end opt", ASN1_EOC
, ASN1_END
}, /* 27 */
303 { 3, "objectDigestInfo", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 28 */
304 { 4, "digestInfo", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 29 */
305 { 5, "digestedObjectType", ASN1_ENUMERATED
, ASN1_BODY
}, /* 30 */
306 { 5, "otherObjectTypeID", ASN1_OID
, ASN1_OPT
|
307 ASN1_BODY
}, /* 31 */
308 { 5, "end opt", ASN1_EOC
, ASN1_END
}, /* 32 */
309 { 5, "digestAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 33 */
310 { 3, "end opt", ASN1_EOC
, ASN1_END
}, /* 34 */
311 { 2, "signature", ASN1_EOC
, ASN1_RAW
}, /* 35 */
312 { 2, "serialNumber", ASN1_INTEGER
, ASN1_BODY
}, /* 36 */
313 { 2, "attrCertValidityPeriod", ASN1_SEQUENCE
, ASN1_NONE
}, /* 37 */
314 { 3, "notBeforeTime", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 38 */
315 { 3, "notAfterTime", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 39 */
316 { 2, "attributes", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 40 */
317 { 3, "attribute", ASN1_SEQUENCE
, ASN1_NONE
}, /* 41 */
318 { 4, "type", ASN1_OID
, ASN1_BODY
}, /* 42 */
319 { 4, "values", ASN1_SET
, ASN1_LOOP
}, /* 43 */
320 { 5, "value", ASN1_EOC
, ASN1_RAW
}, /* 44 */
321 { 4, "end loop", ASN1_EOC
, ASN1_END
}, /* 45 */
322 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 46 */
323 { 2, "extensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 47 */
324 { 3, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 48 */
325 { 4, "extnID", ASN1_OID
, ASN1_BODY
}, /* 49 */
326 { 4, "critical", ASN1_BOOLEAN
, ASN1_DEF
|
327 ASN1_BODY
}, /* 50 */
328 { 4, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 51 */
329 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 52 */
330 { 1, "signatureAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 53 */
331 { 1, "signatureValue", ASN1_BIT_STRING
, ASN1_BODY
}, /* 54 */
332 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
334 #define AC_OBJ_CERTIFICATE_INFO 1
335 #define AC_OBJ_VERSION 2
336 #define AC_OBJ_HOLDER_ISSUER 5
337 #define AC_OBJ_HOLDER_SERIAL 6
338 #define AC_OBJ_ENTITY_NAME 10
339 #define AC_OBJ_ISSUER_NAME 19
340 #define AC_OBJ_ISSUER 23
341 #define AC_OBJ_SIG_ALG 35
342 #define AC_OBJ_SERIAL_NUMBER 36
343 #define AC_OBJ_NOT_BEFORE 38
344 #define AC_OBJ_NOT_AFTER 39
345 #define AC_OBJ_ATTRIBUTE_TYPE 42
346 #define AC_OBJ_ATTRIBUTE_VALUE 44
347 #define AC_OBJ_EXTN_ID 49
348 #define AC_OBJ_CRITICAL 50
349 #define AC_OBJ_EXTN_VALUE 51
350 #define AC_OBJ_ALGORITHM 53
351 #define AC_OBJ_SIGNATURE 54
354 * Parses an X.509 attribute certificate
356 static bool parse_certificate(private_x509_ac_t
*this)
358 asn1_parser_t
*parser
;
361 int type
= OID_UNKNOWN
;
362 int extn_oid
= OID_UNKNOWN
;
363 int sig_alg
= OID_UNKNOWN
;
364 bool success
= FALSE
;
367 parser
= asn1_parser_create(acObjects
, this->encoding
);
369 while (parser
->iterate(parser
, &objectID
, &object
))
371 u_int level
= parser
->get_level(parser
)+1;
375 case AC_OBJ_CERTIFICATE_INFO
:
376 this->certificateInfo
= object
;
379 this->version
= (object
.len
) ?
(1 + (u_int
)*object
.ptr
) : 1;
380 DBG2(" v%d", this->version
);
381 if (this->version
!= 2)
383 DBG1("v%d attribute certificates are not supported", this->version
);
387 case AC_OBJ_HOLDER_ISSUER
:
388 if (!parse_directoryName(object
, level
, FALSE
, &this->holderIssuer
))
393 case AC_OBJ_HOLDER_SERIAL
:
394 this->holderSerial
= object
;
396 case AC_OBJ_ENTITY_NAME
:
397 if (!parse_directoryName(object
, level
, TRUE
, &this->entityName
))
402 case AC_OBJ_ISSUER_NAME
:
403 if (!parse_directoryName(object
, level
, FALSE
, &this->issuerName
))
409 sig_alg
= asn1_parse_algorithmIdentifier(object
, level
, NULL
);
411 case AC_OBJ_SERIAL_NUMBER
:
412 this->serialNumber
= object
;
414 case AC_OBJ_NOT_BEFORE
:
415 this->notBefore
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
417 case AC_OBJ_NOT_AFTER
:
418 this->notAfter
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
420 case AC_OBJ_ATTRIBUTE_TYPE
:
421 type
= asn1_known_oid(object
);
423 case AC_OBJ_ATTRIBUTE_VALUE
:
427 case OID_AUTHENTICATION_INFO
:
428 DBG2(" need to parse authenticationInfo");
430 case OID_ACCESS_IDENTITY
:
431 DBG2(" need to parse accessIdentity");
433 case OID_CHARGING_IDENTITY
:
434 ietfAttr_list_create_from_chunk(object
, this->charging
, level
);
437 ietfAttr_list_create_from_chunk(object
, this->groups
, level
);
440 parse_roleSyntax(object
, level
);
448 extn_oid
= asn1_known_oid(object
);
450 case AC_OBJ_CRITICAL
:
451 critical
= object
.len
&& *object
.ptr
;
452 DBG2(" %s",(critical
)?
"TRUE":"FALSE");
454 case AC_OBJ_EXTN_VALUE
:
458 case OID_CRL_DISTRIBUTION_POINTS
:
459 DBG2(" need to parse crlDistributionPoints");
461 case OID_AUTHORITY_KEY_ID
:
462 this->authKeyIdentifier
= x509_parse_authorityKeyIdentifier(object
,
463 level
, &this->authKeySerialNumber
);
465 case OID_TARGET_INFORMATION
:
466 DBG2(" need to parse targetInformation");
468 case OID_NO_REV_AVAIL
:
469 this->noRevAvail
= TRUE
;
476 case AC_OBJ_ALGORITHM
:
477 this->algorithm
= asn1_parse_algorithmIdentifier(object
, level
,
479 if (this->algorithm
!= sig_alg
)
481 DBG1(" signature algorithms do not agree");
486 case AC_OBJ_SIGNATURE
:
487 this->signature
= object
;
493 success
= parser
->success(parser
);
496 parser
->destroy(parser
);
501 * build directoryName
503 static chunk_t
build_directoryName(asn1_t tag
, chunk_t name
)
505 return asn1_wrap(tag
, "m",
506 asn1_simple_object(ASN1_CONTEXT_C_4
, name
));
512 static chunk_t
build_holder(private_x509_ac_t
*this)
514 x509_t
* x509
= (x509_t
*)this->holderCert
;
515 identification_t
*issuer
= this->holderCert
->get_issuer(this->holderCert
);
516 identification_t
*subject
= this->holderCert
->get_subject(this->holderCert
);
518 return asn1_wrap(ASN1_SEQUENCE
, "mm",
519 asn1_wrap(ASN1_CONTEXT_C_0
, "mm",
520 build_directoryName(ASN1_SEQUENCE
, issuer
->get_encoding(issuer
)),
521 asn1_simple_object(ASN1_INTEGER
, x509
->get_serial(x509
))
523 build_directoryName(ASN1_CONTEXT_C_1
, subject
->get_encoding(subject
)));
529 static chunk_t
build_v2_form(private_x509_ac_t
*this)
531 identification_t
*subject
= this->signerCert
->get_subject(this->signerCert
);
533 return asn1_wrap(ASN1_CONTEXT_C_0
, "m",
534 build_directoryName(ASN1_SEQUENCE
, subject
->get_encoding(subject
)));
538 * build attrCertValidityPeriod
540 static chunk_t
build_attr_cert_validity(private_x509_ac_t
*this)
542 return asn1_wrap(ASN1_SEQUENCE
, "mm",
543 asn1_from_time(&this->notBefore
, ASN1_GENERALIZEDTIME
),
544 asn1_from_time(&this->notAfter
, ASN1_GENERALIZEDTIME
));
549 * build attribute type
551 static chunk_t
build_attribute_type(const chunk_t type
, chunk_t content
)
553 return asn1_wrap(ASN1_SEQUENCE
, "cm",
555 asn1_wrap(ASN1_SET
, "m", content
));
561 static chunk_t
build_attributes(private_x509_ac_t
*this)
563 return asn1_wrap(ASN1_SEQUENCE
, "m",
564 build_attribute_type(ASN1_group_oid
, ietfAttr_list_encode(this->groups
)));
568 * build authorityKeyIdentifier
570 static chunk_t
build_authorityKeyIdentifier(private_x509_ac_t
*this)
572 chunk_t keyIdentifier
;
573 chunk_t authorityCertIssuer
;
574 chunk_t authorityCertSerialNumber
;
575 x509_t
*x509
= (x509_t
*)this->signerCert
;
576 identification_t
*issuer
= this->signerCert
->get_issuer(this->signerCert
);
577 public_key_t
*public = this->signerCert
->get_public_key(this->signerCert
);
581 identification_t
*keyid
= public->get_id(public, ID_PUBKEY_SHA1
);
583 this->authKeyIdentifier
= keyid
= keyid
->clone(keyid
);
584 keyIdentifier
= keyid
->get_encoding(keyid
);
585 public->destroy(public);
589 keyIdentifier
= chunk_empty
;
591 authorityCertIssuer
= build_directoryName(ASN1_CONTEXT_C_1
,
592 issuer
->get_encoding(issuer
));
593 authorityCertSerialNumber
= asn1_simple_object(ASN1_CONTEXT_S_2
,
594 x509
->get_serial(x509
));
595 return asn1_wrap(ASN1_SEQUENCE
, "cm",
596 ASN1_authorityKeyIdentifier_oid
,
597 asn1_wrap(ASN1_OCTET_STRING
, "m",
598 asn1_wrap(ASN1_SEQUENCE
, "cmm",
601 authorityCertSerialNumber
610 static chunk_t
build_extensions(private_x509_ac_t
*this)
612 return asn1_wrap(ASN1_SEQUENCE
, "mc",
613 build_authorityKeyIdentifier(this),
614 ASN1_noRevAvail_ext
);
618 * build attributeCertificateInfo
620 static chunk_t
build_attr_cert_info(private_x509_ac_t
*this)
622 return asn1_wrap(ASN1_SEQUENCE
, "cmmcmmmm",
626 asn1_algorithmIdentifier(OID_SHA1_WITH_RSA
),
627 asn1_simple_object(ASN1_INTEGER
, this->serialNumber
),
628 build_attr_cert_validity(this),
629 build_attributes(this),
630 build_extensions(this));
635 * build an X.509 attribute certificate
637 static chunk_t
build_ac(private_x509_ac_t
*this)
639 chunk_t signatureValue
;
640 chunk_t attributeCertificateInfo
;
642 attributeCertificateInfo
= build_attr_cert_info(this);
644 this->signerKey
->sign(this->signerKey
, SIGN_RSA_EMSA_PKCS1_SHA1
,
645 attributeCertificateInfo
, &signatureValue
);
647 return asn1_wrap(ASN1_SEQUENCE
, "mcm",
648 attributeCertificateInfo
,
649 asn1_algorithmIdentifier(OID_SHA1_WITH_RSA
),
650 asn1_bitstring("m", signatureValue
));
654 * Implementation of ac_t.get_serial.
656 static chunk_t
get_serial(private_x509_ac_t
*this)
658 return this->serialNumber
;
662 * Implementation of ac_t.get_holderSerial.
664 static chunk_t
get_holderSerial(private_x509_ac_t
*this)
666 return this->holderSerial
;
670 * Implementation of ac_t.get_holderIssuer.
672 static identification_t
* get_holderIssuer(private_x509_ac_t
*this)
674 return this->holderIssuer
;
678 * Implementation of ac_t.get_authKeyIdentifier.
680 static identification_t
* get_authKeyIdentifier(private_x509_ac_t
*this)
682 return this->authKeyIdentifier
;
686 * Implementation of certificate_t.get_type
688 static certificate_type_t
get_type(private_x509_ac_t
*this)
694 * Implementation of certificate_t.get_subject
696 static identification_t
* get_subject(private_x509_ac_t
*this)
698 return this->entityName
;
702 * Implementation of certificate_t.get_issuer
704 static identification_t
* get_issuer(private_x509_ac_t
*this)
706 return this->issuerName
;
710 * Implementation of certificate_t.has_subject.
712 static id_match_t
has_subject(private_x509_ac_t
*this, identification_t
*subject
)
714 return ID_MATCH_NONE
;
718 * Implementation of certificate_t.has_issuer.
720 static id_match_t
has_issuer(private_x509_ac_t
*this, identification_t
*issuer
)
724 if (issuer
->get_type(issuer
) == ID_PUBKEY_SHA1
)
726 if (this->authKeyIdentifier
)
728 match
= issuer
->matches(issuer
, this->authKeyIdentifier
);
732 match
= ID_MATCH_NONE
;
737 match
= this->issuerName
->matches(this->issuerName
, issuer
);
743 * Implementation of certificate_t.issued_by
745 static bool issued_by(private_x509_ac_t
*this, certificate_t
*issuer
)
748 signature_scheme_t scheme
;
750 x509_t
*x509
= (x509_t
*)issuer
;
752 /* check if issuer is an X.509 AA certificate */
753 if (issuer
->get_type(issuer
) != CERT_X509
)
757 if (!(x509
->get_flags(x509
) & X509_AA
))
762 /* get the public key of the issuer */
763 key
= issuer
->get_public_key(issuer
);
765 /* compare keyIdentifiers if available, otherwise use DNs */
766 if (this->authKeyIdentifier
&& key
)
768 identification_t
*subjectKeyIdentifier
= key
->get_id(key
, ID_PUBKEY_SHA1
);
770 if (!subjectKeyIdentifier
->equals(subjectKeyIdentifier
,
771 this->authKeyIdentifier
))
778 if (!this->issuerName
->equals(this->issuerName
, issuer
->get_subject(issuer
)))
783 /* TODO: generic OID to scheme mapper? */
784 switch (this->algorithm
)
786 case OID_MD5_WITH_RSA
:
787 scheme
= SIGN_RSA_EMSA_PKCS1_MD5
;
789 case OID_SHA1_WITH_RSA
:
790 scheme
= SIGN_RSA_EMSA_PKCS1_SHA1
;
792 case OID_SHA256_WITH_RSA
:
793 scheme
= SIGN_RSA_EMSA_PKCS1_SHA256
;
795 case OID_SHA384_WITH_RSA
:
796 scheme
= SIGN_RSA_EMSA_PKCS1_SHA384
;
798 case OID_SHA512_WITH_RSA
:
799 scheme
= SIGN_RSA_EMSA_PKCS1_SHA512
;
801 case OID_ECDSA_WITH_SHA1
:
802 scheme
= SIGN_ECDSA_WITH_SHA1
;
811 valid
= key
->verify(key
, scheme
, this->certificateInfo
, this->signature
);
817 * Implementation of certificate_t.get_public_key.
819 static public_key_t
* get_public_key(private_x509_ac_t
*this)
825 * Implementation of certificate_t.get_ref.
827 static private_x509_ac_t
* get_ref(private_x509_ac_t
*this)
834 * Implementation of certificate_t.get_validity.
836 static bool get_validity(private_x509_ac_t
*this, time_t *when
,
837 time_t *not_before
, time_t *not_after
)
851 *not_before
= this->notBefore
;
855 *not_after
= this->notAfter
;
857 return (t
>= this->notBefore
&& t
<= this->notAfter
);
861 * Implementation of certificate_t.is_newer.
863 static bool is_newer(private_x509_ac_t
*this, ac_t
*that
)
865 certificate_t
*this_cert
= &this->public.interface
.certificate
;
866 certificate_t
*that_cert
= &that
->certificate
;
867 time_t this_update
, that_update
, now
= time(NULL
);
870 this_cert
->get_validity(this_cert
, &now
, &this_update
, NULL
);
871 that_cert
->get_validity(that_cert
, &now
, &that_update
, NULL
);
872 new = this_update
> that_update
;
873 DBG1(" attr cert from %#T is %s - existing attr_cert from %#T %s",
874 &this_update
, FALSE
, new ?
"newer":"not newer",
875 &that_update
, FALSE
, new ?
"replaced":"retained");
880 * Implementation of certificate_t.get_encoding.
882 static chunk_t
get_encoding(private_x509_ac_t
*this)
884 return chunk_clone(this->encoding
);
888 * Implementation of certificate_t.equals.
890 static bool equals(private_x509_ac_t
*this, certificate_t
*other
)
895 if ((certificate_t
*)this == other
)
899 if (other
->equals
== (void*)equals
)
900 { /* skip allocation if we have the same implementation */
901 return chunk_equals(this->encoding
, ((private_x509_ac_t
*)other
)->encoding
);
903 encoding
= other
->get_encoding(other
);
904 equal
= chunk_equals(this->encoding
, encoding
);
910 * Implementation of x509_ac_t.destroy
912 static void destroy(private_x509_ac_t
*this)
914 if (ref_put(&this->ref
))
916 DESTROY_IF(this->holderIssuer
);
917 DESTROY_IF(this->entityName
);
918 DESTROY_IF(this->issuerName
);
919 DESTROY_IF(this->authKeyIdentifier
);
920 DESTROY_IF(this->holderCert
);
921 DESTROY_IF(this->signerCert
);
922 DESTROY_IF(this->signerKey
);
924 ietfAttr_list_destroy(this->charging
);
925 ietfAttr_list_destroy(this->groups
);
926 free(this->encoding
.ptr
);
932 * create an empty but initialized X.509 attribute certificate
934 static private_x509_ac_t
*create_empty(void)
936 private_x509_ac_t
*this = malloc_thing(private_x509_ac_t
);
938 /* public functions */
939 this->public.interface
.get_serial
= (chunk_t (*)(ac_t
*))get_serial
;
940 this->public.interface
.get_holderSerial
= (chunk_t (*)(ac_t
*))get_holderSerial
;
941 this->public.interface
.get_holderIssuer
= (identification_t
* (*)(ac_t
*))get_holderIssuer
;
942 this->public.interface
.get_authKeyIdentifier
= (identification_t
* (*)(ac_t
*))get_authKeyIdentifier
;
943 this->public.interface
.certificate
.get_type
= (certificate_type_t (*)(certificate_t
*this))get_type
;
944 this->public.interface
.certificate
.get_subject
= (identification_t
* (*)(certificate_t
*this))get_subject
;
945 this->public.interface
.certificate
.get_issuer
= (identification_t
* (*)(certificate_t
*this))get_issuer
;
946 this->public.interface
.certificate
.has_subject
= (id_match_t(*)(certificate_t
*, identification_t
*subject
))has_subject
;
947 this->public.interface
.certificate
.has_issuer
= (id_match_t(*)(certificate_t
*, identification_t
*issuer
))has_issuer
;
948 this->public.interface
.certificate
.issued_by
= (bool (*)(certificate_t
*this, certificate_t
*issuer
))issued_by
;
949 this->public.interface
.certificate
.get_public_key
= (public_key_t
* (*)(certificate_t
*this))get_public_key
;
950 this->public.interface
.certificate
.get_validity
= (bool(*)(certificate_t
*, time_t *when
, time_t *, time_t*))get_validity
;
951 this->public.interface
.certificate
.is_newer
= (bool (*)(certificate_t
*,certificate_t
*))is_newer
;
952 this->public.interface
.certificate
.get_encoding
= (chunk_t(*)(certificate_t
*))get_encoding
;
953 this->public.interface
.certificate
.equals
= (bool(*)(certificate_t
*, certificate_t
*other
))equals
;
954 this->public.interface
.certificate
.get_ref
= (certificate_t
* (*)(certificate_t
*this))get_ref
;
955 this->public.interface
.certificate
.destroy
= (void (*)(certificate_t
*this))destroy
;
958 this->encoding
= chunk_empty
;
959 this->holderSerial
= chunk_empty
;
960 this->holderIssuer
= NULL
;
961 this->entityName
= NULL
;
962 this->issuerName
= NULL
;
963 this->authKeyIdentifier
= NULL
;
964 this->holderCert
= NULL
;
965 this->signerCert
= NULL
;
966 this->signerKey
= NULL
;
967 this->charging
= linked_list_create();
968 this->groups
= linked_list_create();
975 * create X.509 attribute certificate from a chunk
977 static private_x509_ac_t
* create_from_chunk(chunk_t chunk
)
979 private_x509_ac_t
*this = create_empty();
981 this->encoding
= chunk
;
982 if (!parse_certificate(this))
991 * create X.509 crl from a file
993 static private_x509_ac_t
* create_from_file(char *path
)
997 private_x509_ac_t
*this;
999 if (!pem_asn1_load_file(path
, NULL
, &chunk
, &pgp
))
1004 this = create_from_chunk(chunk
);
1008 DBG1(" could not parse loaded attribute certificate file '%s'", path
);
1011 DBG1(" loaded attribute certificate file '%s'", path
);
1015 typedef struct private_builder_t private_builder_t
;
1017 * Builder implementation for certificate loading
1019 struct private_builder_t
{
1020 /** implements the builder interface */
1022 /** X.509 attribute certificate to build */
1023 private_x509_ac_t
*ac
;
1027 * Implementation of builder_t.build
1029 static private_x509_ac_t
* build(private_builder_t
*this)
1031 private_x509_ac_t
*ac
= this->ac
;
1035 /* synthesis if encoding does not exist */
1036 if (ac
&& ac
->encoding
.ptr
== NULL
)
1038 if (ac
->holderCert
&& ac
->signerCert
&& ac
->signerKey
)
1040 ac
->encoding
= build_ac(ac
);
1053 * Implementation of builder_t.add
1055 static void add(private_builder_t
*this, builder_part_t part
, ...)
1058 certificate_t
*cert
;
1061 va_start(args
, part
);
1064 case BUILD_FROM_FILE
:
1069 this->ac
= create_from_file(va_arg(args
, char*));
1071 case BUILD_BLOB_ASN1_DER
:
1076 chunk
= va_arg(args
, chunk_t
);
1077 this->ac
= create_from_chunk(chunk_clone(chunk
));
1079 case BUILD_NOT_BEFORE_TIME
:
1080 this->ac
->notBefore
= va_arg(args
, time_t);
1082 case BUILD_NOT_AFTER_TIME
:
1083 this->ac
->notAfter
= va_arg(args
, time_t);
1086 chunk
= va_arg(args
, chunk_t
);
1087 this->ac
->serialNumber
= chunk_clone(chunk
);
1089 case BUILD_IETF_GROUP_ATTR
:
1090 ietfAttr_list_create_from_string(va_arg(args
, char*),
1094 cert
= va_arg(args
, certificate_t
*);
1095 if (cert
->get_type(cert
) == CERT_X509
)
1097 this->ac
->holderCert
= cert
->get_ref(cert
);
1100 case BUILD_SIGNING_CERT
:
1101 cert
= va_arg(args
, certificate_t
*);
1102 if (cert
->get_type(cert
) == CERT_X509
)
1104 this->ac
->signerCert
= cert
->get_ref(cert
);
1107 case BUILD_SIGNING_KEY
:
1108 this->ac
->signerKey
= va_arg(args
, private_key_t
*);
1109 this->ac
->signerKey
->get_ref(this->ac
->signerKey
);
1112 /* abort if unsupported option */
1117 builder_cancel(&this->public);
1124 * Builder construction function
1126 builder_t
*x509_ac_builder(certificate_type_t type
)
1128 private_builder_t
*this;
1130 if (type
!= CERT_X509_AC
)
1135 this = malloc_thing(private_builder_t
);
1137 this->ac
= create_empty();
1138 this->public.add
= (void(*)(builder_t
*this, builder_part_t part
, ...))add
;
1139 this->public.build
= (void*(*)(builder_t
*this))build
;
1141 return &this->public;