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
25 #include "x509_cert.h"
36 #include <asn1/asn1.h>
37 #include <asn1/asn1_parser.h>
39 #include <crypto/hashers/hasher.h>
40 #include <utils/linked_list.h>
41 #include <utils/identification.h>
44 * Different kinds of generalNames
51 GN_DIRECTORY_NAME
= 4,
52 GN_EDI_PARTY_NAME
= 5,
59 typedef struct private_x509_cert_t private_x509_cert_t
;
62 * Private data of a x509_cert_t object.
64 struct private_x509_cert_t
{
66 * Public interface for this certificate.
71 * X.509 certificate encoding in ASN.1 DER format
76 * SHA1 hash of the DER encoding of this X.509 certificate
78 chunk_t encoding_hash
;
81 * X.509 certificate body over which signature is computed
83 chunk_t tbsCertificate
;
86 * Version of the X.509 certificate
91 * Serial number of the X.509 certificate
96 * ID representing the certificate issuer
98 identification_t
*issuer
;
101 * Start time of certificate validity
106 * End time of certificate validity
111 * ID representing the certificate subject
113 identification_t
*subject
;
116 * List of subjectAltNames as identification_t
118 linked_list_t
*subjectAltNames
;
121 * List of crlDistributionPoints as allocated char*
123 linked_list_t
*crl_uris
;
126 * List ocspAccessLocations as identification_t
128 linked_list_t
*ocsp_uris
;
131 * certificates embedded public key
133 public_key_t
*public_key
;
136 * Subject Key Identifier
138 chunk_t subjectKeyID
;
141 * Authority Key Identifier
143 identification_t
*authKeyIdentifier
;
146 * Authority Key Serial Number
148 chunk_t authKeySerialNumber
;
151 * x509 constraints and other flags
156 * Signature algorithm
166 * Certificate parsed from blob/file?
176 static u_char ASN1_sAN_oid_buf
[] = {
177 0x06, 0x03, 0x55, 0x1D, 0x11
179 static const chunk_t ASN1_subjectAltName_oid
= chunk_from_buf(ASN1_sAN_oid_buf
);
182 * ASN.1 definition of a basicConstraints extension
184 static const asn1Object_t basicConstraintsObjects
[] = {
185 { 0, "basicConstraints", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
186 { 1, "CA", ASN1_BOOLEAN
, ASN1_DEF
|ASN1_BODY
}, /* 1 */
187 { 1, "pathLenConstraint", ASN1_INTEGER
, ASN1_OPT
|ASN1_BODY
}, /* 2 */
188 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 3 */
189 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
191 #define BASIC_CONSTRAINTS_CA 1
194 * Extracts the basicConstraints extension
196 static bool parse_basicConstraints(chunk_t blob
, int level0
)
198 asn1_parser_t
*parser
;
203 parser
= asn1_parser_create(basicConstraintsObjects
, blob
);
204 parser
->set_top_level(parser
, level0
);
206 while (parser
->iterate(parser
, &objectID
, &object
))
208 if (objectID
== BASIC_CONSTRAINTS_CA
)
210 isCA
= object
.len
&& *object
.ptr
;
211 DBG2(" %s", isCA ?
"TRUE" : "FALSE");
214 parser
->destroy(parser
);
220 * ASN.1 definition of otherName
222 static const asn1Object_t otherNameObjects
[] = {
223 {0, "type-id", ASN1_OID
, ASN1_BODY
}, /* 0 */
224 {0, "value", ASN1_CONTEXT_C_0
, ASN1_BODY
}, /* 1 */
225 {0, "exit", ASN1_EOC
, ASN1_EXIT
}
227 #define ON_OBJ_ID_TYPE 0
228 #define ON_OBJ_VALUE 1
231 * Extracts an otherName
233 static bool parse_otherName(chunk_t blob
, int level0
)
235 asn1_parser_t
*parser
;
238 int oid
= OID_UNKNOWN
;
239 bool success
= FALSE
;
241 parser
= asn1_parser_create(otherNameObjects
, blob
);
242 parser
->set_top_level(parser
, level0
);
244 while (parser
->iterate(parser
, &objectID
, &object
))
249 oid
= asn1_known_oid(object
);
252 if (oid
== OID_XMPP_ADDR
)
254 if (!asn1_parse_simple_object(&object
, ASN1_UTF8STRING
,
255 parser
->get_level(parser
)+1, "xmppAddr"))
265 success
= parser
->success(parser
);
268 parser
->destroy(parser
);
273 * ASN.1 definition of generalName
275 static const asn1Object_t generalNameObjects
[] = {
276 { 0, "otherName", ASN1_CONTEXT_C_0
, ASN1_OPT
|ASN1_BODY
}, /* 0 */
277 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 1 */
278 { 0, "rfc822Name", ASN1_CONTEXT_S_1
, ASN1_OPT
|ASN1_BODY
}, /* 2 */
279 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 3 */
280 { 0, "dnsName", ASN1_CONTEXT_S_2
, ASN1_OPT
|ASN1_BODY
}, /* 4 */
281 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 5 */
282 { 0, "x400Address", ASN1_CONTEXT_S_3
, ASN1_OPT
|ASN1_BODY
}, /* 6 */
283 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 7 */
284 { 0, "directoryName", ASN1_CONTEXT_C_4
, ASN1_OPT
|ASN1_BODY
}, /* 8 */
285 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 9 */
286 { 0, "ediPartyName", ASN1_CONTEXT_C_5
, ASN1_OPT
|ASN1_BODY
}, /* 10 */
287 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 11 */
288 { 0, "URI", ASN1_CONTEXT_S_6
, ASN1_OPT
|ASN1_BODY
}, /* 12 */
289 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 13 */
290 { 0, "ipAddress", ASN1_CONTEXT_S_7
, ASN1_OPT
|ASN1_BODY
}, /* 14 */
291 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 15 */
292 { 0, "registeredID", ASN1_CONTEXT_S_8
, ASN1_OPT
|ASN1_BODY
}, /* 16 */
293 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 17 */
294 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
296 #define GN_OBJ_OTHER_NAME 0
297 #define GN_OBJ_RFC822_NAME 2
298 #define GN_OBJ_DNS_NAME 4
299 #define GN_OBJ_X400_ADDRESS 6
300 #define GN_OBJ_DIRECTORY_NAME 8
301 #define GN_OBJ_EDI_PARTY_NAME 10
302 #define GN_OBJ_URI 12
303 #define GN_OBJ_IP_ADDRESS 14
304 #define GN_OBJ_REGISTERED_ID 16
307 * Extracts a generalName
309 static identification_t
*parse_generalName(chunk_t blob
, int level0
)
311 asn1_parser_t
*parser
;
315 identification_t
*gn
= NULL
;
317 parser
= asn1_parser_create(generalNameObjects
, blob
);
318 parser
->set_top_level(parser
, level0
);
320 while (parser
->iterate(parser
, &objectID
, &object
))
322 id_type_t id_type
= ID_ANY
;
326 case GN_OBJ_RFC822_NAME
:
327 id_type
= ID_RFC822_ADDR
;
329 case GN_OBJ_DNS_NAME
:
333 id_type
= ID_DER_ASN1_GN_URI
;
335 case GN_OBJ_DIRECTORY_NAME
:
336 id_type
= ID_DER_ASN1_DN
;
338 case GN_OBJ_IP_ADDRESS
:
339 id_type
= ID_IPV4_ADDR
;
341 case GN_OBJ_OTHER_NAME
:
342 if (!parse_otherName(object
, parser
->get_level(parser
)+1))
347 case GN_OBJ_X400_ADDRESS
:
348 case GN_OBJ_EDI_PARTY_NAME
:
349 case GN_OBJ_REGISTERED_ID
:
353 if (id_type
!= ID_ANY
)
355 gn
= identification_create_from_encoding(id_type
, object
);
362 parser
->destroy(parser
);
367 * ASN.1 definition of generalNames
369 static const asn1Object_t generalNamesObjects
[] = {
370 { 0, "generalNames", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
371 { 1, "generalName", ASN1_EOC
, ASN1_RAW
}, /* 1 */
372 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 2 */
373 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
375 #define GENERAL_NAMES_GN 1
378 * Extracts one or several GNs and puts them into a chained list
380 void x509_parse_generalNames(chunk_t blob
, int level0
, bool implicit
, linked_list_t
*list
)
382 asn1_parser_t
*parser
;
386 parser
= asn1_parser_create(generalNamesObjects
, blob
);
387 parser
->set_top_level(parser
, level0
);
388 parser
->set_flags(parser
, implicit
, FALSE
);
390 while (parser
->iterate(parser
, &objectID
, &object
))
392 if (objectID
== GENERAL_NAMES_GN
)
394 identification_t
*gn
= parse_generalName(object
,
395 parser
->get_level(parser
)+1);
399 list
->insert_last(list
, (void *)gn
);
403 parser
->destroy(parser
);
407 * ASN.1 definition of a authorityKeyIdentifier extension
409 static const asn1Object_t authKeyIdentifierObjects
[] = {
410 { 0, "authorityKeyIdentifier", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
411 { 1, "keyIdentifier", ASN1_CONTEXT_S_0
, ASN1_OPT
|ASN1_BODY
}, /* 1 */
412 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 2 */
413 { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1
, ASN1_OPT
|ASN1_OBJ
}, /* 3 */
414 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 4 */
415 { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2
, ASN1_OPT
|ASN1_BODY
}, /* 5 */
416 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 6 */
417 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
419 #define AUTH_KEY_ID_KEY_ID 1
420 #define AUTH_KEY_ID_CERT_ISSUER 3
421 #define AUTH_KEY_ID_CERT_SERIAL 5
424 * Extracts an authoritykeyIdentifier
426 identification_t
* x509_parse_authorityKeyIdentifier(chunk_t blob
, int level0
,
427 chunk_t
*authKeySerialNumber
)
429 asn1_parser_t
*parser
;
432 identification_t
*authKeyIdentifier
= NULL
;
434 *authKeySerialNumber
= chunk_empty
;
436 parser
= asn1_parser_create(authKeyIdentifierObjects
, blob
);
437 parser
->set_top_level(parser
, level0
);
439 while (parser
->iterate(parser
, &objectID
, &object
))
443 case AUTH_KEY_ID_KEY_ID
:
444 authKeyIdentifier
= identification_create_from_encoding(
445 ID_PUBKEY_SHA1
, object
);
447 case AUTH_KEY_ID_CERT_ISSUER
:
448 /* TODO: x509_parse_generalNames(object, level+1, TRUE); */
450 case AUTH_KEY_ID_CERT_SERIAL
:
451 *authKeySerialNumber
= object
;
457 parser
->destroy(parser
);
458 return authKeyIdentifier
;
462 * ASN.1 definition of a authorityInfoAccess extension
464 static const asn1Object_t authInfoAccessObjects
[] = {
465 { 0, "authorityInfoAccess", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
466 { 1, "accessDescription", ASN1_SEQUENCE
, ASN1_NONE
}, /* 1 */
467 { 2, "accessMethod", ASN1_OID
, ASN1_BODY
}, /* 2 */
468 { 2, "accessLocation", ASN1_EOC
, ASN1_RAW
}, /* 3 */
469 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 4 */
470 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
472 #define AUTH_INFO_ACCESS_METHOD 2
473 #define AUTH_INFO_ACCESS_LOCATION 3
476 * Extracts an authorityInfoAcess location
478 static void parse_authorityInfoAccess(chunk_t blob
, int level0
,
479 private_x509_cert_t
*this)
481 asn1_parser_t
*parser
;
484 int accessMethod
= OID_UNKNOWN
;
486 parser
= asn1_parser_create(authInfoAccessObjects
, blob
);
487 parser
->set_top_level(parser
, level0
);
489 while (parser
->iterate(parser
, &objectID
, &object
))
493 case AUTH_INFO_ACCESS_METHOD
:
494 accessMethod
= asn1_known_oid(object
);
496 case AUTH_INFO_ACCESS_LOCATION
:
498 switch (accessMethod
)
503 identification_t
*id
;
506 id
= parse_generalName(object
,
507 parser
->get_level(parser
)+1);
510 /* parsing went wrong - abort */
514 if (accessMethod
== OID_OCSP
&&
515 asprintf(&uri
, "%D", id
) > 0)
517 this->ocsp_uris
->insert_last(this->ocsp_uris
, uri
);
523 /* unkown accessMethod, ignoring */
534 parser
->destroy(parser
);
538 * ASN.1 definition of a extendedKeyUsage extension
540 static const asn1Object_t extendedKeyUsageObjects
[] = {
541 { 0, "extendedKeyUsage", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
542 { 1, "keyPurposeID", ASN1_OID
, ASN1_BODY
}, /* 1 */
543 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 2 */
544 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
546 #define EXT_KEY_USAGE_PURPOSE_ID 1
549 * Extracts extendedKeyUsage OIDs - currently only OCSP_SIGING is returned
551 static bool parse_extendedKeyUsage(chunk_t blob
, int level0
)
553 asn1_parser_t
*parser
;
556 bool ocsp_signing
= FALSE
;
558 parser
= asn1_parser_create(extendedKeyUsageObjects
, blob
);
559 parser
->set_top_level(parser
, level0
);
561 while (parser
->iterate(parser
, &objectID
, &object
))
563 if (objectID
== EXT_KEY_USAGE_PURPOSE_ID
&&
564 asn1_known_oid(object
) == OID_OCSP_SIGNING
)
569 parser
->destroy(parser
);
574 * ASN.1 definition of crlDistributionPoints
576 static const asn1Object_t crlDistributionPointsObjects
[] = {
577 { 0, "crlDistributionPoints", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
578 { 1, "DistributionPoint", ASN1_SEQUENCE
, ASN1_NONE
}, /* 1 */
579 { 2, "distributionPoint", ASN1_CONTEXT_C_0
, ASN1_OPT
|ASN1_LOOP
}, /* 2 */
580 { 3, "fullName", ASN1_CONTEXT_C_0
, ASN1_OPT
|ASN1_OBJ
}, /* 3 */
581 { 3, "end choice", ASN1_EOC
, ASN1_END
}, /* 4 */
582 { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1
, ASN1_OPT
|ASN1_BODY
}, /* 5 */
583 { 3, "end choice", ASN1_EOC
, ASN1_END
}, /* 6 */
584 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 7 */
585 { 2, "reasons", ASN1_CONTEXT_C_1
, ASN1_OPT
|ASN1_BODY
}, /* 8 */
586 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 9 */
587 { 2, "crlIssuer", ASN1_CONTEXT_C_2
, ASN1_OPT
|ASN1_BODY
}, /* 10 */
588 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 11 */
589 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 12 */
590 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
592 #define CRL_DIST_POINTS_FULLNAME 3
595 * Extracts one or several crlDistributionPoints into a list
597 static void parse_crlDistributionPoints(chunk_t blob
, int level0
,
598 private_x509_cert_t
*this)
600 asn1_parser_t
*parser
;
603 linked_list_t
*list
= linked_list_create();
605 parser
= asn1_parser_create(crlDistributionPointsObjects
, blob
);
606 parser
->set_top_level(parser
, level0
);
608 while (parser
->iterate(parser
, &objectID
, &object
))
610 if (objectID
== CRL_DIST_POINTS_FULLNAME
)
612 identification_t
*id
;
614 /* append extracted generalNames to existing chained list */
615 x509_parse_generalNames(object
, parser
->get_level(parser
)+1,
618 while (list
->remove_last(list
, (void**)&id
) == SUCCESS
)
622 if (asprintf(&uri
, "%D", id
) > 0)
624 this->crl_uris
->insert_last(this->crl_uris
, uri
);
630 parser
->destroy(parser
);
635 * ASN.1 definition of an X.509v3 x509_cert
637 static const asn1Object_t certObjects
[] = {
638 { 0, "x509", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 0 */
639 { 1, "tbsCertificate", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 1 */
640 { 2, "DEFAULT v1", ASN1_CONTEXT_C_0
, ASN1_DEF
}, /* 2 */
641 { 3, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
642 { 2, "serialNumber", ASN1_INTEGER
, ASN1_BODY
}, /* 4 */
643 { 2, "signature", ASN1_EOC
, ASN1_RAW
}, /* 5 */
644 { 2, "issuer", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 6 */
645 { 2, "validity", ASN1_SEQUENCE
, ASN1_NONE
}, /* 7 */
646 { 3, "notBefore", ASN1_EOC
, ASN1_RAW
}, /* 8 */
647 { 3, "notAfter", ASN1_EOC
, ASN1_RAW
}, /* 9 */
648 { 2, "subject", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 10 */
649 { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE
, ASN1_RAW
}, /* 11 */
650 { 2, "issuerUniqueID", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 12 */
651 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 13 */
652 { 2, "subjectUniqueID", ASN1_CONTEXT_C_2
, ASN1_OPT
}, /* 14 */
653 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 15 */
654 { 2, "optional extensions", ASN1_CONTEXT_C_3
, ASN1_OPT
}, /* 16 */
655 { 3, "extensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 17 */
656 { 4, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 18 */
657 { 5, "extnID", ASN1_OID
, ASN1_BODY
}, /* 19 */
658 { 5, "critical", ASN1_BOOLEAN
, ASN1_DEF
|ASN1_BODY
}, /* 20 */
659 { 5, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 21 */
660 { 3, "end loop", ASN1_EOC
, ASN1_END
}, /* 22 */
661 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 23 */
662 { 1, "signatureAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 24 */
663 { 1, "signatureValue", ASN1_BIT_STRING
, ASN1_BODY
}, /* 25 */
664 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
666 #define X509_OBJ_TBS_CERTIFICATE 1
667 #define X509_OBJ_VERSION 3
668 #define X509_OBJ_SERIAL_NUMBER 4
669 #define X509_OBJ_SIG_ALG 5
670 #define X509_OBJ_ISSUER 6
671 #define X509_OBJ_NOT_BEFORE 8
672 #define X509_OBJ_NOT_AFTER 9
673 #define X509_OBJ_SUBJECT 10
674 #define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO 11
675 #define X509_OBJ_EXTN_ID 19
676 #define X509_OBJ_CRITICAL 20
677 #define X509_OBJ_EXTN_VALUE 21
678 #define X509_OBJ_ALGORITHM 24
679 #define X509_OBJ_SIGNATURE 25
682 * Parses an X.509v3 certificate
684 static bool parse_certificate(private_x509_cert_t
*this)
686 asn1_parser_t
*parser
;
689 int extn_oid
= OID_UNKNOWN
;
690 int sig_alg
= OID_UNKNOWN
;
691 bool success
= FALSE
;
694 parser
= asn1_parser_create(certObjects
, this->encoding
);
696 while (parser
->iterate(parser
, &objectID
, &object
))
698 u_int level
= parser
->get_level(parser
)+1;
702 case X509_OBJ_TBS_CERTIFICATE
:
703 this->tbsCertificate
= object
;
705 case X509_OBJ_VERSION
:
706 this->version
= (object
.len
) ?
(1+(u_int
)*object
.ptr
) : 1;
707 DBG2(" v%d", this->version
);
709 case X509_OBJ_SERIAL_NUMBER
:
710 this->serialNumber
= object
;
712 case X509_OBJ_SIG_ALG
:
713 sig_alg
= asn1_parse_algorithmIdentifier(object
, level
, NULL
);
715 case X509_OBJ_ISSUER
:
716 this->issuer
= identification_create_from_encoding(ID_DER_ASN1_DN
, object
);
717 DBG2(" '%D'", this->issuer
);
719 case X509_OBJ_NOT_BEFORE
:
720 this->notBefore
= asn1_parse_time(object
, level
);
722 case X509_OBJ_NOT_AFTER
:
723 this->notAfter
= asn1_parse_time(object
, level
);
725 case X509_OBJ_SUBJECT
:
726 this->subject
= identification_create_from_encoding(ID_DER_ASN1_DN
, object
);
727 DBG2(" '%D'", this->subject
);
729 case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO
:
730 this->public_key
= lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
,
731 KEY_ANY
, BUILD_BLOB_ASN1_DER
, object
, BUILD_END
);
732 if (this->public_key
== NULL
)
734 DBG1("could not create public key");
738 case X509_OBJ_EXTN_ID
:
739 extn_oid
= asn1_known_oid(object
);
741 case X509_OBJ_CRITICAL
:
742 critical
= object
.len
&& *object
.ptr
;
743 DBG2(" %s", critical ?
"TRUE" : "FALSE");
745 case X509_OBJ_EXTN_VALUE
:
749 case OID_SUBJECT_KEY_ID
:
750 if (!asn1_parse_simple_object(&object
, ASN1_OCTET_STRING
,
751 level
, "keyIdentifier"))
755 this->subjectKeyID
= object
;
757 case OID_SUBJECT_ALT_NAME
:
758 x509_parse_generalNames(object
, level
, FALSE
,
759 this->subjectAltNames
);
761 case OID_BASIC_CONSTRAINTS
:
762 if (parse_basicConstraints(object
, level
))
764 this->flags
|= X509_CA
;
767 case OID_CRL_DISTRIBUTION_POINTS
:
768 parse_crlDistributionPoints(object
, level
, this);
770 case OID_AUTHORITY_KEY_ID
:
771 this->authKeyIdentifier
= x509_parse_authorityKeyIdentifier(object
,
772 level
, &this->authKeySerialNumber
);
774 case OID_AUTHORITY_INFO_ACCESS
:
775 parse_authorityInfoAccess(object
, level
, this);
777 case OID_EXTENDED_KEY_USAGE
:
778 if (parse_extendedKeyUsage(object
, level
))
780 this->flags
|= X509_OCSP_SIGNER
;
783 case OID_NS_REVOCATION_URL
:
784 case OID_NS_CA_REVOCATION_URL
:
785 case OID_NS_CA_POLICY_URL
:
787 if (!asn1_parse_simple_object(&object
, ASN1_IA5STRING
,
788 level
, oid_names
[extn_oid
].name
))
798 case X509_OBJ_ALGORITHM
:
799 this->algorithm
= asn1_parse_algorithmIdentifier(object
, level
, NULL
);
800 if (this->algorithm
!= sig_alg
)
802 DBG1(" signature algorithms do not agree");
806 case X509_OBJ_SIGNATURE
:
807 this->signature
= object
;
813 success
= parser
->success(parser
);
816 parser
->destroy(parser
);
821 * Implementation of certificate_t.get_type
823 static certificate_type_t
get_type(private_x509_cert_t
*this)
829 * Implementation of certificate_t.get_subject
831 static identification_t
* get_subject(private_x509_cert_t
*this)
833 return this->subject
;
837 * Implementation of certificate_t.get_issuer
839 static identification_t
* get_issuer(private_x509_cert_t
*this)
845 * Implementation of certificate_t.has_subject.
847 static id_match_t
has_subject(private_x509_cert_t
*this, identification_t
*subject
)
849 identification_t
*current
;
850 enumerator_t
*enumerator
;
851 id_match_t match
, best
;
853 if (this->encoding_hash
.ptr
&& subject
->get_type(subject
) == ID_CERT_DER_SHA1
&&
854 chunk_equals(this->encoding_hash
, subject
->get_encoding(subject
)))
856 return ID_MATCH_PERFECT
;
859 best
= this->subject
->matches(this->subject
, subject
);
860 enumerator
= this->subjectAltNames
->create_enumerator(this->subjectAltNames
);
861 while (enumerator
->enumerate(enumerator
, ¤t
))
863 match
= current
->matches(current
, subject
);
869 enumerator
->destroy(enumerator
);
874 * Implementation of certificate_t.has_subject.
876 static id_match_t
has_issuer(private_x509_cert_t
*this, identification_t
*issuer
)
878 /* issuerAltNames currently not supported */
879 return this->issuer
->matches(this->issuer
, issuer
);
883 * Implementation of certificate_t.issued_by
885 static bool issued_by(private_x509_cert_t
*this, certificate_t
*issuer
)
888 signature_scheme_t scheme
;
890 x509_t
*x509
= (x509_t
*)issuer
;
892 if (&this->public.interface
.interface
== issuer
)
894 if (this->flags
& X509_SELF_SIGNED
)
901 if (issuer
->get_type(issuer
) != CERT_X509
)
906 if (!(x509
->get_flags(x509
) & X509_CA
))
912 if (!this->issuer
->equals(this->issuer
, issuer
->get_subject(issuer
)))
916 /* TODO: generic OID to scheme mapper? */
917 switch (this->algorithm
)
919 case OID_MD5_WITH_RSA
:
920 scheme
= SIGN_RSA_EMSA_PKCS1_MD5
;
922 case OID_SHA1_WITH_RSA
:
923 scheme
= SIGN_RSA_EMSA_PKCS1_SHA1
;
925 case OID_SHA256_WITH_RSA
:
926 scheme
= SIGN_RSA_EMSA_PKCS1_SHA256
;
928 case OID_SHA384_WITH_RSA
:
929 scheme
= SIGN_RSA_EMSA_PKCS1_SHA384
;
931 case OID_SHA512_WITH_RSA
:
932 scheme
= SIGN_RSA_EMSA_PKCS1_SHA512
;
934 case OID_ECDSA_WITH_SHA1
:
935 scheme
= SIGN_ECDSA_WITH_SHA1
;
941 key
= issuer
->get_public_key(issuer
);
947 /* TODO: add a lightweight check option (comparing auth/subject keyids only) */
948 valid
= key
->verify(key
, scheme
, this->tbsCertificate
, this->signature
);
954 * Implementation of certificate_t.get_public_key
956 static public_key_t
* get_public_key(private_x509_cert_t
*this)
958 this->public_key
->get_ref(this->public_key
);
959 return this->public_key
;
963 * Implementation of certificate_t.asdf
965 static private_x509_cert_t
* get_ref(private_x509_cert_t
*this)
972 * Implementation of x509_cert_t.get_flags.
974 static x509_flag_t
get_flags(private_x509_cert_t
*this)
980 * Implementation of x509_cert_t.get_validity.
982 static bool get_validity(private_x509_cert_t
*this, time_t *when
,
983 time_t *not_before
, time_t *not_after
)
997 *not_before
= this->notBefore
;
1001 *not_after
= this->notAfter
;
1003 return (t
>= this->notBefore
&& t
<= this->notAfter
);
1007 * Implementation of certificate_t.is_newer.
1009 static bool is_newer(certificate_t
*this, certificate_t
*that
)
1011 time_t this_update
, that_update
, now
= time(NULL
);
1014 this->get_validity(this, &now
, &this_update
, NULL
);
1015 that
->get_validity(that
, &now
, &that_update
, NULL
);
1016 new = this_update
> that_update
;
1017 DBG1(" certificate from %#T is %s - existing certificate from %#T %s",
1018 &this_update
, FALSE
, new ?
"newer":"not newer",
1019 &that_update
, FALSE
, new ?
"replaced":"retained");
1024 * Implementation of certificate_t.get_encoding.
1026 static chunk_t
get_encoding(private_x509_cert_t
*this)
1028 return chunk_clone(this->encoding
);
1032 * Implementation of certificate_t.equals.
1034 static bool equals(private_x509_cert_t
*this, certificate_t
*other
)
1039 if (this == (private_x509_cert_t
*)other
)
1043 if (other
->get_type(other
) != CERT_X509
)
1047 if (other
->equals
== (void*)equals
)
1048 { /* skip allocation if we have the same implementation */
1049 return chunk_equals(this->encoding
, ((private_x509_cert_t
*)other
)->encoding
);
1051 encoding
= other
->get_encoding(other
);
1052 equal
= chunk_equals(this->encoding
, encoding
);
1058 * Implementation of x509_t.get_serial.
1060 static chunk_t
get_serial(private_x509_cert_t
*this)
1062 return this->serialNumber
;
1066 * Implementation of x509_t.get_authKeyIdentifier.
1068 static identification_t
*get_authKeyIdentifier(private_x509_cert_t
*this)
1070 return this->authKeyIdentifier
;
1074 * Implementation of x509_cert_t.create_subjectAltName_enumerator.
1076 static enumerator_t
* create_subjectAltName_enumerator(private_x509_cert_t
*this)
1078 return this->subjectAltNames
->create_enumerator(this->subjectAltNames
);
1082 * Implementation of x509_cert_t.create_ocsp_uri_enumerator.
1084 static enumerator_t
* create_ocsp_uri_enumerator(private_x509_cert_t
*this)
1086 return this->ocsp_uris
->create_enumerator(this->ocsp_uris
);
1090 * Implementation of x509_cert_t.create_crl_uri_enumerator.
1092 static enumerator_t
* create_crl_uri_enumerator(private_x509_cert_t
*this)
1094 return this->crl_uris
->create_enumerator(this->crl_uris
);
1098 * Implementation of certificate_t.asdf
1100 static void destroy(private_x509_cert_t
*this)
1102 if (ref_put(&this->ref
))
1104 this->subjectAltNames
->destroy_offset(this->subjectAltNames
,
1105 offsetof(identification_t
, destroy
));
1106 this->crl_uris
->destroy_function(this->crl_uris
, free
);
1107 this->ocsp_uris
->destroy_function(this->ocsp_uris
, free
);
1108 DESTROY_IF(this->issuer
);
1109 DESTROY_IF(this->subject
);
1110 DESTROY_IF(this->public_key
);
1111 DESTROY_IF(this->authKeyIdentifier
);
1112 chunk_free(&this->encoding
);
1113 chunk_free(&this->encoding_hash
);
1115 { /* only parsed certificates point these fields to "encoded" */
1116 chunk_free(&this->signature
);
1117 chunk_free(&this->serialNumber
);
1118 chunk_free(&this->tbsCertificate
);
1125 * create an empty but initialized X.509 certificate
1127 static private_x509_cert_t
* create_empty(void)
1129 private_x509_cert_t
*this = malloc_thing(private_x509_cert_t
);
1131 this->public.interface
.interface
.get_type
= (certificate_type_t (*)(certificate_t
*this))get_type
;
1132 this->public.interface
.interface
.get_subject
= (identification_t
* (*)(certificate_t
*this))get_subject
;
1133 this->public.interface
.interface
.get_issuer
= (identification_t
* (*)(certificate_t
*this))get_issuer
;
1134 this->public.interface
.interface
.has_subject
= (id_match_t (*)(certificate_t
*, identification_t
*subject
))has_subject
;
1135 this->public.interface
.interface
.has_issuer
= (id_match_t (*)(certificate_t
*, identification_t
*issuer
))has_issuer
;
1136 this->public.interface
.interface
.issued_by
= (bool (*)(certificate_t
*this, certificate_t
*issuer
))issued_by
;
1137 this->public.interface
.interface
.get_public_key
= (public_key_t
* (*)(certificate_t
*this))get_public_key
;
1138 this->public.interface
.interface
.get_validity
= (bool (*)(certificate_t
*, time_t *when
, time_t *, time_t*))get_validity
;
1139 this->public.interface
.interface
.is_newer
= (bool (*)(certificate_t
*,certificate_t
*))is_newer
;
1140 this->public.interface
.interface
.get_encoding
= (chunk_t (*)(certificate_t
*))get_encoding
;
1141 this->public.interface
.interface
.equals
= (bool (*)(certificate_t
*, certificate_t
*other
))equals
;
1142 this->public.interface
.interface
.get_ref
= (certificate_t
* (*)(certificate_t
*this))get_ref
;
1143 this->public.interface
.interface
.destroy
= (void (*)(certificate_t
*this))destroy
;
1144 this->public.interface
.get_flags
= (x509_flag_t (*)(x509_t
*))get_flags
;
1145 this->public.interface
.get_serial
= (chunk_t (*)(x509_t
*))get_serial
;
1146 this->public.interface
.get_authKeyIdentifier
= (identification_t
* (*)(x509_t
*))get_authKeyIdentifier
;
1147 this->public.interface
.create_subjectAltName_enumerator
= (enumerator_t
* (*)(x509_t
*))create_subjectAltName_enumerator
;
1148 this->public.interface
.create_crl_uri_enumerator
= (enumerator_t
* (*)(x509_t
*))create_crl_uri_enumerator
;
1149 this->public.interface
.create_ocsp_uri_enumerator
= (enumerator_t
* (*)(x509_t
*))create_ocsp_uri_enumerator
;
1151 this->encoding
= chunk_empty
;
1152 this->encoding_hash
= chunk_empty
;
1153 this->tbsCertificate
= chunk_empty
;
1155 this->serialNumber
= chunk_empty
;
1156 this->notBefore
= 0;
1158 this->public_key
= NULL
;
1159 this->subject
= NULL
;
1160 this->issuer
= NULL
;
1161 this->subjectAltNames
= linked_list_create();
1162 this->crl_uris
= linked_list_create();
1163 this->ocsp_uris
= linked_list_create();
1164 this->subjectKeyID
= chunk_empty
;
1165 this->authKeyIdentifier
= NULL
;
1166 this->authKeySerialNumber
= chunk_empty
;
1167 this->algorithm
= 0;
1168 this->signature
= chunk_empty
;
1171 this->parsed
= FALSE
;
1177 * create an X.509 certificate from a chunk
1179 static private_x509_cert_t
*create_from_chunk(chunk_t chunk
)
1182 private_x509_cert_t
*this = create_empty();
1184 this->encoding
= chunk
;
1185 if (!parse_certificate(this))
1191 /* check if the certificate is self-signed */
1192 if (issued_by(this, &this->public.interface
.interface
))
1194 this->flags
|= X509_SELF_SIGNED
;
1197 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
1200 hasher
->allocate_hash(hasher
, this->encoding
, &this->encoding_hash
);
1201 hasher
->destroy(hasher
);
1205 DBG1(" unable to create hash of certificate, SHA1 not supported");
1208 this->parsed
= TRUE
;
1213 * create an X.509 certificate from a file
1215 static private_x509_cert_t
*create_from_file(char *path
)
1219 private_x509_cert_t
*this;
1221 if (!pem_asn1_load_file(path
, NULL
, &chunk
, &pgp
))
1226 this = create_from_chunk(chunk
);
1230 DBG1(" could not parse loaded certificate file '%s'",path
);
1233 DBG1(" loaded certificate file '%s'", path
);
1237 typedef struct private_builder_t private_builder_t
;
1239 * Builder implementation for certificate loading
1241 struct private_builder_t
{
1242 /** implements the builder interface */
1244 /** loaded certificate */
1245 private_x509_cert_t
*cert
;
1246 /** additional flags to enforce */
1248 /** certificate to sign, if we generate a new cert */
1249 certificate_t
*sign_cert
;
1250 /** private key to sign, if we generate a new cert */
1251 private_key_t
*sign_key
;
1255 * Generate and sign a new certificate
1257 static bool generate(private_builder_t
*this)
1259 chunk_t extensions
= chunk_empty
;
1260 identification_t
*issuer
, *subject
;
1261 chunk_t key_info
, key
;
1262 signature_scheme_t scheme
;
1265 subject
= this->cert
->subject
;
1266 if (this->sign_cert
)
1268 issuer
= this->sign_cert
->get_subject(this->sign_cert
);
1269 if (!this->cert
->public_key
)
1277 if (!this->cert
->public_key
)
1279 this->cert
->public_key
= this->sign_key
->get_public_key(this->sign_key
);
1281 this->flags
|= X509_SELF_SIGNED
;
1283 this->cert
->issuer
= issuer
->clone(issuer
);
1284 if (!this->cert
->notBefore
)
1286 this->cert
->notBefore
= time(NULL
);
1288 if (!this->cert
->notAfter
)
1289 { /* defaults to 1 years from now on */
1290 this->cert
->notAfter
= this->cert
->notBefore
+ 60 * 60 * 24 * 365;
1292 this->cert
->flags
= this->flags
;
1294 switch (this->sign_key
->get_type(this->sign_key
))
1297 this->cert
->algorithm
= OID_SHA1_WITH_RSA
;
1298 scheme
= SIGN_RSA_EMSA_PKCS1_SHA1
;
1304 switch (this->cert
->public_key
->get_type(this->cert
->public_key
))
1307 key
= this->cert
->public_key
->get_encoding(this->cert
->public_key
);
1308 key_info
= asn1_wrap(ASN1_SEQUENCE
, "cm",
1309 asn1_algorithmIdentifier(OID_RSA_ENCRYPTION
),
1310 asn1_bitstring("m", key
));
1316 if (this->cert
->subjectAltNames
->get_count(this->cert
->subjectAltNames
))
1318 /* TODO: encode subjectAltNames */
1321 this->cert
->tbsCertificate
= asn1_wrap(ASN1_SEQUENCE
, "mmccmcmm",
1322 asn1_simple_object(ASN1_CONTEXT_C_0
, ASN1_INTEGER_2
),
1323 asn1_simple_object(ASN1_INTEGER
, this->cert
->serialNumber
),
1324 asn1_algorithmIdentifier(this->cert
->algorithm
),
1325 issuer
->get_encoding(issuer
),
1326 asn1_wrap(ASN1_SEQUENCE
, "mm",
1327 asn1_from_time(&this->cert
->notBefore
, ASN1_UTCTIME
),
1328 asn1_from_time(&this->cert
->notAfter
, ASN1_UTCTIME
)),
1329 subject
->get_encoding(subject
),
1330 key_info
, extensions
);
1332 if (!this->sign_key
->sign(this->sign_key
, scheme
,
1333 this->cert
->tbsCertificate
, &this->cert
->signature
))
1337 this->cert
->encoding
= asn1_wrap(ASN1_SEQUENCE
, "ccm",
1338 this->cert
->tbsCertificate
,
1339 asn1_algorithmIdentifier(this->cert
->algorithm
),
1340 asn1_bitstring("c", this->cert
->signature
));
1342 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
1347 hasher
->allocate_hash(hasher
, this->cert
->encoding
,
1348 &this->cert
->encoding_hash
);
1349 hasher
->destroy(hasher
);
1354 * Implementation of builder_t.build
1356 static private_x509_cert_t
*build(private_builder_t
*this)
1358 private_x509_cert_t
*cert
;
1361 if (this->cert
&& !this->cert
->encoding
.ptr
)
1363 if (!this->sign_key
|| !this->cert
||
1366 destroy(this->cert
);
1372 flags
= this->flags
;
1379 if ((flags
& X509_CA
) && !(cert
->flags
& X509_CA
))
1381 DBG1(" ca certificate must have ca basic constraint set, discarded");
1385 cert
->flags
|= flags
;
1390 * Implementation of builder_t.add
1392 static void add(private_builder_t
*this, builder_part_t part
, ...)
1396 bool handled
= TRUE
;
1398 va_start(args
, part
);
1401 case BUILD_FROM_FILE
:
1402 this->cert
= create_from_file(va_arg(args
, char*));
1404 case BUILD_BLOB_ASN1_DER
:
1405 chunk
= va_arg(args
, chunk_t
);
1406 this->cert
= create_from_chunk(chunk_clone(chunk
));
1408 case BUILD_X509_FLAG
:
1409 this->flags
= va_arg(args
, x509_flag_t
);
1411 case BUILD_SIGNING_KEY
:
1412 this->sign_key
= va_arg(args
, private_key_t
*);
1414 case BUILD_SIGNING_CERT
:
1415 this->sign_cert
= va_arg(args
, certificate_t
*);
1418 /* all other parts need an empty cert */
1421 this->cert
= create_empty();
1434 case BUILD_PUBLIC_KEY
:
1436 public_key_t
*key
= va_arg(args
, public_key_t
*);
1437 this->cert
->public_key
= key
->get_ref(key
);
1442 identification_t
*id
= va_arg(args
, identification_t
*);
1443 this->cert
->subject
= id
->clone(id
);
1446 case BUILD_SUBJECT_ALTNAME
:
1448 identification_t
*id
= va_arg(args
, identification_t
*);
1449 this->cert
->subjectAltNames
->insert_last(
1450 this->cert
->subjectAltNames
, id
->clone(id
));
1453 case BUILD_NOT_BEFORE_TIME
:
1454 this->cert
->notBefore
= va_arg(args
, time_t);
1456 case BUILD_NOT_AFTER_TIME
:
1457 this->cert
->notAfter
= va_arg(args
, time_t);
1461 chunk_t serial
= va_arg(args
, chunk_t
);
1462 this->cert
->serialNumber
= chunk_clone(serial
);
1466 /* abort if unsupported option */
1469 destroy(this->cert
);
1471 builder_cancel(&this->public);
1478 * Builder construction function
1480 builder_t
*x509_cert_builder(certificate_type_t type
)
1482 private_builder_t
*this;
1484 if (type
!= CERT_X509
)
1489 this = malloc_thing(private_builder_t
);
1493 this->sign_cert
= NULL
;
1494 this->sign_key
= NULL
;
1495 this->public.add
= (void(*)(builder_t
*this, builder_part_t part
, ...))add
;
1496 this->public.build
= (void*(*)(builder_t
*this))build
;
1498 return &this->public;