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