2 * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
3 * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
4 * Copyright (C) 2002 Mario Strasser
5 * Copyright (C) 2000-2006 Andreas Steffen
6 * Copyright (C) 2006-2008 Martin Willi
7 * Copyright (C) 2008 Tobias Brunner
8 * Hochschule fuer Technik Rapperswil
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 #include "x509_cert.h"
34 #include <asn1/asn1.h>
35 #include <asn1/asn1_parser.h>
36 #include <crypto/hashers/hasher.h>
37 #include <credentials/keys/private_key.h>
38 #include <utils/linked_list.h>
39 #include <utils/identification.h>
42 * Different kinds of generalNames
49 GN_DIRECTORY_NAME
= 4,
50 GN_EDI_PARTY_NAME
= 5,
57 typedef struct private_x509_cert_t private_x509_cert_t
;
60 * Private data of a x509_cert_t object.
62 struct private_x509_cert_t
{
64 * Public interface for this certificate.
69 * X.509 certificate encoding in ASN.1 DER format
74 * SHA1 hash of the DER encoding of this X.509 certificate
76 chunk_t encoding_hash
;
79 * X.509 certificate body over which signature is computed
81 chunk_t tbsCertificate
;
84 * Version of the X.509 certificate
89 * Serial number of the X.509 certificate
94 * ID representing the certificate issuer
96 identification_t
*issuer
;
99 * Start time of certificate validity
104 * End time of certificate validity
109 * ID representing the certificate subject
111 identification_t
*subject
;
114 * List of subjectAltNames as identification_t
116 linked_list_t
*subjectAltNames
;
119 * List of crlDistributionPoints as allocated char*
121 linked_list_t
*crl_uris
;
124 * List ocspAccessLocations as identification_t
126 linked_list_t
*ocsp_uris
;
129 * certificates embedded public key
131 public_key_t
*public_key
;
134 * Subject Key Identifier
136 chunk_t subjectKeyID
;
139 * Authority Key Identifier
141 chunk_t authKeyIdentifier
;
144 * Authority Key Serial Number
146 chunk_t authKeySerialNumber
;
149 * x509 constraints and other flags
154 * Signature algorithm
164 * Certificate parsed from blob/file?
174 static u_char ASN1_sAN_oid_buf
[] = {
175 0x06, 0x03, 0x55, 0x1D, 0x11
177 static const chunk_t ASN1_subjectAltName_oid
= chunk_from_buf(ASN1_sAN_oid_buf
);
180 * ASN.1 definition of a basicConstraints extension
182 static const asn1Object_t basicConstraintsObjects
[] = {
183 { 0, "basicConstraints", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
184 { 1, "CA", ASN1_BOOLEAN
, ASN1_DEF
|ASN1_BODY
}, /* 1 */
185 { 1, "pathLenConstraint", ASN1_INTEGER
, ASN1_OPT
|ASN1_BODY
}, /* 2 */
186 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 3 */
187 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
189 #define BASIC_CONSTRAINTS_CA 1
192 * Extracts the basicConstraints extension
194 static bool parse_basicConstraints(chunk_t blob
, int level0
)
196 asn1_parser_t
*parser
;
201 parser
= asn1_parser_create(basicConstraintsObjects
, blob
);
202 parser
->set_top_level(parser
, level0
);
204 while (parser
->iterate(parser
, &objectID
, &object
))
206 if (objectID
== BASIC_CONSTRAINTS_CA
)
208 isCA
= object
.len
&& *object
.ptr
;
209 DBG2(" %s", isCA ?
"TRUE" : "FALSE");
212 parser
->destroy(parser
);
218 * ASN.1 definition of otherName
220 static const asn1Object_t otherNameObjects
[] = {
221 {0, "type-id", ASN1_OID
, ASN1_BODY
}, /* 0 */
222 {0, "value", ASN1_CONTEXT_C_0
, ASN1_BODY
}, /* 1 */
223 {0, "exit", ASN1_EOC
, ASN1_EXIT
}
225 #define ON_OBJ_ID_TYPE 0
226 #define ON_OBJ_VALUE 1
229 * Extracts an otherName
231 static bool parse_otherName(chunk_t blob
, int level0
)
233 asn1_parser_t
*parser
;
236 int oid
= OID_UNKNOWN
;
237 bool success
= FALSE
;
239 parser
= asn1_parser_create(otherNameObjects
, blob
);
240 parser
->set_top_level(parser
, level0
);
242 while (parser
->iterate(parser
, &objectID
, &object
))
247 oid
= asn1_known_oid(object
);
250 if (oid
== OID_XMPP_ADDR
)
252 if (!asn1_parse_simple_object(&object
, ASN1_UTF8STRING
,
253 parser
->get_level(parser
)+1, "xmppAddr"))
263 success
= parser
->success(parser
);
266 parser
->destroy(parser
);
271 * ASN.1 definition of generalName
273 static const asn1Object_t generalNameObjects
[] = {
274 { 0, "otherName", ASN1_CONTEXT_C_0
, ASN1_OPT
|ASN1_BODY
}, /* 0 */
275 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 1 */
276 { 0, "rfc822Name", ASN1_CONTEXT_S_1
, ASN1_OPT
|ASN1_BODY
}, /* 2 */
277 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 3 */
278 { 0, "dnsName", ASN1_CONTEXT_S_2
, ASN1_OPT
|ASN1_BODY
}, /* 4 */
279 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 5 */
280 { 0, "x400Address", ASN1_CONTEXT_S_3
, ASN1_OPT
|ASN1_BODY
}, /* 6 */
281 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 7 */
282 { 0, "directoryName", ASN1_CONTEXT_C_4
, ASN1_OPT
|ASN1_BODY
}, /* 8 */
283 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 9 */
284 { 0, "ediPartyName", ASN1_CONTEXT_C_5
, ASN1_OPT
|ASN1_BODY
}, /* 10 */
285 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 11 */
286 { 0, "URI", ASN1_CONTEXT_S_6
, ASN1_OPT
|ASN1_BODY
}, /* 12 */
287 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 13 */
288 { 0, "ipAddress", ASN1_CONTEXT_S_7
, ASN1_OPT
|ASN1_BODY
}, /* 14 */
289 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 15 */
290 { 0, "registeredID", ASN1_CONTEXT_S_8
, ASN1_OPT
|ASN1_BODY
}, /* 16 */
291 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 17 */
292 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
294 #define GN_OBJ_OTHER_NAME 0
295 #define GN_OBJ_RFC822_NAME 2
296 #define GN_OBJ_DNS_NAME 4
297 #define GN_OBJ_X400_ADDRESS 6
298 #define GN_OBJ_DIRECTORY_NAME 8
299 #define GN_OBJ_EDI_PARTY_NAME 10
300 #define GN_OBJ_URI 12
301 #define GN_OBJ_IP_ADDRESS 14
302 #define GN_OBJ_REGISTERED_ID 16
305 * Extracts a generalName
307 static identification_t
*parse_generalName(chunk_t blob
, int level0
)
309 asn1_parser_t
*parser
;
313 identification_t
*gn
= NULL
;
315 parser
= asn1_parser_create(generalNameObjects
, blob
);
316 parser
->set_top_level(parser
, level0
);
318 while (parser
->iterate(parser
, &objectID
, &object
))
320 id_type_t id_type
= ID_ANY
;
324 case GN_OBJ_RFC822_NAME
:
325 id_type
= ID_RFC822_ADDR
;
327 case GN_OBJ_DNS_NAME
:
331 id_type
= ID_DER_ASN1_GN_URI
;
333 case GN_OBJ_DIRECTORY_NAME
:
334 id_type
= ID_DER_ASN1_DN
;
336 case GN_OBJ_IP_ADDRESS
:
337 id_type
= ID_IPV4_ADDR
;
339 case GN_OBJ_OTHER_NAME
:
340 if (!parse_otherName(object
, parser
->get_level(parser
)+1))
345 case GN_OBJ_X400_ADDRESS
:
346 case GN_OBJ_EDI_PARTY_NAME
:
347 case GN_OBJ_REGISTERED_ID
:
351 if (id_type
!= ID_ANY
)
353 gn
= identification_create_from_encoding(id_type
, object
);
360 parser
->destroy(parser
);
365 * ASN.1 definition of generalNames
367 static const asn1Object_t generalNamesObjects
[] = {
368 { 0, "generalNames", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
369 { 1, "generalName", ASN1_EOC
, ASN1_RAW
}, /* 1 */
370 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 2 */
371 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
373 #define GENERAL_NAMES_GN 1
376 * Extracts one or several GNs and puts them into a chained list
378 void x509_parse_generalNames(chunk_t blob
, int level0
, bool implicit
, linked_list_t
*list
)
380 asn1_parser_t
*parser
;
384 parser
= asn1_parser_create(generalNamesObjects
, blob
);
385 parser
->set_top_level(parser
, level0
);
386 parser
->set_flags(parser
, implicit
, FALSE
);
388 while (parser
->iterate(parser
, &objectID
, &object
))
390 if (objectID
== GENERAL_NAMES_GN
)
392 identification_t
*gn
= parse_generalName(object
,
393 parser
->get_level(parser
)+1);
397 list
->insert_last(list
, (void *)gn
);
401 parser
->destroy(parser
);
405 * ASN.1 definition of a authorityKeyIdentifier extension
407 static const asn1Object_t authKeyIdentifierObjects
[] = {
408 { 0, "authorityKeyIdentifier", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
409 { 1, "keyIdentifier", ASN1_CONTEXT_S_0
, ASN1_OPT
|ASN1_BODY
}, /* 1 */
410 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 2 */
411 { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1
, ASN1_OPT
|ASN1_OBJ
}, /* 3 */
412 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 4 */
413 { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2
, ASN1_OPT
|ASN1_BODY
}, /* 5 */
414 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 6 */
415 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
417 #define AUTH_KEY_ID_KEY_ID 1
418 #define AUTH_KEY_ID_CERT_ISSUER 3
419 #define AUTH_KEY_ID_CERT_SERIAL 5
422 * Extracts an authoritykeyIdentifier
424 chunk_t
x509_parse_authorityKeyIdentifier(chunk_t blob
, int level0
,
425 chunk_t
*authKeySerialNumber
)
427 asn1_parser_t
*parser
;
430 chunk_t authKeyIdentifier
= chunk_empty
;
432 *authKeySerialNumber
= chunk_empty
;
434 parser
= asn1_parser_create(authKeyIdentifierObjects
, blob
);
435 parser
->set_top_level(parser
, level0
);
437 while (parser
->iterate(parser
, &objectID
, &object
))
441 case AUTH_KEY_ID_KEY_ID
:
442 authKeyIdentifier
= chunk_clone(object
);
444 case AUTH_KEY_ID_CERT_ISSUER
:
445 /* TODO: x509_parse_generalNames(object, level+1, TRUE); */
447 case AUTH_KEY_ID_CERT_SERIAL
:
448 *authKeySerialNumber
= object
;
454 parser
->destroy(parser
);
455 return authKeyIdentifier
;
459 * ASN.1 definition of a authorityInfoAccess extension
461 static const asn1Object_t authInfoAccessObjects
[] = {
462 { 0, "authorityInfoAccess", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
463 { 1, "accessDescription", ASN1_SEQUENCE
, ASN1_NONE
}, /* 1 */
464 { 2, "accessMethod", ASN1_OID
, ASN1_BODY
}, /* 2 */
465 { 2, "accessLocation", ASN1_EOC
, ASN1_RAW
}, /* 3 */
466 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 4 */
467 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
469 #define AUTH_INFO_ACCESS_METHOD 2
470 #define AUTH_INFO_ACCESS_LOCATION 3
473 * Extracts an authorityInfoAcess location
475 static void parse_authorityInfoAccess(chunk_t blob
, int level0
,
476 private_x509_cert_t
*this)
478 asn1_parser_t
*parser
;
481 int accessMethod
= OID_UNKNOWN
;
483 parser
= asn1_parser_create(authInfoAccessObjects
, blob
);
484 parser
->set_top_level(parser
, level0
);
486 while (parser
->iterate(parser
, &objectID
, &object
))
490 case AUTH_INFO_ACCESS_METHOD
:
491 accessMethod
= asn1_known_oid(object
);
493 case AUTH_INFO_ACCESS_LOCATION
:
495 switch (accessMethod
)
500 identification_t
*id
;
503 id
= parse_generalName(object
,
504 parser
->get_level(parser
)+1);
507 /* parsing went wrong - abort */
511 if (accessMethod
== OID_OCSP
&&
512 asprintf(&uri
, "%Y", id
) > 0)
514 this->ocsp_uris
->insert_last(this->ocsp_uris
, uri
);
520 /* unkown accessMethod, ignoring */
531 parser
->destroy(parser
);
535 * ASN.1 definition of a extendedKeyUsage extension
537 static const asn1Object_t extendedKeyUsageObjects
[] = {
538 { 0, "extendedKeyUsage", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
539 { 1, "keyPurposeID", ASN1_OID
, ASN1_BODY
}, /* 1 */
540 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 2 */
541 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
543 #define EXT_KEY_USAGE_PURPOSE_ID 1
546 * Extracts extendedKeyUsage OIDs - currently only OCSP_SIGING is returned
548 static bool parse_extendedKeyUsage(chunk_t blob
, int level0
)
550 asn1_parser_t
*parser
;
553 bool ocsp_signing
= FALSE
;
555 parser
= asn1_parser_create(extendedKeyUsageObjects
, blob
);
556 parser
->set_top_level(parser
, level0
);
558 while (parser
->iterate(parser
, &objectID
, &object
))
560 if (objectID
== EXT_KEY_USAGE_PURPOSE_ID
&&
561 asn1_known_oid(object
) == OID_OCSP_SIGNING
)
566 parser
->destroy(parser
);
571 * ASN.1 definition of crlDistributionPoints
573 static const asn1Object_t crlDistributionPointsObjects
[] = {
574 { 0, "crlDistributionPoints", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
575 { 1, "DistributionPoint", ASN1_SEQUENCE
, ASN1_NONE
}, /* 1 */
576 { 2, "distributionPoint", ASN1_CONTEXT_C_0
, ASN1_OPT
|ASN1_LOOP
}, /* 2 */
577 { 3, "fullName", ASN1_CONTEXT_C_0
, ASN1_OPT
|ASN1_OBJ
}, /* 3 */
578 { 3, "end choice", ASN1_EOC
, ASN1_END
}, /* 4 */
579 { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1
, ASN1_OPT
|ASN1_BODY
}, /* 5 */
580 { 3, "end choice", ASN1_EOC
, ASN1_END
}, /* 6 */
581 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 7 */
582 { 2, "reasons", ASN1_CONTEXT_C_1
, ASN1_OPT
|ASN1_BODY
}, /* 8 */
583 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 9 */
584 { 2, "crlIssuer", ASN1_CONTEXT_C_2
, ASN1_OPT
|ASN1_BODY
}, /* 10 */
585 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 11 */
586 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 12 */
587 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
589 #define CRL_DIST_POINTS_FULLNAME 3
592 * Extracts one or several crlDistributionPoints into a list
594 static void parse_crlDistributionPoints(chunk_t blob
, int level0
,
595 private_x509_cert_t
*this)
597 asn1_parser_t
*parser
;
600 linked_list_t
*list
= linked_list_create();
602 parser
= asn1_parser_create(crlDistributionPointsObjects
, blob
);
603 parser
->set_top_level(parser
, level0
);
605 while (parser
->iterate(parser
, &objectID
, &object
))
607 if (objectID
== CRL_DIST_POINTS_FULLNAME
)
609 identification_t
*id
;
611 /* append extracted generalNames to existing chained list */
612 x509_parse_generalNames(object
, parser
->get_level(parser
)+1,
615 while (list
->remove_last(list
, (void**)&id
) == SUCCESS
)
619 if (asprintf(&uri
, "%Y", id
) > 0)
621 this->crl_uris
->insert_last(this->crl_uris
, uri
);
627 parser
->destroy(parser
);
632 * ASN.1 definition of an X.509v3 x509_cert
634 static const asn1Object_t certObjects
[] = {
635 { 0, "x509", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 0 */
636 { 1, "tbsCertificate", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 1 */
637 { 2, "DEFAULT v1", ASN1_CONTEXT_C_0
, ASN1_DEF
}, /* 2 */
638 { 3, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
639 { 2, "serialNumber", ASN1_INTEGER
, ASN1_BODY
}, /* 4 */
640 { 2, "signature", ASN1_EOC
, ASN1_RAW
}, /* 5 */
641 { 2, "issuer", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 6 */
642 { 2, "validity", ASN1_SEQUENCE
, ASN1_NONE
}, /* 7 */
643 { 3, "notBefore", ASN1_EOC
, ASN1_RAW
}, /* 8 */
644 { 3, "notAfter", ASN1_EOC
, ASN1_RAW
}, /* 9 */
645 { 2, "subject", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 10 */
646 { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE
, ASN1_RAW
}, /* 11 */
647 { 2, "issuerUniqueID", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 12 */
648 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 13 */
649 { 2, "subjectUniqueID", ASN1_CONTEXT_C_2
, ASN1_OPT
}, /* 14 */
650 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 15 */
651 { 2, "optional extensions", ASN1_CONTEXT_C_3
, ASN1_OPT
}, /* 16 */
652 { 3, "extensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 17 */
653 { 4, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 18 */
654 { 5, "extnID", ASN1_OID
, ASN1_BODY
}, /* 19 */
655 { 5, "critical", ASN1_BOOLEAN
, ASN1_DEF
|ASN1_BODY
}, /* 20 */
656 { 5, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 21 */
657 { 3, "end loop", ASN1_EOC
, ASN1_END
}, /* 22 */
658 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 23 */
659 { 1, "signatureAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 24 */
660 { 1, "signatureValue", ASN1_BIT_STRING
, ASN1_BODY
}, /* 25 */
661 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
663 #define X509_OBJ_TBS_CERTIFICATE 1
664 #define X509_OBJ_VERSION 3
665 #define X509_OBJ_SERIAL_NUMBER 4
666 #define X509_OBJ_SIG_ALG 5
667 #define X509_OBJ_ISSUER 6
668 #define X509_OBJ_NOT_BEFORE 8
669 #define X509_OBJ_NOT_AFTER 9
670 #define X509_OBJ_SUBJECT 10
671 #define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO 11
672 #define X509_OBJ_EXTN_ID 19
673 #define X509_OBJ_CRITICAL 20
674 #define X509_OBJ_EXTN_VALUE 21
675 #define X509_OBJ_ALGORITHM 24
676 #define X509_OBJ_SIGNATURE 25
679 * Parses an X.509v3 certificate
681 static bool parse_certificate(private_x509_cert_t
*this)
683 asn1_parser_t
*parser
;
686 int extn_oid
= OID_UNKNOWN
;
687 int sig_alg
= OID_UNKNOWN
;
688 bool success
= FALSE
;
691 parser
= asn1_parser_create(certObjects
, this->encoding
);
693 while (parser
->iterate(parser
, &objectID
, &object
))
695 u_int level
= parser
->get_level(parser
)+1;
699 case X509_OBJ_TBS_CERTIFICATE
:
700 this->tbsCertificate
= object
;
702 case X509_OBJ_VERSION
:
703 this->version
= (object
.len
) ?
(1+(u_int
)*object
.ptr
) : 1;
704 DBG2(" v%d", this->version
);
706 case X509_OBJ_SERIAL_NUMBER
:
707 this->serialNumber
= object
;
709 case X509_OBJ_SIG_ALG
:
710 sig_alg
= asn1_parse_algorithmIdentifier(object
, level
, NULL
);
712 case X509_OBJ_ISSUER
:
713 this->issuer
= identification_create_from_encoding(ID_DER_ASN1_DN
, object
);
714 DBG2(" '%Y'", this->issuer
);
716 case X509_OBJ_NOT_BEFORE
:
717 this->notBefore
= asn1_parse_time(object
, level
);
719 case X509_OBJ_NOT_AFTER
:
720 this->notAfter
= asn1_parse_time(object
, level
);
722 case X509_OBJ_SUBJECT
:
723 this->subject
= identification_create_from_encoding(ID_DER_ASN1_DN
, object
);
724 DBG2(" '%Y'", this->subject
);
726 case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO
:
727 this->public_key
= lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
,
728 KEY_ANY
, BUILD_BLOB_ASN1_DER
, object
, BUILD_END
);
729 if (this->public_key
== NULL
)
734 case X509_OBJ_EXTN_ID
:
735 extn_oid
= asn1_known_oid(object
);
737 case X509_OBJ_CRITICAL
:
738 critical
= object
.len
&& *object
.ptr
;
739 DBG2(" %s", critical ?
"TRUE" : "FALSE");
741 case X509_OBJ_EXTN_VALUE
:
745 case OID_SUBJECT_KEY_ID
:
746 if (!asn1_parse_simple_object(&object
, ASN1_OCTET_STRING
,
747 level
, "keyIdentifier"))
751 this->subjectKeyID
= object
;
753 case OID_SUBJECT_ALT_NAME
:
754 x509_parse_generalNames(object
, level
, FALSE
,
755 this->subjectAltNames
);
757 case OID_BASIC_CONSTRAINTS
:
758 if (parse_basicConstraints(object
, level
))
760 this->flags
|= X509_CA
;
763 case OID_CRL_DISTRIBUTION_POINTS
:
764 parse_crlDistributionPoints(object
, level
, this);
766 case OID_AUTHORITY_KEY_ID
:
767 this->authKeyIdentifier
= x509_parse_authorityKeyIdentifier(object
,
768 level
, &this->authKeySerialNumber
);
770 case OID_AUTHORITY_INFO_ACCESS
:
771 parse_authorityInfoAccess(object
, level
, this);
773 case OID_EXTENDED_KEY_USAGE
:
774 if (parse_extendedKeyUsage(object
, level
))
776 this->flags
|= X509_OCSP_SIGNER
;
779 case OID_NS_REVOCATION_URL
:
780 case OID_NS_CA_REVOCATION_URL
:
781 case OID_NS_CA_POLICY_URL
:
783 if (!asn1_parse_simple_object(&object
, ASN1_IA5STRING
,
784 level
, oid_names
[extn_oid
].name
))
794 case X509_OBJ_ALGORITHM
:
795 this->algorithm
= asn1_parse_algorithmIdentifier(object
, level
, NULL
);
796 if (this->algorithm
!= sig_alg
)
798 DBG1(" signature algorithms do not agree");
802 case X509_OBJ_SIGNATURE
:
803 this->signature
= object
;
809 success
= parser
->success(parser
);
812 parser
->destroy(parser
);
817 * Implementation of certificate_t.get_type
819 static certificate_type_t
get_type(private_x509_cert_t
*this)
825 * Implementation of certificate_t.get_subject
827 static identification_t
* get_subject(private_x509_cert_t
*this)
829 return this->subject
;
833 * Implementation of certificate_t.get_issuer
835 static identification_t
* get_issuer(private_x509_cert_t
*this)
841 * Implementation of certificate_t.has_subject.
843 static id_match_t
has_subject(private_x509_cert_t
*this, identification_t
*subject
)
845 identification_t
*current
;
846 enumerator_t
*enumerator
;
847 id_match_t match
, best
;
849 if (this->encoding_hash
.ptr
&& subject
->get_type(subject
) == ID_KEY_ID
)
851 if (chunk_equals(this->encoding_hash
, subject
->get_encoding(subject
)))
853 return ID_MATCH_PERFECT
;
857 best
= this->subject
->matches(this->subject
, subject
);
858 enumerator
= this->subjectAltNames
->create_enumerator(this->subjectAltNames
);
859 while (enumerator
->enumerate(enumerator
, ¤t
))
861 match
= current
->matches(current
, subject
);
867 enumerator
->destroy(enumerator
);
872 * Implementation of certificate_t.has_subject.
874 static id_match_t
has_issuer(private_x509_cert_t
*this, identification_t
*issuer
)
876 /* issuerAltNames currently not supported */
877 return this->issuer
->matches(this->issuer
, issuer
);
881 * Implementation of certificate_t.issued_by
883 static bool issued_by(private_x509_cert_t
*this, certificate_t
*issuer
)
886 signature_scheme_t scheme
;
888 x509_t
*x509
= (x509_t
*)issuer
;
890 if (&this->public.interface
.interface
== issuer
)
892 if (this->flags
& X509_SELF_SIGNED
)
899 if (issuer
->get_type(issuer
) != CERT_X509
)
903 if (!(x509
->get_flags(x509
) & X509_CA
))
908 if (!this->issuer
->equals(this->issuer
, issuer
->get_subject(issuer
)))
913 /* get the public key of the issuer */
914 key
= issuer
->get_public_key(issuer
);
916 /* determine signature scheme */
917 scheme
= signature_scheme_from_oid(this->algorithm
);
919 if (scheme
== SIGN_UNKNOWN
|| key
== NULL
)
923 /* TODO: add a lightweight check option (comparing auth/subject keyids only) */
924 valid
= key
->verify(key
, scheme
, this->tbsCertificate
, this->signature
);
930 * Implementation of certificate_t.get_public_key
932 static public_key_t
* get_public_key(private_x509_cert_t
*this)
934 this->public_key
->get_ref(this->public_key
);
935 return this->public_key
;
939 * Implementation of certificate_t.asdf
941 static private_x509_cert_t
* get_ref(private_x509_cert_t
*this)
948 * Implementation of x509_cert_t.get_flags.
950 static x509_flag_t
get_flags(private_x509_cert_t
*this)
956 * Implementation of x509_cert_t.get_validity.
958 static bool get_validity(private_x509_cert_t
*this, time_t *when
,
959 time_t *not_before
, time_t *not_after
)
973 *not_before
= this->notBefore
;
977 *not_after
= this->notAfter
;
979 return (t
>= this->notBefore
&& t
<= this->notAfter
);
983 * Implementation of certificate_t.is_newer.
985 static bool is_newer(certificate_t
*this, certificate_t
*that
)
987 time_t this_update
, that_update
, now
= time(NULL
);
990 this->get_validity(this, &now
, &this_update
, NULL
);
991 that
->get_validity(that
, &now
, &that_update
, NULL
);
992 new = this_update
> that_update
;
993 DBG1(" certificate from %T is %s - existing certificate from %T %s",
994 &this_update
, FALSE
, new ?
"newer":"not newer",
995 &that_update
, FALSE
, new ?
"replaced":"retained");
1000 * Implementation of certificate_t.get_encoding.
1002 static chunk_t
get_encoding(private_x509_cert_t
*this)
1004 return chunk_clone(this->encoding
);
1008 * Implementation of certificate_t.equals.
1010 static bool equals(private_x509_cert_t
*this, certificate_t
*other
)
1015 if (this == (private_x509_cert_t
*)other
)
1019 if (other
->get_type(other
) != CERT_X509
)
1023 if (other
->equals
== (void*)equals
)
1024 { /* skip allocation if we have the same implementation */
1025 return chunk_equals(this->encoding
, ((private_x509_cert_t
*)other
)->encoding
);
1027 encoding
= other
->get_encoding(other
);
1028 equal
= chunk_equals(this->encoding
, encoding
);
1034 * Implementation of x509_t.get_serial.
1036 static chunk_t
get_serial(private_x509_cert_t
*this)
1038 return this->serialNumber
;
1042 * Implementation of x509_t.get_authKeyIdentifier.
1044 static chunk_t
get_authKeyIdentifier(private_x509_cert_t
*this)
1046 return this->authKeyIdentifier
;
1050 * Implementation of x509_cert_t.create_subjectAltName_enumerator.
1052 static enumerator_t
* create_subjectAltName_enumerator(private_x509_cert_t
*this)
1054 return this->subjectAltNames
->create_enumerator(this->subjectAltNames
);
1058 * Implementation of x509_cert_t.create_ocsp_uri_enumerator.
1060 static enumerator_t
* create_ocsp_uri_enumerator(private_x509_cert_t
*this)
1062 return this->ocsp_uris
->create_enumerator(this->ocsp_uris
);
1066 * Implementation of x509_cert_t.create_crl_uri_enumerator.
1068 static enumerator_t
* create_crl_uri_enumerator(private_x509_cert_t
*this)
1070 return this->crl_uris
->create_enumerator(this->crl_uris
);
1074 * Implementation of certificate_t.asdf
1076 static void destroy(private_x509_cert_t
*this)
1078 if (ref_put(&this->ref
))
1080 this->subjectAltNames
->destroy_offset(this->subjectAltNames
,
1081 offsetof(identification_t
, destroy
));
1082 this->crl_uris
->destroy_function(this->crl_uris
, free
);
1083 this->ocsp_uris
->destroy_function(this->ocsp_uris
, free
);
1084 DESTROY_IF(this->issuer
);
1085 DESTROY_IF(this->subject
);
1086 DESTROY_IF(this->public_key
);
1087 chunk_free(&this->authKeyIdentifier
);
1088 chunk_free(&this->encoding
);
1089 chunk_free(&this->encoding_hash
);
1091 { /* only parsed certificates point these fields to "encoded" */
1092 chunk_free(&this->signature
);
1093 chunk_free(&this->serialNumber
);
1094 chunk_free(&this->tbsCertificate
);
1101 * create an empty but initialized X.509 certificate
1103 static private_x509_cert_t
* create_empty(void)
1105 private_x509_cert_t
*this = malloc_thing(private_x509_cert_t
);
1107 this->public.interface
.interface
.get_type
= (certificate_type_t (*) (certificate_t
*))get_type
;
1108 this->public.interface
.interface
.get_subject
= (identification_t
* (*) (certificate_t
*))get_subject
;
1109 this->public.interface
.interface
.get_issuer
= (identification_t
* (*) (certificate_t
*))get_issuer
;
1110 this->public.interface
.interface
.has_subject
= (id_match_t (*) (certificate_t
*, identification_t
*))has_subject
;
1111 this->public.interface
.interface
.has_issuer
= (id_match_t (*) (certificate_t
*, identification_t
*))has_issuer
;
1112 this->public.interface
.interface
.issued_by
= (bool (*) (certificate_t
*, certificate_t
*))issued_by
;
1113 this->public.interface
.interface
.get_public_key
= (public_key_t
* (*) (certificate_t
*))get_public_key
;
1114 this->public.interface
.interface
.get_validity
= (bool (*) (certificate_t
*, time_t*, time_t*, time_t*))get_validity
;
1115 this->public.interface
.interface
.is_newer
= (bool (*) (certificate_t
*,certificate_t
*))is_newer
;
1116 this->public.interface
.interface
.get_encoding
= (chunk_t (*) (certificate_t
*))get_encoding
;
1117 this->public.interface
.interface
.equals
= (bool (*)(certificate_t
*, certificate_t
*))equals
;
1118 this->public.interface
.interface
.get_ref
= (certificate_t
* (*)(certificate_t
*))get_ref
;
1119 this->public.interface
.interface
.destroy
= (void (*)(certificate_t
*))destroy
;
1120 this->public.interface
.get_flags
= (x509_flag_t (*)(x509_t
*))get_flags
;
1121 this->public.interface
.get_serial
= (chunk_t (*)(x509_t
*))get_serial
;
1122 this->public.interface
.get_authKeyIdentifier
= (chunk_t (*)(x509_t
*))get_authKeyIdentifier
;
1123 this->public.interface
.create_subjectAltName_enumerator
= (enumerator_t
* (*)(x509_t
*))create_subjectAltName_enumerator
;
1124 this->public.interface
.create_crl_uri_enumerator
= (enumerator_t
* (*)(x509_t
*))create_crl_uri_enumerator
;
1125 this->public.interface
.create_ocsp_uri_enumerator
= (enumerator_t
* (*)(x509_t
*))create_ocsp_uri_enumerator
;
1127 this->encoding
= chunk_empty
;
1128 this->encoding_hash
= chunk_empty
;
1129 this->tbsCertificate
= chunk_empty
;
1131 this->serialNumber
= chunk_empty
;
1132 this->notBefore
= 0;
1134 this->public_key
= NULL
;
1135 this->subject
= NULL
;
1136 this->issuer
= NULL
;
1137 this->subjectAltNames
= linked_list_create();
1138 this->crl_uris
= linked_list_create();
1139 this->ocsp_uris
= linked_list_create();
1140 this->subjectKeyID
= chunk_empty
;
1141 this->authKeyIdentifier
= chunk_empty
;
1142 this->authKeySerialNumber
= chunk_empty
;
1143 this->algorithm
= 0;
1144 this->signature
= chunk_empty
;
1147 this->parsed
= FALSE
;
1153 * create an X.509 certificate from a chunk
1155 static private_x509_cert_t
*create_from_chunk(chunk_t chunk
)
1158 private_x509_cert_t
*this = create_empty();
1160 this->encoding
= chunk
;
1161 this->parsed
= TRUE
;
1162 if (!parse_certificate(this))
1168 /* check if the certificate is self-signed */
1169 if (issued_by(this, &this->public.interface
.interface
))
1171 this->flags
|= X509_SELF_SIGNED
;
1174 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
1177 DBG1(" unable to create hash of certificate, SHA1 not supported");
1181 hasher
->allocate_hash(hasher
, this->encoding
, &this->encoding_hash
);
1182 hasher
->destroy(hasher
);
1187 typedef struct private_builder_t private_builder_t
;
1189 * Builder implementation for certificate loading
1191 struct private_builder_t
{
1192 /** implements the builder interface */
1194 /** loaded certificate */
1195 private_x509_cert_t
*cert
;
1196 /** additional flags to enforce */
1198 /** certificate to sign, if we generate a new cert */
1199 certificate_t
*sign_cert
;
1200 /** private key to sign, if we generate a new cert */
1201 private_key_t
*sign_key
;
1205 * Generate and sign a new certificate
1207 static bool generate(private_builder_t
*this)
1209 chunk_t extensions
= chunk_empty
;
1210 identification_t
*issuer
, *subject
;
1212 signature_scheme_t scheme
;
1215 subject
= this->cert
->subject
;
1216 if (this->sign_cert
)
1218 issuer
= this->sign_cert
->get_subject(this->sign_cert
);
1219 if (!this->cert
->public_key
)
1227 if (!this->cert
->public_key
)
1229 this->cert
->public_key
= this->sign_key
->get_public_key(this->sign_key
);
1231 this->flags
|= X509_SELF_SIGNED
;
1233 this->cert
->issuer
= issuer
->clone(issuer
);
1234 if (!this->cert
->notBefore
)
1236 this->cert
->notBefore
= time(NULL
);
1238 if (!this->cert
->notAfter
)
1239 { /* defaults to 1 years from now on */
1240 this->cert
->notAfter
= this->cert
->notBefore
+ 60 * 60 * 24 * 365;
1242 this->cert
->flags
= this->flags
;
1244 /* select signature scheme. TODO: support other hashes. */
1245 switch (this->sign_key
->get_type(this->sign_key
))
1248 this->cert
->algorithm
= OID_SHA1_WITH_RSA
;
1249 scheme
= SIGN_RSA_EMSA_PKCS1_SHA1
;
1252 scheme
= SIGN_ECDSA_WITH_SHA1_DER
;
1253 this->cert
->algorithm
= OID_ECDSA_WITH_SHA1
;
1258 if (!this->cert
->public_key
->get_encoding(this->cert
->public_key
,
1259 KEY_PUB_SPKI_ASN1_DER
, &key_info
))
1263 if (this->cert
->subjectAltNames
->get_count(this->cert
->subjectAltNames
))
1265 /* TODO: encode subjectAltNames */
1268 this->cert
->tbsCertificate
= asn1_wrap(ASN1_SEQUENCE
, "mmmcmcmm",
1269 asn1_simple_object(ASN1_CONTEXT_C_0
, ASN1_INTEGER_2
),
1270 asn1_integer("c", this->cert
->serialNumber
),
1271 asn1_algorithmIdentifier(this->cert
->algorithm
),
1272 issuer
->get_encoding(issuer
),
1273 asn1_wrap(ASN1_SEQUENCE
, "mm",
1274 asn1_from_time(&this->cert
->notBefore
, ASN1_UTCTIME
),
1275 asn1_from_time(&this->cert
->notAfter
, ASN1_UTCTIME
)),
1276 subject
->get_encoding(subject
),
1277 key_info
, extensions
);
1279 if (!this->sign_key
->sign(this->sign_key
, scheme
,
1280 this->cert
->tbsCertificate
, &this->cert
->signature
))
1284 this->cert
->encoding
= asn1_wrap(ASN1_SEQUENCE
, "cmm",
1285 this->cert
->tbsCertificate
,
1286 asn1_algorithmIdentifier(this->cert
->algorithm
),
1287 asn1_bitstring("c", this->cert
->signature
));
1289 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
1294 hasher
->allocate_hash(hasher
, this->cert
->encoding
,
1295 &this->cert
->encoding_hash
);
1296 hasher
->destroy(hasher
);
1301 * Implementation of builder_t.build
1303 static private_x509_cert_t
*build(private_builder_t
*this)
1305 private_x509_cert_t
*cert
;
1309 this->cert
->flags
|= this->flags
;
1310 if (!this->cert
->encoding
.ptr
)
1311 { /* generate a new certificate */
1312 if (!this->sign_key
|| !generate(this))
1314 destroy(this->cert
);
1326 * Implementation of builder_t.add
1328 static void add(private_builder_t
*this, builder_part_t part
, ...)
1332 bool handled
= TRUE
;
1334 va_start(args
, part
);
1337 case BUILD_BLOB_ASN1_DER
:
1338 chunk
= va_arg(args
, chunk_t
);
1339 this->cert
= create_from_chunk(chunk_clone(chunk
));
1341 case BUILD_X509_FLAG
:
1342 this->flags
= va_arg(args
, x509_flag_t
);
1344 case BUILD_SIGNING_KEY
:
1345 this->sign_key
= va_arg(args
, private_key_t
*);
1347 case BUILD_SIGNING_CERT
:
1348 this->sign_cert
= va_arg(args
, certificate_t
*);
1351 /* all other parts need an empty cert */
1354 this->cert
= create_empty();
1367 case BUILD_PUBLIC_KEY
:
1369 public_key_t
*key
= va_arg(args
, public_key_t
*);
1370 this->cert
->public_key
= key
->get_ref(key
);
1375 identification_t
*id
= va_arg(args
, identification_t
*);
1376 this->cert
->subject
= id
->clone(id
);
1379 case BUILD_SUBJECT_ALTNAME
:
1381 identification_t
*id
= va_arg(args
, identification_t
*);
1382 this->cert
->subjectAltNames
->insert_last(
1383 this->cert
->subjectAltNames
, id
->clone(id
));
1386 case BUILD_NOT_BEFORE_TIME
:
1387 this->cert
->notBefore
= va_arg(args
, time_t);
1389 case BUILD_NOT_AFTER_TIME
:
1390 this->cert
->notAfter
= va_arg(args
, time_t);
1394 chunk_t serial
= va_arg(args
, chunk_t
);
1395 this->cert
->serialNumber
= chunk_clone(serial
);
1399 /* abort if unsupported option */
1402 destroy(this->cert
);
1404 builder_cancel(&this->public);
1411 * Builder construction function
1413 builder_t
*x509_cert_builder(certificate_type_t type
)
1415 private_builder_t
*this;
1417 if (type
!= CERT_X509
)
1422 this = malloc_thing(private_builder_t
);
1426 this->sign_cert
= NULL
;
1427 this->sign_key
= NULL
;
1428 this->public.add
= (void(*)(builder_t
*this, builder_part_t part
, ...))add
;
1429 this->public.build
= (void*(*)(builder_t
*this))build
;
1431 return &this->public;