added public methods is_ca() and is_valid()
[strongswan.git] / src / libstrongswan / crypto / x509.c
1 /**
2 * @file x509.c
3 *
4 * @brief Implementation of x509_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2006 Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include <gmp.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <string.h>
27
28 #include "x509.h"
29
30 #include <types.h>
31 #include <definitions.h>
32 #include <asn1/oid.h>
33 #include <asn1/asn1.h>
34 #include <asn1/pem.h>
35 #include <utils/logger_manager.h>
36 #include <utils/linked_list.h>
37 #include <utils/identification.h>
38
39 #define BITS_PER_BYTE 8
40 #define RSA_MIN_OCTETS (1024 / BITS_PER_BYTE)
41 #define RSA_MIN_OCTETS_UGH "RSA modulus too small for security: less than 1024 bits"
42 #define RSA_MAX_OCTETS (8192 / BITS_PER_BYTE)
43 #define RSA_MAX_OCTETS_UGH "RSA modulus too large: more than 8192 bits"
44
45 #define CERT_WARNING_INTERVAL 30 /* days */
46
47 static logger_t *logger;
48
49 /**
50 * Different kinds of generalNames
51 */
52 typedef enum generalNames_t generalNames_t;
53
54 enum generalNames_t {
55 GN_OTHER_NAME = 0,
56 GN_RFC822_NAME = 1,
57 GN_DNS_NAME = 2,
58 GN_X400_ADDRESS = 3,
59 GN_DIRECTORY_NAME = 4,
60 GN_EDI_PARTY_NAME = 5,
61 GN_URI = 6,
62 GN_IP_ADDRESS = 7,
63 GN_REGISTERED_ID = 8,
64 };
65
66 typedef struct private_x509_t private_x509_t;
67
68 /**
69 * Private data of a x509_t object.
70 */
71 struct private_x509_t {
72 /**
73 * Public interface for this certificate.
74 */
75 x509_t public;
76
77 /**
78 * Time when certificate was installed
79 */
80 time_t installed;
81
82 /**
83 * X.509 Certificate in DER format
84 */
85 chunk_t certificate;
86
87 /**
88 * Version of the X.509 certificate
89 */
90 u_int version;
91
92 /**
93 * Serial number of the X.509 certificate
94 */
95 chunk_t serialNumber;
96
97 /**
98 * ID representing the certificate issuer
99 */
100 identification_t *issuer;
101
102 /**
103 * Start time of certificate validity
104 */
105 time_t notBefore;
106
107 /**
108 * End time of certificate validity
109 */
110 time_t notAfter;
111
112 /**
113 * ID representing the certificate subject
114 */
115 identification_t *subject;
116
117 /**
118 * List of identification_t's representing subjectAltNames
119 */
120 linked_list_t *subjectAltNames;
121
122 /**
123 * List of identification_t's representing crlDistributionPoints
124 */
125 linked_list_t *crlDistributionPoints;
126
127 /**
128 * Subject RSA public key, if subjectPublicKeyAlgorithm == RSA
129 */
130 rsa_public_key_t *public_key;
131
132 /**
133 * Subject Key Identifier
134 */
135 chunk_t subjectKeyID;
136
137 /**
138 * Authority Key Identifier
139 */
140 chunk_t authKeyID;
141
142 /**
143 * Authority Key Serial Number
144 */
145 chunk_t authKeySerialNumber;
146
147 /**
148 * CA basic constraints flag
149 */
150 bool isCA;
151
152 u_char authority_flags;
153 chunk_t tbsCertificate;
154 /* signature */
155 int sigAlg;
156 chunk_t subjectPublicKey;
157 bool isOcspSigner; /* ocsp */
158 chunk_t accessLocation; /* ocsp */
159 /* signatureAlgorithm */
160 int algorithm;
161 chunk_t signature;
162 };
163
164 /**
165 * ASN.1 definition of generalName
166 */
167 static const asn1Object_t generalNameObjects[] = {
168 { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */
169 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
170 { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */
171 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
172 { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */
173 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
174 { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */
175 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
176 { 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT|ASN1_BODY }, /* 8 */
177 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
178 { 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT|ASN1_BODY }, /* 10 */
179 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
180 { 0, "URI", ASN1_CONTEXT_S_6, ASN1_OPT|ASN1_BODY }, /* 12 */
181 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */
182 { 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT|ASN1_BODY }, /* 14 */
183 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */
184 { 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT|ASN1_BODY }, /* 16 */
185 { 0, "end choice", ASN1_EOC, ASN1_END } /* 17 */
186 };
187 #define GN_OBJ_OTHER_NAME 0
188 #define GN_OBJ_RFC822_NAME 2
189 #define GN_OBJ_DNS_NAME 4
190 #define GN_OBJ_X400_ADDRESS 6
191 #define GN_OBJ_DIRECTORY_NAME 8
192 #define GN_OBJ_EDI_PARTY_NAME 10
193 #define GN_OBJ_URI 12
194 #define GN_OBJ_IP_ADDRESS 14
195 #define GN_OBJ_REGISTERED_ID 16
196 #define GN_OBJ_ROOF 18
197
198 /**
199 * ASN.1 definition of otherName
200 */
201 static const asn1Object_t otherNameObjects[] = {
202 {0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */
203 {0, "value", ASN1_CONTEXT_C_0, ASN1_BODY } /* 1 */
204 };
205 #define ON_OBJ_ID_TYPE 0
206 #define ON_OBJ_VALUE 1
207 #define ON_OBJ_ROOF 2
208 /**
209 * ASN.1 definition of a basicConstraints extension
210 */
211 static const asn1Object_t basicConstraintsObjects[] = {
212 { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
213 { 1, "CA", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 1 */
214 { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */
215 { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */
216 };
217 #define BASIC_CONSTRAINTS_CA 1
218 #define BASIC_CONSTRAINTS_ROOF 4
219
220 /**
221 * ASN.1 definition of time
222 */
223 static const asn1Object_t timeObjects[] = {
224 { 0, "utcTime", ASN1_UTCTIME, ASN1_OPT|ASN1_BODY }, /* 0 */
225 { 0, "end opt", ASN1_EOC, ASN1_END }, /* 1 */
226 { 0, "generalizeTime",ASN1_GENERALIZEDTIME, ASN1_OPT|ASN1_BODY }, /* 2 */
227 { 0, "end opt", ASN1_EOC, ASN1_END } /* 3 */
228 };
229 #define TIME_UTC 0
230 #define TIME_GENERALIZED 2
231 #define TIME_ROOF 4
232
233 /**
234 * ASN.1 definition of a keyIdentifier
235 */
236 static const asn1Object_t keyIdentifierObjects[] = {
237 { 0, "keyIdentifier", ASN1_OCTET_STRING, ASN1_BODY } /* 0 */
238 };
239
240 /**
241 * ASN.1 definition of a authorityKeyIdentifier extension
242 */
243 static const asn1Object_t authorityKeyIdentifierObjects[] = {
244 { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
245 { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_OBJ }, /* 1 */
246 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
247 { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */
248 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
249 { 1, "authorityCertSerialNumber",ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */
250 { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
251 };
252 #define AUTH_KEY_ID_KEY_ID 1
253 #define AUTH_KEY_ID_CERT_ISSUER 3
254 #define AUTH_KEY_ID_CERT_SERIAL 5
255 #define AUTH_KEY_ID_ROOF 7
256
257 /**
258 * ASN.1 definition of a authorityInfoAccess extension
259 */
260 static const asn1Object_t authorityInfoAccessObjects[] = {
261 { 0, "authorityInfoAccess", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
262 { 1, "accessDescription", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
263 { 2, "accessMethod", ASN1_OID, ASN1_BODY }, /* 2 */
264 { 2, "accessLocation", ASN1_EOC, ASN1_RAW }, /* 3 */
265 { 0, "end loop", ASN1_EOC, ASN1_END } /* 4 */
266 };
267 #define AUTH_INFO_ACCESS_METHOD 2
268 #define AUTH_INFO_ACCESS_LOCATION 3
269 #define AUTH_INFO_ACCESS_ROOF 5
270
271 /**
272 * ASN.1 definition of a extendedKeyUsage extension
273 */
274 static const asn1Object_t extendedKeyUsageObjects[] = {
275 { 0, "extendedKeyUsage", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
276 { 1, "keyPurposeID", ASN1_OID, ASN1_BODY }, /* 1 */
277 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
278 };
279
280 #define EXT_KEY_USAGE_PURPOSE_ID 1
281 #define EXT_KEY_USAGE_ROOF 3
282
283 /**
284 * ASN.1 definition of generalNames
285 */
286 static const asn1Object_t generalNamesObjects[] = {
287 { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
288 { 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */
289 { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
290 };
291 #define GENERAL_NAMES_GN 1
292 #define GENERAL_NAMES_ROOF 3
293
294
295 /**
296 * ASN.1 definition of crlDistributionPoints
297 */
298 static const asn1Object_t crlDistributionPointsObjects[] = {
299 { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
300 { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
301 { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 2 */
302 { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */
303 { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
304 { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */
305 { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
306 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
307 { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */
308 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
309 { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_BODY }, /* 10 */
310 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
311 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
312 };
313 #define CRL_DIST_POINTS_FULLNAME 3
314 #define CRL_DIST_POINTS_ROOF 13
315
316 /**
317 * ASN.1 definition of an X.509v3 x509
318 */
319 static const asn1Object_t certObjects[] = {
320 { 0, "x509", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
321 { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
322 { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
323 { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
324 { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
325 { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */
326 { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
327 { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */
328 { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */
329 { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */
330 { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
331 { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
332 { 3, "algorithm", ASN1_EOC, ASN1_RAW }, /* 12 */
333 { 3, "subjectPublicKey", ASN1_BIT_STRING, ASN1_NONE }, /* 13 */
334 { 4, "RSAPublicKey", ASN1_SEQUENCE, ASN1_RAW }, /* 14 */
335 { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 15 */
336 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 16 */
337 { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 17 */
338 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 18 */
339 { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 19 */
340 { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
341 { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
342 { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
343 { 5, "critical", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 23 */
344 { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
345 { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
346 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
347 { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
348 { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 28 */
349 };
350 #define X509_OBJ_CERTIFICATE 0
351 #define X509_OBJ_TBS_CERTIFICATE 1
352 #define X509_OBJ_VERSION 3
353 #define X509_OBJ_SERIAL_NUMBER 4
354 #define X509_OBJ_SIG_ALG 5
355 #define X509_OBJ_ISSUER 6
356 #define X509_OBJ_NOT_BEFORE 8
357 #define X509_OBJ_NOT_AFTER 9
358 #define X509_OBJ_SUBJECT 10
359 #define X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM 12
360 #define X509_OBJ_SUBJECT_PUBLIC_KEY 13
361 #define X509_OBJ_RSA_PUBLIC_KEY 14
362 #define X509_OBJ_EXTN_ID 22
363 #define X509_OBJ_CRITICAL 23
364 #define X509_OBJ_EXTN_VALUE 24
365 #define X509_OBJ_ALGORITHM 27
366 #define X509_OBJ_SIGNATURE 28
367 #define X509_OBJ_ROOF 29
368
369
370 static u_char ASN1_subjectAltName_oid_str[] = {
371 0x06, 0x03, 0x55, 0x1D, 0x11
372 };
373
374 static const chunk_t ASN1_subjectAltName_oid = chunk_from_buf(ASN1_subjectAltName_oid_str);
375
376
377 /**
378 * compare two X.509 x509s by comparing their signatures
379 */
380 static bool equals(const private_x509_t *this, const private_x509_t *other)
381 {
382 return chunk_equals(this->signature, other->signature);
383 }
384
385 /**
386 * extracts the basicConstraints extension
387 */
388 static bool parse_basicConstraints(chunk_t blob, int level0)
389 {
390 asn1_ctx_t ctx;
391 chunk_t object;
392 u_int level;
393 int objectID = 0;
394 bool isCA = FALSE;
395
396 asn1_init(&ctx, blob, level0, FALSE);
397
398 while (objectID < BASIC_CONSTRAINTS_ROOF) {
399
400 if (!extract_object(basicConstraintsObjects, &objectID, &object,&level, &ctx))
401 {
402 break;
403 }
404 if (objectID == BASIC_CONSTRAINTS_CA)
405 {
406 isCA = object.len && *object.ptr;
407 logger->log(logger, CONTROL|LEVEL2, " %s", isCA ? "TRUE" : "FALSE");
408 }
409 objectID++;
410 }
411 return isCA;
412 }
413
414 /*
415 * extracts an otherName
416 */
417 static bool
418 parse_otherName(chunk_t blob, int level0)
419 {
420 asn1_ctx_t ctx;
421 chunk_t object;
422 int objectID = 0;
423 u_int level;
424 int oid = OID_UNKNOWN;
425
426 asn1_init(&ctx, blob, level0, FALSE);
427
428 while (objectID < ON_OBJ_ROOF)
429 {
430 if (!extract_object(otherNameObjects, &objectID, &object, &level, &ctx))
431 return FALSE;
432
433 switch (objectID)
434 {
435 case ON_OBJ_ID_TYPE:
436 oid = known_oid(object);
437 break;
438 case ON_OBJ_VALUE:
439 if (oid == OID_XMPP_ADDR)
440 {
441 if (!parse_asn1_simple_object(&object, ASN1_UTF8STRING, level + 1, "xmppAddr"))
442 return FALSE;
443 }
444 break;
445 default:
446 break;
447 }
448 objectID++;
449 }
450 return TRUE;
451 }
452
453 /*
454 * extracts a generalName
455 */
456 static identification_t *parse_generalName(chunk_t blob, int level0)
457 {
458 u_char buf[BUF_LEN];
459 asn1_ctx_t ctx;
460 chunk_t object;
461 int objectID = 0;
462 u_int level;
463
464 asn1_init(&ctx, blob, level0, FALSE);
465
466 while (objectID < GN_OBJ_ROOF)
467 {
468 id_type_t id_type = ID_ANY;
469
470 if (!extract_object(generalNameObjects, &objectID, &object, &level, &ctx))
471 return NULL;
472
473 switch (objectID)
474 {
475 case GN_OBJ_RFC822_NAME:
476 id_type = ID_RFC822_ADDR;
477 break;
478 case GN_OBJ_DNS_NAME:
479 id_type = ID_FQDN;
480 break;
481 case GN_OBJ_URI:
482 id_type = ID_DER_ASN1_GN_URI;
483 break;
484 case GN_OBJ_DIRECTORY_NAME:
485 id_type = ID_DER_ASN1_DN;
486 break;
487 case GN_OBJ_IP_ADDRESS:
488 id_type = ID_IPV4_ADDR;
489 break;
490 case GN_OBJ_OTHER_NAME:
491 if (!parse_otherName(object, level + 1))
492 return NULL;
493 break;
494 case GN_OBJ_X400_ADDRESS:
495 case GN_OBJ_EDI_PARTY_NAME:
496 case GN_OBJ_REGISTERED_ID:
497 break;
498 default:
499 break;
500 }
501
502 if (id_type != ID_ANY)
503 {
504 identification_t *gn = identification_create_from_encoding(id_type, object);
505 logger->log(logger, CONTROL|LEVEL2, " '%s'", gn->get_string(gn));
506 return gn;
507 }
508 objectID++;
509 }
510 return NULL;
511 }
512
513
514 /**
515 * extracts one or several GNs and puts them into a chained list
516 */
517 static void parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list)
518 {
519 asn1_ctx_t ctx;
520 chunk_t object;
521 u_int level;
522 int objectID = 0;
523
524 asn1_init(&ctx, blob, level0, implicit);
525
526 while (objectID < GENERAL_NAMES_ROOF)
527 {
528 if (!extract_object(generalNamesObjects, &objectID, &object, &level, &ctx))
529 return;
530
531 if (objectID == GENERAL_NAMES_GN)
532 {
533 identification_t *gn = parse_generalName(object, level+1);
534
535 if (gn != NULL)
536 list->insert_last(list, gn);
537 }
538 objectID++;
539 }
540 return;
541 }
542
543 /**
544 * extracts and converts a UTCTIME or GENERALIZEDTIME object
545 */
546 time_t parse_time(chunk_t blob, int level0)
547 {
548 asn1_ctx_t ctx;
549 chunk_t object;
550 u_int level;
551 int objectID = 0;
552
553 asn1_init(&ctx, blob, level0, FALSE);
554
555 while (objectID < TIME_ROOF)
556 {
557 if (!extract_object(timeObjects, &objectID, &object, &level, &ctx))
558 return 0;
559
560 if (objectID == TIME_UTC || objectID == TIME_GENERALIZED)
561 {
562 return asn1totime(&object, (objectID == TIME_UTC)
563 ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME);
564 }
565 objectID++;
566 }
567 return 0;
568 }
569
570 /**
571 * extracts a keyIdentifier
572 */
573 static chunk_t parse_keyIdentifier(chunk_t blob, int level0, bool implicit)
574 {
575 asn1_ctx_t ctx;
576 chunk_t object;
577 u_int level;
578 int objectID = 0;
579
580 asn1_init(&ctx, blob, level0, implicit);
581
582 extract_object(keyIdentifierObjects, &objectID, &object, &level, &ctx);
583 return object;
584 }
585
586 /**
587 * extracts an authoritykeyIdentifier
588 */
589 void parse_authorityKeyIdentifier(chunk_t blob, int level0 , chunk_t *authKeyID, chunk_t *authKeySerialNumber)
590 {
591 asn1_ctx_t ctx;
592 chunk_t object;
593 u_int level;
594 int objectID = 0;
595
596 asn1_init(&ctx, blob, level0, FALSE);
597 while (objectID < AUTH_KEY_ID_ROOF)
598 {
599 if (!extract_object(authorityKeyIdentifierObjects, &objectID, &object, &level, &ctx))
600 {
601 return;
602 }
603 switch (objectID)
604 {
605 case AUTH_KEY_ID_KEY_ID:
606 *authKeyID = parse_keyIdentifier(object, level+1, TRUE);
607 break;
608 case AUTH_KEY_ID_CERT_ISSUER:
609 {
610 /* TODO: parse_generalNames(object, level+1, TRUE); */
611 break;
612 }
613 case AUTH_KEY_ID_CERT_SERIAL:
614 *authKeySerialNumber = object;
615 break;
616 default:
617 break;
618 }
619 objectID++;
620 }
621 }
622
623 /**
624 * extracts an authorityInfoAcess location
625 */
626 static void parse_authorityInfoAccess(chunk_t blob, int level0, chunk_t *accessLocation)
627 {
628 asn1_ctx_t ctx;
629 chunk_t object;
630 u_int level;
631 int objectID = 0;
632
633 u_int accessMethod = OID_UNKNOWN;
634
635 asn1_init(&ctx, blob, level0, FALSE);
636 while (objectID < AUTH_INFO_ACCESS_ROOF)
637 {
638 if (!extract_object(authorityInfoAccessObjects, &objectID, &object, &level, &ctx))
639 {
640 return;
641 }
642 switch (objectID)
643 {
644 case AUTH_INFO_ACCESS_METHOD:
645 accessMethod = known_oid(object);
646 break;
647 case AUTH_INFO_ACCESS_LOCATION:
648 {
649 switch (accessMethod)
650 {
651 case OID_OCSP:
652 if (*object.ptr == ASN1_CONTEXT_S_6)
653 {
654 if (asn1_length(&object) == ASN1_INVALID_LENGTH)
655 return;
656 logger->log(logger, CONTROL|LEVEL2, " '%.*s'",(int)object.len, object.ptr);
657 /* only HTTP(S) URIs accepted */
658 if (strncasecmp(object.ptr, "http", 4) == 0)
659 {
660 *accessLocation = object;
661 return;
662 }
663 }
664 logger->log(logger, ERROR|LEVEL2, "ignoring OCSP InfoAccessLocation with unkown protocol");
665 break;
666 default:
667 /* unkown accessMethod, ignoring */
668 break;
669 }
670 break;
671 }
672 default:
673 break;
674 }
675 objectID++;
676 }
677 }
678
679 /**
680 * extracts extendedKeyUsage OIDs
681 */
682 static bool parse_extendedKeyUsage(chunk_t blob, int level0)
683 {
684 asn1_ctx_t ctx;
685 chunk_t object;
686 u_int level;
687 int objectID = 0;
688
689 asn1_init(&ctx, blob, level0, FALSE);
690 while (objectID < EXT_KEY_USAGE_ROOF)
691 {
692 if (!extract_object(extendedKeyUsageObjects, &objectID, &object, &level, &ctx))
693 {
694 return FALSE;
695 }
696 if (objectID == EXT_KEY_USAGE_PURPOSE_ID &&
697 known_oid(object) == OID_OCSP_SIGNING)
698 {
699 return TRUE;
700 }
701 objectID++;
702 }
703 return FALSE;
704 }
705
706 /**
707 * extracts one or several crlDistributionPoints and puts them into
708 * a chained list
709 */
710 static void parse_crlDistributionPoints(chunk_t blob, int level0, linked_list_t *list)
711 {
712 asn1_ctx_t ctx;
713 chunk_t object;
714 u_int level;
715 int objectID = 0;
716
717 asn1_init(&ctx, blob, level0, FALSE);
718 while (objectID < CRL_DIST_POINTS_ROOF)
719 {
720 if (!extract_object(crlDistributionPointsObjects, &objectID, &object, &level, &ctx))
721 {
722 return;
723 }
724 if (objectID == CRL_DIST_POINTS_FULLNAME)
725 {
726 /* append extracted generalNames to existing chained list */
727 parse_generalNames(object, level+1, TRUE, list);
728
729 }
730 objectID++;
731 }
732 }
733
734
735 /**
736 * Parses an X.509v3 certificate
737 */
738 bool parse_x509cert(chunk_t blob, u_int level0, private_x509_t *cert)
739 {
740 asn1_ctx_t ctx;
741 bool critical;
742 chunk_t object;
743 u_int level;
744 u_int extn_oid = OID_UNKNOWN;
745 int objectID = 0;
746
747 asn1_init(&ctx, blob, level0, FALSE);
748 while (objectID < X509_OBJ_ROOF)
749 {
750 if (!extract_object(certObjects, &objectID, &object, &level, &ctx))
751 {
752 return FALSE;
753 }
754 /* those objects which will parsed further need the next higher level */
755 level++;
756 switch (objectID) {
757 case X509_OBJ_CERTIFICATE:
758 cert->certificate = object;
759 break;
760 case X509_OBJ_TBS_CERTIFICATE:
761 cert->tbsCertificate = object;
762 break;
763 case X509_OBJ_VERSION:
764 cert->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
765 logger->log(logger, CONTROL|LEVEL2, " v%d", cert->version);
766 break;
767 case X509_OBJ_SERIAL_NUMBER:
768 cert->serialNumber = object;
769 break;
770 case X509_OBJ_SIG_ALG:
771 cert->sigAlg = parse_algorithmIdentifier(object, level, NULL);
772 break;
773 case X509_OBJ_ISSUER:
774 cert->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
775 logger->log(logger, CONTROL|LEVEL1, " '%s'", cert->issuer->get_string(cert->issuer));
776 break;
777 case X509_OBJ_NOT_BEFORE:
778 cert->notBefore = parse_time(object, level);
779 break;
780 case X509_OBJ_NOT_AFTER:
781 cert->notAfter = parse_time(object, level);
782 break;
783 case X509_OBJ_SUBJECT:
784 cert->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
785 logger->log(logger, CONTROL|LEVEL1, " '%s'", cert->subject->get_string(cert->subject));
786 break;
787 case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM:
788 if (parse_algorithmIdentifier(object, level, NULL) != OID_RSA_ENCRYPTION)
789 {
790 logger->log(logger, ERROR|LEVEL1, " unsupported public key algorithm");
791 return FALSE;
792 }
793 break;
794 case X509_OBJ_SUBJECT_PUBLIC_KEY:
795 if (ctx.blobs[4].len > 0 && *ctx.blobs[4].ptr == 0x00)
796 {
797 /* skip initial bit string octet defining 0 unused bits */
798 ctx.blobs[4].ptr++; ctx.blobs[4].len--;
799 }
800 else
801 {
802 logger->log(logger, ERROR|LEVEL1, " invalid RSA public key format");
803 return FALSE;
804 }
805 break;
806 case X509_OBJ_RSA_PUBLIC_KEY:
807 cert->subjectPublicKey = object;
808 break;
809 case X509_OBJ_EXTN_ID:
810 extn_oid = known_oid(object);
811 break;
812 case X509_OBJ_CRITICAL:
813 critical = object.len && *object.ptr;
814 logger->log(logger, ERROR|LEVEL2, " %s", critical ? "TRUE" : "FALSE");
815 break;
816 case X509_OBJ_EXTN_VALUE:
817 {
818 switch (extn_oid) {
819 case OID_SUBJECT_KEY_ID:
820 cert->subjectKeyID = parse_keyIdentifier(object, level, FALSE);
821 break;
822 case OID_SUBJECT_ALT_NAME:
823 parse_generalNames(object, level, FALSE, cert->subjectAltNames);
824 break;
825 case OID_BASIC_CONSTRAINTS:
826 cert->isCA = parse_basicConstraints(object, level);
827 break;
828 case OID_CRL_DISTRIBUTION_POINTS:
829 parse_crlDistributionPoints(object, level, cert->crlDistributionPoints);
830 break;
831 case OID_AUTHORITY_KEY_ID:
832 parse_authorityKeyIdentifier(object, level , &cert->authKeyID, &cert->authKeySerialNumber);
833 break;
834 case OID_AUTHORITY_INFO_ACCESS:
835 parse_authorityInfoAccess(object, level, &cert->accessLocation);
836 break;
837 case OID_EXTENDED_KEY_USAGE:
838 cert->isOcspSigner = parse_extendedKeyUsage(object, level);
839 break;
840 case OID_NS_REVOCATION_URL:
841 case OID_NS_CA_REVOCATION_URL:
842 case OID_NS_CA_POLICY_URL:
843 case OID_NS_COMMENT:
844 if (!parse_asn1_simple_object(&object, ASN1_IA5STRING , level, oid_names[extn_oid].name))
845 return FALSE;
846 break;
847 default:
848 break;
849 }
850 break;
851 }
852 case X509_OBJ_ALGORITHM:
853 cert->algorithm = parse_algorithmIdentifier(object, level, NULL);
854 break;
855 case X509_OBJ_SIGNATURE:
856 cert->signature = object;
857 break;
858 default:
859 break;
860 }
861 objectID++;
862 }
863 time(&cert->installed);
864 return TRUE;
865 }
866
867 /**
868 * Implements x509_t.is_valid
869 */
870 static err_t is_valid(const private_x509_t *this, time_t *until)
871 {
872 char buf[TIMETOA_BUF];
873
874 time_t current_time = time(NULL);
875
876 timetoa(buf, BUF_LEN, &this->notBefore, TRUE);
877 logger->log(logger, CONTROL|LEVEL1, " not before : %s", buf);
878 timetoa(buf, BUF_LEN, &current_time, TRUE);
879 logger->log(logger, CONTROL|LEVEL1, " current time: %s", buf);
880 timetoa(buf, BUF_LEN, &this->notAfter, TRUE);
881 logger->log(logger, CONTROL|LEVEL1, " not after : %s", buf);
882
883 if (until != NULL
884 && (*until == UNDEFINED_TIME || this->notAfter < *until))
885 {
886 *until = this->notAfter;
887 }
888 if (current_time < this->notBefore)
889 return "is not valid yet";
890 if (current_time > this->notAfter)
891 return "has expired";
892 logger->log(logger, CONTROL|LEVEL1, " certificate is valid", buf);
893 return NULL;
894 }
895
896 /**
897 * Implements x509_t.is_ca
898 */
899 static bool is_ca(const private_x509_t *this)
900 {
901 return this->isCA;
902 }
903
904 /**
905 * Implements x509_t.equals_subjectAltName
906 */
907 static bool equals_subjectAltName(const private_x509_t *this, identification_t *id)
908 {
909 bool found = FALSE;
910 iterator_t *iterator = this->subjectAltNames->create_iterator(this->subjectAltNames, TRUE);
911
912 while (iterator->has_next(iterator))
913 {
914 identification_t *subjectAltName;
915
916 iterator->current(iterator, (void**)&subjectAltName);
917 if (id->equals(id, subjectAltName))
918 {
919 found = TRUE;
920 break;
921 }
922 }
923 iterator->destroy(iterator);
924 return found;
925 }
926
927 /**
928 * Implements x509_t.get_public_key
929 */
930 static rsa_public_key_t *get_public_key(const private_x509_t *this)
931 {
932 return this->public_key->clone(this->public_key);
933 }
934
935 /**
936 * Implements x509_t.get_subject
937 */
938 static identification_t *get_subject(const private_x509_t *this)
939 {
940 return this->subject;
941 }
942
943 /**
944 * Implements x509_t.get_issuer
945 */
946 static identification_t *get_issuer(const private_x509_t *this)
947 {
948 return this->issuer;
949 }
950
951 /**
952 * destroy
953 */
954 static void destroy(private_x509_t *this)
955 {
956 identification_t *id;
957 while (this->subjectAltNames->remove_last(this->subjectAltNames, (void**)&id) == SUCCESS)
958 {
959 id->destroy(id);
960 }
961 this->subjectAltNames->destroy(this->subjectAltNames);
962
963 while (this->crlDistributionPoints->remove_last(this->crlDistributionPoints, (void**)&id) == SUCCESS)
964 {
965 id->destroy(id);
966 }
967 this->crlDistributionPoints->destroy(this->crlDistributionPoints);
968
969 if (this->issuer)
970 this->issuer->destroy(this->issuer);
971
972 if (this->subject)
973 this->subject->destroy(this->subject);
974
975 if (this->public_key)
976 this->public_key->destroy(this->public_key);
977
978 free(this->certificate.ptr);
979 free(this);
980 }
981
982 /**
983 * checks if the expiration date has been reached and warns during the
984 * warning_interval of the imminent expiration.
985 * strict=TRUE declares a fatal error, strict=FALSE issues a warning upon expiry.
986 */
987 char* check_expiry(time_t expiration_date, int warning_interval, bool strict)
988 {
989 time_t now;
990 int time_left;
991
992 if (expiration_date == UNDEFINED_TIME)
993 return "ok (expires never)";
994
995 time_left = (expiration_date - time(NULL));
996 if (time_left < 0)
997 return strict? "fatal (expired)" : "warning (expired)";
998
999 {
1000 static char buf[35]; /* temporary storage */
1001 const char* unit = "second";
1002
1003 if (time_left > 86400*warning_interval)
1004 return "ok";
1005
1006 if (time_left > 172800)
1007 {
1008 time_left /= 86400;
1009 unit = "day";
1010 }
1011 else if (time_left > 7200)
1012 {
1013 time_left /= 3600;
1014 unit = "hour";
1015 }
1016 else if (time_left > 120)
1017 {
1018 time_left /= 60;
1019 unit = "minute";
1020 }
1021 snprintf(buf, sizeof(buf), "warning (expires in %d %s%s)", time_left, unit, (time_left == 1)?"":"s");
1022 }
1023 }
1024
1025 /**
1026 * log certificate
1027 */
1028 static void log_certificate(const private_x509_t *this, logger_t *logger, bool utc, bool has_key)
1029 {
1030 identification_t *subject = this->subject;
1031 identification_t *issuer = this->issuer;
1032 rsa_public_key_t *pubkey = this->public_key;
1033
1034 char buf[BUF_LEN];
1035
1036 /* determine the current time */
1037 time_t now = time(NULL);
1038
1039 timetoa(buf, BUF_LEN, &this->installed, utc);
1040 logger->log(logger, CONTROL, "%s", buf);
1041 logger->log(logger, CONTROL, " subject: '%s'", subject->get_string(subject));
1042 logger->log(logger, CONTROL, " issuer: '%s'", issuer->get_string(issuer));
1043
1044 chunk_to_hex(buf, BUF_LEN, this->serialNumber);
1045 logger->log(logger, CONTROL, " serial: %s", buf);
1046
1047 timetoa(buf, BUF_LEN, &this->notBefore, utc);
1048 logger->log(logger, CONTROL, " validity: not before %s %s", buf,
1049 (this->notBefore < now)? "ok":"fatal (not valid yet)");
1050
1051 timetoa(buf, BUF_LEN, &this->notAfter, utc);
1052 logger->log(logger, CONTROL, " not after %s %s", buf,
1053 check_expiry(this->notAfter, CERT_WARNING_INTERVAL, TRUE));
1054
1055 logger->log(logger, CONTROL, " pubkey: RSA %d bits%s",
1056 BITS_PER_BYTE * pubkey->get_keysize(pubkey), has_key? ", has private key":"");
1057 chunk_to_hex(buf, BUF_LEN, pubkey->get_keyid(pubkey));
1058 logger->log(logger, CONTROL, " keyid: %s", buf);
1059
1060 if (this->subjectKeyID.ptr != NULL)
1061 {
1062 chunk_to_hex(buf, BUF_LEN, this->subjectKeyID);
1063 logger->log(logger, CONTROL, " subjkey: %s", buf);
1064 }
1065 if (this->authKeyID.ptr != NULL)
1066 {
1067 chunk_to_hex(buf, BUF_LEN, this->authKeyID);
1068 logger->log(logger, CONTROL, " authkey: %s", buf);
1069 }
1070 if (this->authKeySerialNumber.ptr != NULL)
1071 {
1072 chunk_to_hex(buf, BUF_LEN, this->authKeySerialNumber);
1073 logger->log(logger, CONTROL, " aserial: %s", buf);
1074 }
1075 }
1076
1077 /*
1078 * Described in header.
1079 */
1080 x509_t *x509_create_from_chunk(chunk_t chunk)
1081 {
1082 private_x509_t *this = malloc_thing(private_x509_t);
1083
1084 /* initialize */
1085 this->subjectPublicKey = CHUNK_INITIALIZER;
1086 this->public_key = NULL;
1087 this->subject = NULL;
1088 this->issuer = NULL;
1089 this->subjectAltNames = linked_list_create();
1090 this->crlDistributionPoints = linked_list_create();
1091 this->subjectKeyID = CHUNK_INITIALIZER;
1092 this->authKeyID = CHUNK_INITIALIZER;
1093 this->authKeySerialNumber = CHUNK_INITIALIZER;
1094
1095 /* public functions */
1096 this->public.equals = (bool (*) (const x509_t*,const x509_t*))equals;
1097 this->public.equals_subjectAltName = (bool (*) (const x509_t*,identification_t*))equals_subjectAltName;
1098 this->public.is_valid = (err_t (*) (const x509_t*,time_t*))is_valid;
1099 this->public.is_ca = (bool (*) (const x509_t*))is_ca;
1100 this->public.destroy = (void (*) (x509_t*))destroy;
1101 this->public.get_public_key = (rsa_public_key_t* (*) (const x509_t*))get_public_key;
1102 this->public.get_subject = (identification_t* (*) (const x509_t*))get_subject;
1103 this->public.get_issuer = (identification_t* (*) (const x509_t*))get_issuer;
1104 this->public.log_certificate = (void (*) (const x509_t*,logger_t*,bool,bool))log_certificate;
1105
1106 /* we do not use a per-instance logger right now, since its not always accessible */
1107 logger = logger_manager->get_logger(logger_manager, ASN1);
1108
1109 if (!parse_x509cert(chunk, 0, this))
1110 {
1111 destroy(this);
1112 return NULL;
1113 }
1114
1115 /* extract public key from certificate */
1116 this->public_key = rsa_public_key_create_from_chunk(this->subjectPublicKey);
1117 if (this->public_key == NULL)
1118 {
1119 destroy(this);
1120 return NULL;
1121 }
1122
1123 return &this->public;
1124 }
1125
1126 /*
1127 * Described in header.
1128 */
1129 x509_t *x509_create_from_file(const char *filename, const char *label)
1130 {
1131 bool pgp = FALSE;
1132 chunk_t chunk = CHUNK_INITIALIZER;
1133 x509_t *cert = NULL;
1134
1135 if (!pem_asn1_load_file(filename, "", label, &chunk, &pgp))
1136 return NULL;
1137
1138 cert = x509_create_from_chunk(chunk);
1139
1140 if (cert == NULL)
1141 free(chunk.ptr);
1142 return cert;
1143 }