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