2 * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
3 * Copyright (C) 2003 Martin Berner, Lukas Suter
4 * Copyright (C) 2002-2017 Andreas Steffen
5 * Copyright (C) 2009 Martin Willi
6 * HSR 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
24 #include <utils/debug.h>
26 #include <asn1/asn1.h>
27 #include <asn1/asn1_parser.h>
28 #include <utils/identification.h>
29 #include <collections/linked_list.h>
30 #include <credentials/certificates/x509.h>
31 #include <credentials/keys/private_key.h>
33 extern chunk_t
x509_parse_authorityKeyIdentifier(chunk_t blob
,
34 int level0
, chunk_t
*authKeySerialNumber
);
36 typedef struct private_x509_ac_t private_x509_ac_t
;
39 * private data of x509_ac_t object
41 struct private_x509_ac_t
{
49 * X.509 attribute certificate encoding in ASN.1 DER format
54 * X.509 attribute certificate body over which signature is computed
56 chunk_t certificateInfo
;
59 * Version of the X.509 attribute certificate
64 * Serial number of the X.509 attribute certificate
69 * ID representing the issuer of the holder certificate
71 identification_t
*holderIssuer
;
74 * Serial number of the holder certificate
76 identification_t
*holderSerial
;
79 * ID representing the holder
81 identification_t
*entityName
;
84 * ID representing the attribute certificate issuer
86 identification_t
*issuerName
;
89 * Start time of certificate validity
94 * End time of certificate validity
99 * List of group attributes, as group_t
101 linked_list_t
*groups
;
104 * Authority Key Identifier
106 chunk_t authKeyIdentifier
;
109 * Authority Key Serial Number
111 chunk_t authKeySerialNumber
;
114 * No revocation information available
119 * Signature algorithm
131 certificate_t
*holderCert
;
136 certificate_t
*signerCert
;
139 * Signer private key;
141 private_key_t
*signerKey
;
150 * Group definition, an IETF attribute
153 /** Attribute type */
154 ac_group_type_t type
;
155 /* attribute value */
160 * Clean up a group entry
162 static void group_destroy(group_t
*group
)
164 free(group
->value
.ptr
);
168 static chunk_t ASN1_noRevAvail_ext
= chunk_from_chars(
177 * declaration of function implemented in x509_cert.c
179 extern bool x509_parse_generalNames(chunk_t blob
, int level0
, bool implicit
,
180 linked_list_t
*list
);
182 * parses a directoryName
184 static bool parse_directoryName(chunk_t blob
, int level
, bool implicit
,
185 identification_t
**name
)
187 identification_t
*directoryName
;
188 enumerator_t
*enumerator
;
192 list
= linked_list_create();
193 if (!x509_parse_generalNames(blob
, level
, implicit
, list
))
199 enumerator
= list
->create_enumerator(list
);
200 while (enumerator
->enumerate(enumerator
, &directoryName
))
204 *name
= directoryName
;
209 DBG1(DBG_ASN
, "more than one directory name - first selected");
210 directoryName
->destroy(directoryName
);
214 enumerator
->destroy(enumerator
);
219 DBG1(DBG_ASN
, "no directoryName found");
226 * ASN.1 definition of roleSyntax
228 static const asn1Object_t roleSyntaxObjects
[] =
230 { 0, "roleSyntax", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
231 { 1, "roleAuthority", ASN1_CONTEXT_C_0
, ASN1_OPT
|
233 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 2 */
234 { 1, "roleName", ASN1_CONTEXT_C_1
, ASN1_OBJ
}, /* 3 */
235 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
241 static void parse_roleSyntax(chunk_t blob
, int level0
)
243 asn1_parser_t
*parser
;
247 parser
= asn1_parser_create(roleSyntaxObjects
, blob
);
248 parser
->set_top_level(parser
, level0
);
250 while (parser
->iterate(parser
, &objectID
, &object
))
258 parser
->destroy(parser
);
262 * ASN.1 definition of ietfAttrSyntax
264 static const asn1Object_t ietfAttrSyntaxObjects
[] =
266 { 0, "ietfAttrSyntax", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
267 { 1, "policyAuthority", ASN1_CONTEXT_C_0
, ASN1_OPT
|
269 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 2 */
270 { 1, "values", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 3 */
271 { 2, "octets", ASN1_OCTET_STRING
, ASN1_OPT
|
273 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 5 */
274 { 2, "oid", ASN1_OID
, ASN1_OPT
|
276 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 7 */
277 { 2, "string", ASN1_UTF8STRING
, ASN1_OPT
|
279 { 2, "end choice", ASN1_EOC
, ASN1_END
}, /* 9 */
280 { 1, "end loop", ASN1_EOC
, ASN1_END
}, /* 10 */
281 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
283 #define IETF_ATTR_OCTETS 4
284 #define IETF_ATTR_OID 6
285 #define IETF_ATTR_STRING 8
288 * Parse group memberships, IETF attributes
290 static bool parse_groups(private_x509_ac_t
*this, chunk_t encoded
, int level0
)
292 ac_group_type_t type
;
294 asn1_parser_t
*parser
;
299 parser
= asn1_parser_create(ietfAttrSyntaxObjects
, encoded
);
300 parser
->set_top_level(parser
, level0
);
301 while (parser
->iterate(parser
, &objectID
, &object
))
305 case IETF_ATTR_OCTETS
:
306 type
= AC_GROUP_TYPE_OCTETS
;
309 type
= AC_GROUP_TYPE_OID
;
311 case IETF_ATTR_STRING
:
312 type
= AC_GROUP_TYPE_STRING
;
319 .value
= chunk_clone(object
),
321 this->groups
->insert_last(this->groups
, group
);
323 success
= parser
->success(parser
);
324 parser
->destroy(parser
);
330 * ASN.1 definition of an X509 attribute certificate
332 static const asn1Object_t acObjects
[] =
334 { 0, "AttributeCertificate", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 0 */
335 { 1, "AttributeCertificateInfo", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 1 */
336 { 2, "version", ASN1_INTEGER
, ASN1_DEF
|
338 { 2, "holder", ASN1_SEQUENCE
, ASN1_NONE
}, /* 3 */
339 { 3, "baseCertificateID", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 4 */
340 { 4, "issuer", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 5 */
341 { 4, "serial", ASN1_INTEGER
, ASN1_BODY
}, /* 6 */
342 { 4, "issuerUID", ASN1_BIT_STRING
, ASN1_OPT
|
344 { 4, "end opt", ASN1_EOC
, ASN1_END
}, /* 8 */
345 { 3, "end opt", ASN1_EOC
, ASN1_END
}, /* 9 */
346 { 3, "entityName", ASN1_CONTEXT_C_1
, ASN1_OPT
|
348 { 3, "end opt", ASN1_EOC
, ASN1_END
}, /* 11 */
349 { 3, "objectDigestInfo", ASN1_CONTEXT_C_2
, ASN1_OPT
}, /* 12 */
350 { 4, "digestedObjectType", ASN1_ENUMERATED
, ASN1_BODY
}, /* 13 */
351 { 4, "otherObjectTypeID", ASN1_OID
, ASN1_OPT
|
352 ASN1_BODY
}, /* 14 */
353 { 4, "end opt", ASN1_EOC
, ASN1_END
}, /* 15 */
354 { 4, "digestAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 16 */
355 { 3, "end opt", ASN1_EOC
, ASN1_END
}, /* 17 */
356 { 2, "v2Form", ASN1_CONTEXT_C_0
, ASN1_NONE
}, /* 18 */
357 { 3, "issuerName", ASN1_SEQUENCE
, ASN1_OPT
|
359 { 3, "end opt", ASN1_EOC
, ASN1_END
}, /* 20 */
360 { 3, "baseCertificateID", ASN1_CONTEXT_C_0
, ASN1_OPT
}, /* 21 */
361 { 4, "issuerSerial", ASN1_SEQUENCE
, ASN1_NONE
}, /* 22 */
362 { 5, "issuer", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 23 */
363 { 5, "serial", ASN1_INTEGER
, ASN1_BODY
}, /* 24 */
364 { 5, "issuerUID", ASN1_BIT_STRING
, ASN1_OPT
|
365 ASN1_BODY
}, /* 25 */
366 { 5, "end opt", ASN1_EOC
, ASN1_END
}, /* 26 */
367 { 3, "end opt", ASN1_EOC
, ASN1_END
}, /* 27 */
368 { 3, "objectDigestInfo", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 28 */
369 { 4, "digestInfo", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 29 */
370 { 5, "digestedObjectType", ASN1_ENUMERATED
, ASN1_BODY
}, /* 30 */
371 { 5, "otherObjectTypeID", ASN1_OID
, ASN1_OPT
|
372 ASN1_BODY
}, /* 31 */
373 { 5, "end opt", ASN1_EOC
, ASN1_END
}, /* 32 */
374 { 5, "digestAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 33 */
375 { 3, "end opt", ASN1_EOC
, ASN1_END
}, /* 34 */
376 { 2, "signature", ASN1_EOC
, ASN1_RAW
}, /* 35 */
377 { 2, "serialNumber", ASN1_INTEGER
, ASN1_BODY
}, /* 36 */
378 { 2, "attrCertValidityPeriod", ASN1_SEQUENCE
, ASN1_NONE
}, /* 37 */
379 { 3, "notBeforeTime", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 38 */
380 { 3, "notAfterTime", ASN1_GENERALIZEDTIME
, ASN1_BODY
}, /* 39 */
381 { 2, "attributes", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 40 */
382 { 3, "attribute", ASN1_SEQUENCE
, ASN1_NONE
}, /* 41 */
383 { 4, "type", ASN1_OID
, ASN1_BODY
}, /* 42 */
384 { 4, "values", ASN1_SET
, ASN1_LOOP
}, /* 43 */
385 { 5, "value", ASN1_EOC
, ASN1_RAW
}, /* 44 */
386 { 4, "end loop", ASN1_EOC
, ASN1_END
}, /* 45 */
387 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 46 */
388 { 2, "extensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 47 */
389 { 3, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 48 */
390 { 4, "extnID", ASN1_OID
, ASN1_BODY
}, /* 49 */
391 { 4, "critical", ASN1_BOOLEAN
, ASN1_DEF
|
392 ASN1_BODY
}, /* 50 */
393 { 4, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 51 */
394 { 2, "end loop", ASN1_EOC
, ASN1_END
}, /* 52 */
395 { 1, "signatureAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 53 */
396 { 1, "signatureValue", ASN1_BIT_STRING
, ASN1_BODY
}, /* 54 */
397 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
399 #define AC_OBJ_CERTIFICATE_INFO 1
400 #define AC_OBJ_VERSION 2
401 #define AC_OBJ_HOLDER_ISSUER 5
402 #define AC_OBJ_HOLDER_SERIAL 6
403 #define AC_OBJ_ENTITY_NAME 10
404 #define AC_OBJ_ISSUER_NAME 19
405 #define AC_OBJ_ISSUER 23
406 #define AC_OBJ_SIG_ALG 35
407 #define AC_OBJ_SERIAL_NUMBER 36
408 #define AC_OBJ_NOT_BEFORE 38
409 #define AC_OBJ_NOT_AFTER 39
410 #define AC_OBJ_ATTRIBUTE_TYPE 42
411 #define AC_OBJ_ATTRIBUTE_VALUE 44
412 #define AC_OBJ_EXTN_ID 49
413 #define AC_OBJ_CRITICAL 50
414 #define AC_OBJ_EXTN_VALUE 51
415 #define AC_OBJ_ALGORITHM 53
416 #define AC_OBJ_SIGNATURE 54
419 * Parses an X.509 attribute certificate
421 static bool parse_certificate(private_x509_ac_t
*this)
423 asn1_parser_t
*parser
;
426 int type
= OID_UNKNOWN
;
427 int extn_oid
= OID_UNKNOWN
;
428 int sig_alg
= OID_UNKNOWN
;
429 bool success
= FALSE
;
432 parser
= asn1_parser_create(acObjects
, this->encoding
);
434 while (parser
->iterate(parser
, &objectID
, &object
))
436 u_int level
= parser
->get_level(parser
)+1;
440 case AC_OBJ_CERTIFICATE_INFO
:
441 this->certificateInfo
= object
;
444 this->version
= (object
.len
) ?
(1 + (u_int
)*object
.ptr
) : 1;
445 DBG2(DBG_ASN
, " v%d", this->version
);
446 if (this->version
!= 2)
448 DBG1(DBG_ASN
, "v%d attribute certificates are not "
449 "supported", this->version
);
453 case AC_OBJ_HOLDER_ISSUER
:
454 if (!parse_directoryName(object
, level
, FALSE
,
455 &this->holderIssuer
))
460 case AC_OBJ_HOLDER_SERIAL
:
461 this->holderSerial
= identification_create_from_encoding(
464 case AC_OBJ_ENTITY_NAME
:
465 if (!parse_directoryName(object
, level
, TRUE
,
471 case AC_OBJ_ISSUER_NAME
:
472 if (!parse_directoryName(object
, level
, FALSE
,
479 sig_alg
= asn1_parse_algorithmIdentifier(object
, level
, NULL
);
481 case AC_OBJ_SERIAL_NUMBER
:
482 this->serialNumber
= chunk_clone(object
);
484 case AC_OBJ_NOT_BEFORE
:
485 this->notBefore
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
487 case AC_OBJ_NOT_AFTER
:
488 this->notAfter
= asn1_to_time(&object
, ASN1_GENERALIZEDTIME
);
490 case AC_OBJ_ATTRIBUTE_TYPE
:
491 type
= asn1_known_oid(object
);
493 case AC_OBJ_ATTRIBUTE_VALUE
:
497 case OID_AUTHENTICATION_INFO
:
498 DBG2(DBG_ASN
, " need to parse authenticationInfo");
500 case OID_ACCESS_IDENTITY
:
501 DBG2(DBG_ASN
, " need to parse accessIdentity");
503 case OID_CHARGING_IDENTITY
:
504 DBG2(DBG_ASN
, " need to parse chargingIdentity");
507 DBG2(DBG_ASN
, "-- > --");
508 if (!parse_groups(this, object
, level
))
512 DBG2(DBG_ASN
, "-- < --");
515 parse_roleSyntax(object
, level
);
523 extn_oid
= asn1_known_oid(object
);
525 case AC_OBJ_CRITICAL
:
526 critical
= object
.len
&& *object
.ptr
;
527 DBG2(DBG_ASN
, " %s",(critical
)?
"TRUE":"FALSE");
529 case AC_OBJ_EXTN_VALUE
:
533 case OID_CRL_DISTRIBUTION_POINTS
:
534 DBG2(DBG_ASN
, " need to parse crlDistributionPoints");
536 case OID_AUTHORITY_KEY_ID
:
537 this->authKeyIdentifier
=
538 x509_parse_authorityKeyIdentifier(object
,
539 level
, &this->authKeySerialNumber
);
541 case OID_TARGET_INFORMATION
:
542 DBG2(DBG_ASN
, " need to parse targetInformation");
544 case OID_NO_REV_AVAIL
:
545 this->noRevAvail
= TRUE
;
552 case AC_OBJ_ALGORITHM
:
553 this->algorithm
= asn1_parse_algorithmIdentifier(object
, level
,
555 if (this->algorithm
!= sig_alg
)
557 DBG1(DBG_ASN
, " signature algorithms do not agree");
562 case AC_OBJ_SIGNATURE
:
563 this->signature
= chunk_skip(object
, 1);
569 success
= parser
->success(parser
);
572 parser
->destroy(parser
);
577 * build directoryName
579 static chunk_t
build_directoryName(asn1_t tag
, chunk_t name
)
581 return asn1_wrap(tag
, "m",
582 asn1_simple_object(ASN1_CONTEXT_C_4
, name
));
588 static chunk_t
build_holder(private_x509_ac_t
*this)
590 x509_t
* x509
= (x509_t
*)this->holderCert
;
591 identification_t
*issuer
, *subject
;
593 issuer
= this->holderCert
->get_issuer(this->holderCert
);
594 subject
= this->holderCert
->get_subject(this->holderCert
);
596 return asn1_wrap(ASN1_SEQUENCE
, "mm",
597 asn1_wrap(ASN1_CONTEXT_C_0
, "mm",
598 build_directoryName(ASN1_SEQUENCE
, issuer
->get_encoding(issuer
)),
599 asn1_simple_object(ASN1_INTEGER
, x509
->get_serial(x509
))),
600 build_directoryName(ASN1_CONTEXT_C_1
, subject
->get_encoding(subject
)));
606 static chunk_t
build_v2_form(private_x509_ac_t
*this)
608 identification_t
*subject
;
610 subject
= this->signerCert
->get_subject(this->signerCert
);
611 return asn1_wrap(ASN1_CONTEXT_C_0
, "m",
612 build_directoryName(ASN1_SEQUENCE
,
613 subject
->get_encoding(subject
)));
617 * build attrCertValidityPeriod
619 static chunk_t
build_attr_cert_validity(private_x509_ac_t
*this)
621 return asn1_wrap(ASN1_SEQUENCE
, "mm",
622 asn1_from_time(&this->notBefore
, ASN1_GENERALIZEDTIME
),
623 asn1_from_time(&this->notAfter
, ASN1_GENERALIZEDTIME
));
627 * build attribute type
629 static chunk_t
build_attribute_type(int type
, chunk_t content
)
631 return asn1_wrap(ASN1_SEQUENCE
, "mm",
632 asn1_build_known_oid(type
),
633 asn1_wrap(ASN1_SET
, "m", content
));
639 static chunk_t
build_attributes(private_x509_ac_t
*this)
641 enumerator_t
*enumerator
;
644 size_t size
= 0, len
;
647 /* precalculate the total size of all values */
648 enumerator
= this->groups
->create_enumerator(this->groups
);
649 while (enumerator
->enumerate(enumerator
, &group
))
651 len
= group
->value
.len
;
652 size
+= 1 + (len
> 0) + (len
>= 128) +
653 (len
>= 256) + (len
>= 65536) + len
;
655 enumerator
->destroy(enumerator
);
657 pos
= asn1_build_object(&values
, ASN1_SEQUENCE
, size
);
659 enumerator
= this->groups
->create_enumerator(this->groups
);
660 while (enumerator
->enumerate(enumerator
, &group
))
667 case AC_GROUP_TYPE_OCTETS
:
668 type
= ASN1_OCTET_STRING
;
670 case AC_GROUP_TYPE_STRING
:
671 type
= ASN1_UTF8STRING
;
673 case AC_GROUP_TYPE_OID
:
679 attr
= asn1_simple_object(type
, group
->value
);
681 memcpy(pos
, attr
.ptr
, attr
.len
);
685 enumerator
->destroy(enumerator
);
687 return asn1_wrap(ASN1_SEQUENCE
, "m",
688 build_attribute_type(OID_GROUP
,
689 asn1_wrap(ASN1_SEQUENCE
, "m", values
)));
693 * build authorityKeyIdentifier
695 static chunk_t
build_authorityKeyIdentifier(private_x509_ac_t
*this)
697 chunk_t keyIdentifier
= chunk_empty
;
698 chunk_t authorityCertIssuer
;
699 chunk_t authorityCertSerialNumber
;
700 identification_t
*issuer
;
701 public_key_t
*public;
704 x509
= (x509_t
*)this->signerCert
;
705 issuer
= this->signerCert
->get_issuer(this->signerCert
);
706 public = this->signerCert
->get_public_key(this->signerCert
);
709 if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1
, &keyIdentifier
))
711 this->authKeyIdentifier
= chunk_clone(keyIdentifier
);
712 keyIdentifier
= asn1_simple_object(ASN1_CONTEXT_S_0
, keyIdentifier
);
714 public->destroy(public);
716 authorityCertIssuer
= build_directoryName(ASN1_CONTEXT_C_1
,
717 issuer
->get_encoding(issuer
));
718 authorityCertSerialNumber
= asn1_simple_object(ASN1_CONTEXT_S_2
,
719 x509
->get_serial(x509
));
720 return asn1_wrap(ASN1_SEQUENCE
, "mm",
721 asn1_build_known_oid(OID_AUTHORITY_KEY_ID
),
722 asn1_wrap(ASN1_OCTET_STRING
, "m",
723 asn1_wrap(ASN1_SEQUENCE
, "mmm",
726 authorityCertSerialNumber
735 static chunk_t
build_extensions(private_x509_ac_t
*this)
737 return asn1_wrap(ASN1_SEQUENCE
, "mc",
738 build_authorityKeyIdentifier(this),
739 ASN1_noRevAvail_ext
);
743 * build attributeCertificateInfo
745 static chunk_t
build_attr_cert_info(private_x509_ac_t
*this)
747 return asn1_wrap(ASN1_SEQUENCE
, "cmmmmmmm",
751 asn1_algorithmIdentifier(OID_SHA1_WITH_RSA
),
752 asn1_simple_object(ASN1_INTEGER
, this->serialNumber
),
753 build_attr_cert_validity(this),
754 build_attributes(this),
755 build_extensions(this));
759 * build an X.509 attribute certificate
761 static bool build_ac(private_x509_ac_t
*this)
763 chunk_t signatureValue
, attributeCertificateInfo
;
765 attributeCertificateInfo
= build_attr_cert_info(this);
766 if (!this->signerKey
->sign(this->signerKey
, SIGN_RSA_EMSA_PKCS1_SHA1
,
767 attributeCertificateInfo
, &signatureValue
))
769 free(attributeCertificateInfo
.ptr
);
772 this->encoding
= asn1_wrap(ASN1_SEQUENCE
, "mmm",
773 attributeCertificateInfo
,
774 asn1_algorithmIdentifier(OID_SHA1_WITH_RSA
),
775 asn1_bitstring("m", signatureValue
));
779 METHOD(ac_t
, get_serial
, chunk_t
,
780 private_x509_ac_t
*this)
782 return this->serialNumber
;
785 METHOD(ac_t
, get_holderSerial
, chunk_t
,
786 private_x509_ac_t
*this)
788 if (this->holderSerial
)
790 return this->holderSerial
->get_encoding(this->holderSerial
);
795 METHOD(ac_t
, get_holderIssuer
, identification_t
*,
796 private_x509_ac_t
*this)
798 return this->holderIssuer
;
801 METHOD(ac_t
, get_authKeyIdentifier
, chunk_t
,
802 private_x509_ac_t
*this)
804 return this->authKeyIdentifier
;
808 * Filter function for attribute enumeration
810 static bool attr_filter(void *null
, group_t
**in
, ac_group_type_t
*type
,
811 void *in2
, chunk_t
*out
)
813 if ((*in
)->type
== AC_GROUP_TYPE_STRING
&&
814 !chunk_printable((*in
)->value
, NULL
, 0))
815 { /* skip non-printable strings */
823 METHOD(ac_t
, create_group_enumerator
, enumerator_t
*,
824 private_x509_ac_t
*this)
826 return enumerator_create_filter(
827 this->groups
->create_enumerator(this->groups
),
828 (void*)attr_filter
, NULL
, NULL
);
831 METHOD(certificate_t
, get_type
, certificate_type_t
,
832 private_x509_ac_t
*this)
837 METHOD(certificate_t
, get_subject
, identification_t
*,
838 private_x509_ac_t
*this)
840 if (this->entityName
)
842 return this->entityName
;
844 return this->holderSerial
;
847 METHOD(certificate_t
, get_issuer
, identification_t
*,
848 private_x509_ac_t
*this)
850 return this->issuerName
;
853 METHOD(certificate_t
, has_subject
, id_match_t
,
854 private_x509_ac_t
*this, identification_t
*subject
)
856 id_match_t entity
= ID_MATCH_NONE
, serial
= ID_MATCH_NONE
;
858 if (this->entityName
)
860 entity
= this->entityName
->matches(this->entityName
, subject
);
862 if (this->holderSerial
)
864 serial
= this->holderSerial
->matches(this->holderSerial
, subject
);
866 return max(entity
, serial
);
869 METHOD(certificate_t
, has_issuer
, id_match_t
,
870 private_x509_ac_t
*this, identification_t
*issuer
)
872 if (issuer
->get_type(issuer
) == ID_KEY_ID
&&
873 this->authKeyIdentifier
.ptr
&&
874 chunk_equals(this->authKeyIdentifier
, issuer
->get_encoding(issuer
)))
876 return ID_MATCH_PERFECT
;
878 return this->issuerName
->matches(this->issuerName
, issuer
);
881 METHOD(certificate_t
, issued_by
, bool,
882 private_x509_ac_t
*this, certificate_t
*issuer
, signature_scheme_t
*schemep
)
885 signature_scheme_t scheme
;
887 x509_t
*x509
= (x509_t
*)issuer
;
889 /* check if issuer is an X.509 AA certificate */
890 if (issuer
->get_type(issuer
) != CERT_X509
)
894 if (!(x509
->get_flags(x509
) & X509_AA
))
899 /* get the public key of the issuer */
900 key
= issuer
->get_public_key(issuer
);
902 /* compare keyIdentifiers if available, otherwise use DNs */
903 if (this->authKeyIdentifier
.ptr
&& key
)
907 if (!key
->get_fingerprint(key
, KEYID_PUBKEY_SHA1
, &fingerprint
) ||
908 !chunk_equals(fingerprint
, this->authKeyIdentifier
))
915 if (!this->issuerName
->equals(this->issuerName
,
916 issuer
->get_subject(issuer
)))
922 /* determine signature scheme */
923 scheme
= signature_scheme_from_oid(this->algorithm
);
925 if (scheme
== SIGN_UNKNOWN
|| key
== NULL
)
929 valid
= key
->verify(key
, scheme
, this->certificateInfo
, this->signature
);
931 if (valid
&& schemep
)
938 METHOD(certificate_t
, get_public_key
, public_key_t
*,
939 private_x509_ac_t
*this)
944 METHOD(certificate_t
, get_ref
, certificate_t
*,
945 private_x509_ac_t
*this)
948 return &this->public.interface
.certificate
;
951 METHOD(certificate_t
, get_validity
, bool,
952 private_x509_ac_t
*this, time_t *when
, time_t *not_before
, time_t *not_after
)
954 time_t t
= when ?
*when
: time(NULL
);
958 *not_before
= this->notBefore
;
962 *not_after
= this->notAfter
;
964 return (t
>= this->notBefore
&& t
<= this->notAfter
);
967 METHOD(certificate_t
, get_encoding
, bool,
968 private_x509_ac_t
*this, cred_encoding_type_t type
, chunk_t
*encoding
)
970 if (type
== CERT_ASN1_DER
)
972 *encoding
= chunk_clone(this->encoding
);
975 return lib
->encoding
->encode(lib
->encoding
, type
, NULL
, encoding
,
976 CRED_PART_X509_AC_ASN1_DER
, this->encoding
, CRED_PART_END
);
979 METHOD(certificate_t
, equals
, bool,
980 private_x509_ac_t
*this, certificate_t
*other
)
985 if ((certificate_t
*)this == other
)
989 if (other
->equals
== _equals
)
990 { /* skip allocation if we have the same implementation */
991 return chunk_equals(this->encoding
,
992 ((private_x509_ac_t
*)other
)->encoding
);
994 if (!other
->get_encoding(other
, CERT_ASN1_DER
, &encoding
))
998 equal
= chunk_equals(this->encoding
, encoding
);
1003 METHOD(certificate_t
, destroy
, void,
1004 private_x509_ac_t
*this)
1006 if (ref_put(&this->ref
))
1008 DESTROY_IF(this->holderIssuer
);
1009 DESTROY_IF(this->holderSerial
);
1010 DESTROY_IF(this->entityName
);
1011 DESTROY_IF(this->issuerName
);
1012 DESTROY_IF(this->holderCert
);
1013 DESTROY_IF(this->signerCert
);
1014 DESTROY_IF(this->signerKey
);
1015 this->groups
->destroy_function(this->groups
, (void*)group_destroy
);
1016 free(this->serialNumber
.ptr
);
1017 free(this->authKeyIdentifier
.ptr
);
1018 free(this->encoding
.ptr
);
1024 * create an empty but initialized X.509 attribute certificate
1026 static private_x509_ac_t
*create_empty(void)
1028 private_x509_ac_t
*this;
1034 .get_type
= _get_type
,
1035 .get_subject
= _get_subject
,
1036 .get_issuer
= _get_issuer
,
1037 .has_subject
= _has_subject
,
1038 .has_issuer
= _has_issuer
,
1039 .issued_by
= _issued_by
,
1040 .get_public_key
= _get_public_key
,
1041 .get_validity
= _get_validity
,
1042 .get_encoding
= _get_encoding
,
1044 .get_ref
= _get_ref
,
1045 .destroy
= _destroy
,
1047 .get_serial
= _get_serial
,
1048 .get_holderSerial
= _get_holderSerial
,
1049 .get_holderIssuer
= _get_holderIssuer
,
1050 .get_authKeyIdentifier
= _get_authKeyIdentifier
,
1051 .create_group_enumerator
= _create_group_enumerator
,
1054 .groups
= linked_list_create(),
1064 x509_ac_t
*x509_ac_load(certificate_type_t type
, va_list args
)
1066 chunk_t blob
= chunk_empty
;
1070 switch (va_arg(args
, builder_part_t
))
1072 case BUILD_BLOB_ASN1_DER
:
1073 blob
= va_arg(args
, chunk_t
);
1084 private_x509_ac_t
*ac
= create_empty();
1086 ac
->encoding
= chunk_clone(blob
);
1087 if (parse_certificate(ac
))
1097 * Add groups from a list into AC group memberships
1099 static void add_groups_from_list(private_x509_ac_t
*this, linked_list_t
*list
)
1101 enumerator_t
*enumerator
;
1105 enumerator
= list
->create_enumerator(list
);
1106 while (enumerator
->enumerate(enumerator
, &name
))
1109 .type
= AC_GROUP_TYPE_STRING
,
1110 .value
= chunk_clone(chunk_from_str(name
)),
1112 this->groups
->insert_last(this->groups
, group
);
1114 enumerator
->destroy(enumerator
);
1120 x509_ac_t
*x509_ac_gen(certificate_type_t type
, va_list args
)
1122 private_x509_ac_t
*ac
;
1124 ac
= create_empty();
1127 switch (va_arg(args
, builder_part_t
))
1129 case BUILD_NOT_BEFORE_TIME
:
1130 ac
->notBefore
= va_arg(args
, time_t);
1132 case BUILD_NOT_AFTER_TIME
:
1133 ac
->notAfter
= va_arg(args
, time_t);
1136 ac
->serialNumber
= chunk_clone(va_arg(args
, chunk_t
));
1138 case BUILD_AC_GROUP_STRINGS
:
1139 add_groups_from_list(ac
, va_arg(args
, linked_list_t
*));
1142 ac
->holderCert
= va_arg(args
, certificate_t
*);
1143 ac
->holderCert
->get_ref(ac
->holderCert
);
1145 case BUILD_SIGNING_CERT
:
1146 ac
->signerCert
= va_arg(args
, certificate_t
*);
1147 ac
->signerCert
->get_ref(ac
->signerCert
);
1149 case BUILD_SIGNING_KEY
:
1150 ac
->signerKey
= va_arg(args
, private_key_t
*);
1151 ac
->signerKey
->get_ref(ac
->signerKey
);
1162 if (ac
->signerKey
&& ac
->holderCert
&& ac
->signerCert
&&
1163 ac
->holderCert
->get_type(ac
->holderCert
) == CERT_X509
&&
1164 ac
->signerCert
->get_type(ac
->signerCert
) == CERT_X509
)