changed prefix of crl_reason_t values from CRL_ to CRL_REASON_
[strongswan.git] / src / pluto / x509.c
1 /* Support of X.509 certificates
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-2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <dirent.h>
23 #include <time.h>
24 #include <sys/types.h>
25
26 #include <freeswan.h>
27
28 #include <asn1/asn1.h>
29 #include <asn1/asn1_parser.h>
30 #include <asn1/oid.h>
31 #include <crypto/hashers/hasher.h>
32
33 #include "constants.h"
34 #include "defs.h"
35 #include "log.h"
36 #include "id.h"
37 #include "x509.h"
38 #include "crl.h"
39 #include "ca.h"
40 #include "certs.h"
41 #include "keys.h"
42 #include "whack.h"
43 #include "fetch.h"
44 #include "ocsp.h"
45
46 /**
47 * Chained lists of X.509 end certificates
48 */
49 static x509cert_t *x509certs = NULL;
50
51 /**
52 * ASN.1 definition of a basicConstraints extension
53 */
54 static const asn1Object_t basicConstraintsObjects[] = {
55 { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
56 { 1, "CA", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 1 */
57 { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */
58 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
59 { 0, "exit", ASN1_EOC, ASN1_EXIT }
60 };
61 #define BASIC_CONSTRAINTS_CA 1
62
63 /**
64 * ASN.1 definition of a authorityKeyIdentifier extension
65 */
66 static const asn1Object_t authKeyIdentifierObjects[] = {
67 { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
68 { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_BODY }, /* 1 */
69 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
70 { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */
71 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
72 { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */
73 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */
74 { 0, "exit", ASN1_EOC, ASN1_EXIT }
75 };
76 #define AUTH_KEY_ID_KEY_ID 1
77 #define AUTH_KEY_ID_CERT_ISSUER 3
78 #define AUTH_KEY_ID_CERT_SERIAL 5
79
80 /**
81 * ASN.1 definition of a authorityInfoAccess extension
82 */
83 static const asn1Object_t authInfoAccessObjects[] = {
84 { 0, "authorityInfoAccess", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
85 { 1, "accessDescription", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
86 { 2, "accessMethod", ASN1_OID, ASN1_BODY }, /* 2 */
87 { 2, "accessLocation", ASN1_EOC, ASN1_RAW }, /* 3 */
88 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 4 */
89 { 0, "exit", ASN1_EOC, ASN1_EXIT }
90 };
91 #define AUTH_INFO_ACCESS_METHOD 2
92 #define AUTH_INFO_ACCESS_LOCATION 3
93
94 /**
95 * ASN.1 definition of a extendedKeyUsage extension
96 */
97 static const asn1Object_t extendedKeyUsageObjects[] = {
98 { 0, "extendedKeyUsage", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
99 { 1, "keyPurposeID", ASN1_OID, ASN1_BODY }, /* 1 */
100 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
101 { 0, "exit", ASN1_EOC, ASN1_EXIT }
102 };
103 #define EXT_KEY_USAGE_PURPOSE_ID 1
104
105 /**
106 * ASN.1 definition of generalNames
107 */
108 static const asn1Object_t generalNamesObjects[] = {
109 { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
110 { 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */
111 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
112 { 0, "exit", ASN1_EOC, ASN1_EXIT }
113 };
114 #define GENERAL_NAMES_GN 1
115
116 /**
117 * ASN.1 definition of generalName
118 */
119 static const asn1Object_t generalNameObjects[] = {
120 { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */
121 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
122 { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */
123 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
124 { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */
125 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
126 { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */
127 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
128 { 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT|ASN1_BODY }, /* 8 */
129 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
130 { 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT|ASN1_BODY }, /* 10 */
131 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
132 { 0, "URI", ASN1_CONTEXT_S_6, ASN1_OPT|ASN1_BODY }, /* 12 */
133 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */
134 { 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT|ASN1_BODY }, /* 14 */
135 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */
136 { 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT|ASN1_BODY }, /* 16 */
137 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 17 */
138 { 0, "exit", ASN1_EOC, ASN1_EXIT }
139 };
140 #define GN_OBJ_OTHER_NAME 0
141 #define GN_OBJ_RFC822_NAME 2
142 #define GN_OBJ_DNS_NAME 4
143 #define GN_OBJ_X400_ADDRESS 6
144 #define GN_OBJ_DIRECTORY_NAME 8
145 #define GN_OBJ_EDI_PARTY_NAME 10
146 #define GN_OBJ_URI 12
147 #define GN_OBJ_IP_ADDRESS 14
148 #define GN_OBJ_REGISTERED_ID 16
149
150 /**
151 * ASN.1 definition of otherName
152 */
153 static const asn1Object_t otherNameObjects[] = {
154 {0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */
155 {0, "value", ASN1_CONTEXT_C_0, ASN1_BODY }, /* 1 */
156 {0, "exit", ASN1_EOC, ASN1_EXIT }
157 };
158 #define ON_OBJ_ID_TYPE 0
159 #define ON_OBJ_VALUE 1
160
161 /**
162 * ASN.1 definition of crlDistributionPoints
163 */
164 static const asn1Object_t crlDistributionPointsObjects[] = {
165 { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
166 { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
167 { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 2 */
168 { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */
169 { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
170 { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */
171 { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
172 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
173 { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */
174 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
175 { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_BODY }, /* 10 */
176 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
177 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
178 { 0, "exit", ASN1_EOC, ASN1_EXIT }
179 };
180 #define CRL_DIST_POINTS_FULLNAME 3
181
182 /**
183 * ASN.1 definition of an X.509v3 x509_cert
184 */
185 static const asn1Object_t certObjects[] = {
186 { 0, "x509", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
187 { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
188 { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
189 { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
190 { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
191 { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */
192 { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
193 { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */
194 { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */
195 { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */
196 { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
197 { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_RAW }, /* 11 */
198 { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
199 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
200 { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 14 */
201 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
202 { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 16 */
203 { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 17 */
204 { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 18 */
205 { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 19 */
206 { 5, "critical", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 20 */
207 { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 21 */
208 { 3, "end loop", ASN1_EOC, ASN1_END }, /* 22 */
209 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 23 */
210 { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 24 */
211 { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 25 */
212 { 0, "exit", ASN1_EOC, ASN1_EXIT }
213 };
214 #define X509_OBJ_CERTIFICATE 0
215 #define X509_OBJ_TBS_CERTIFICATE 1
216 #define X509_OBJ_VERSION 3
217 #define X509_OBJ_SERIAL_NUMBER 4
218 #define X509_OBJ_SIG_ALG 5
219 #define X509_OBJ_ISSUER 6
220 #define X509_OBJ_NOT_BEFORE 8
221 #define X509_OBJ_NOT_AFTER 9
222 #define X509_OBJ_SUBJECT 10
223 #define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO 11
224 #define X509_OBJ_EXTN_ID 19
225 #define X509_OBJ_CRITICAL 20
226 #define X509_OBJ_EXTN_VALUE 21
227 #define X509_OBJ_ALGORITHM 24
228 #define X509_OBJ_SIGNATURE 25
229
230 const x509cert_t empty_x509cert = {
231 NULL , /* *next */
232 UNDEFINED_TIME, /* installed */
233 0 , /* count */
234 FALSE , /* smartcard */
235 AUTH_NONE , /* authority_flags */
236 { NULL, 0 } , /* certificate */
237 { NULL, 0 } , /* tbsCertificate */
238 1 , /* version */
239 { NULL, 0 } , /* serialNumber */
240 OID_UNKNOWN , /* sigAlg */
241 { NULL, 0 } , /* issuer */
242 /* validity */
243 0 , /* notBefore */
244 0 , /* notAfter */
245 { NULL, 0 } , /* subject */
246 NULL , /* public_key */
247 /* issuerUniqueID */
248 /* subjectUniqueID */
249 /* extensions */
250 /* extension */
251 /* extnID */
252 /* critical */
253 /* extnValue */
254 FALSE , /* isCA */
255 FALSE , /* isOcspSigner */
256 { NULL, 0 } , /* subjectKeyID */
257 { NULL, 0 } , /* authKeyID */
258 { NULL, 0 } , /* authKeySerialNumber */
259 { NULL, 0 } , /* accessLocation */
260 NULL , /* subjectAltName */
261 NULL , /* crlDistributionPoints */
262 OID_UNKNOWN , /* algorithm */
263 { NULL, 0 } /* signature */
264 };
265
266 /* coding of X.501 distinguished name */
267
268 typedef struct {
269 const u_char *name;
270 chunk_t oid;
271 u_char type;
272 } x501rdn_t;
273
274 /* X.501 acronyms for well known object identifiers (OIDs) */
275
276 static u_char oid_ND[] = {0x02, 0x82, 0x06, 0x01,
277 0x0A, 0x07, 0x14};
278 static u_char oid_UID[] = {0x09, 0x92, 0x26, 0x89, 0x93,
279 0xF2, 0x2C, 0x64, 0x01, 0x01};
280 static u_char oid_DC[] = {0x09, 0x92, 0x26, 0x89, 0x93,
281 0xF2, 0x2C, 0x64, 0x01, 0x19};
282 static u_char oid_CN[] = {0x55, 0x04, 0x03};
283 static u_char oid_S[] = {0x55, 0x04, 0x04};
284 static u_char oid_SN[] = {0x55, 0x04, 0x05};
285 static u_char oid_C[] = {0x55, 0x04, 0x06};
286 static u_char oid_L[] = {0x55, 0x04, 0x07};
287 static u_char oid_ST[] = {0x55, 0x04, 0x08};
288 static u_char oid_O[] = {0x55, 0x04, 0x0A};
289 static u_char oid_OU[] = {0x55, 0x04, 0x0B};
290 static u_char oid_T[] = {0x55, 0x04, 0x0C};
291 static u_char oid_D[] = {0x55, 0x04, 0x0D};
292 static u_char oid_N[] = {0x55, 0x04, 0x29};
293 static u_char oid_G[] = {0x55, 0x04, 0x2A};
294 static u_char oid_I[] = {0x55, 0x04, 0x2B};
295 static u_char oid_ID[] = {0x55, 0x04, 0x2D};
296 static u_char oid_EN[] = {0x60, 0x86, 0x48, 0x01, 0x86,
297 0xF8, 0x42, 0x03, 0x01, 0x03};
298 static u_char oid_E[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
299 0x0D, 0x01, 0x09, 0x01};
300 static u_char oid_UN[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
301 0x0D, 0x01, 0x09, 0x02};
302 static u_char oid_TCGID[] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x89,
303 0x31, 0x01, 0x01, 0x02, 0x02, 0x4B};
304
305 static const x501rdn_t x501rdns[] = {
306 {"ND" , {oid_ND, 7}, ASN1_PRINTABLESTRING},
307 {"UID" , {oid_UID, 10}, ASN1_PRINTABLESTRING},
308 {"DC" , {oid_DC, 10}, ASN1_PRINTABLESTRING},
309 {"CN" , {oid_CN, 3}, ASN1_PRINTABLESTRING},
310 {"S" , {oid_S, 3}, ASN1_PRINTABLESTRING},
311 {"SN" , {oid_SN, 3}, ASN1_PRINTABLESTRING},
312 {"serialNumber" , {oid_SN, 3}, ASN1_PRINTABLESTRING},
313 {"C" , {oid_C, 3}, ASN1_PRINTABLESTRING},
314 {"L" , {oid_L, 3}, ASN1_PRINTABLESTRING},
315 {"ST" , {oid_ST, 3}, ASN1_PRINTABLESTRING},
316 {"O" , {oid_O, 3}, ASN1_PRINTABLESTRING},
317 {"OU" , {oid_OU, 3}, ASN1_PRINTABLESTRING},
318 {"T" , {oid_T, 3}, ASN1_PRINTABLESTRING},
319 {"D" , {oid_D, 3}, ASN1_PRINTABLESTRING},
320 {"N" , {oid_N, 3}, ASN1_PRINTABLESTRING},
321 {"G" , {oid_G, 3}, ASN1_PRINTABLESTRING},
322 {"I" , {oid_I, 3}, ASN1_PRINTABLESTRING},
323 {"ID" , {oid_ID, 3}, ASN1_PRINTABLESTRING},
324 {"EN" , {oid_EN, 10}, ASN1_PRINTABLESTRING},
325 {"employeeNumber" , {oid_EN, 10}, ASN1_PRINTABLESTRING},
326 {"E" , {oid_E, 9}, ASN1_IA5STRING},
327 {"Email" , {oid_E, 9}, ASN1_IA5STRING},
328 {"emailAddress" , {oid_E, 9}, ASN1_IA5STRING},
329 {"UN" , {oid_UN, 9}, ASN1_IA5STRING},
330 {"unstructuredName", {oid_UN, 9}, ASN1_IA5STRING},
331 {"TCGID" , {oid_TCGID, 12}, ASN1_PRINTABLESTRING}
332 };
333
334 #define X501_RDN_ROOF 26
335
336 static u_char ASN1_subjectAltName_oid_str[] = {
337 0x06, 0x03, 0x55, 0x1D, 0x11
338 };
339
340 static const chunk_t ASN1_subjectAltName_oid = chunk_from_buf(ASN1_subjectAltName_oid_str);
341
342 static void update_chunk(chunk_t *ch, int n)
343 {
344 n = (n > -1 && n < (int)ch->len)? n : (int)ch->len-1;
345 ch->ptr += n; ch->len -= n;
346 }
347
348
349 /**
350 * Pointer is set to the first RDN in a DN
351 */
352 static err_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
353 {
354 *rdn = chunk_empty;
355 *attribute = chunk_empty;
356
357 /* a DN is a SEQUENCE OF RDNs */
358
359 if (*dn.ptr != ASN1_SEQUENCE)
360 {
361 return "DN is not a SEQUENCE";
362 }
363
364 rdn->len = asn1_length(&dn);
365
366 if (rdn->len == ASN1_INVALID_LENGTH)
367 {
368 return "Invalid RDN length";
369 }
370 rdn->ptr = dn.ptr;
371
372 /* are there any RDNs ? */
373 *next = rdn->len > 0;
374
375 return NULL;
376 }
377
378 /**
379 * Fetches the next RDN in a DN
380 */
381 static err_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid,
382 chunk_t *value, asn1_t *type, bool *next)
383 {
384 chunk_t body;
385
386 /* initialize return values */
387 *oid = chunk_empty;
388 *value = chunk_empty;
389
390 /* if all attributes have been parsed, get next rdn */
391 if (attribute->len <= 0)
392 {
393 /* an RDN is a SET OF attributeTypeAndValue */
394 if (*rdn->ptr != ASN1_SET)
395 {
396 return "RDN is not a SET";
397 }
398 attribute->len = asn1_length(rdn);
399
400 if (attribute->len == ASN1_INVALID_LENGTH)
401 {
402 return "Invalid attribute length";
403 }
404 attribute->ptr = rdn->ptr;
405
406 /* advance to start of next RDN */
407 rdn->ptr += attribute->len;
408 rdn->len -= attribute->len;
409 }
410
411 /* an attributeTypeAndValue is a SEQUENCE */
412 if (*attribute->ptr != ASN1_SEQUENCE)
413 {
414 return "attributeTypeAndValue is not a SEQUENCE";
415 }
416
417 /* extract the attribute body */
418 body.len = asn1_length(attribute);
419
420 if (body.len == ASN1_INVALID_LENGTH)
421 {
422 return "Invalid attribute body length";
423 }
424 body.ptr = attribute->ptr;
425
426 /* advance to start of next attribute */
427 attribute->ptr += body.len;
428 attribute->len -= body.len;
429
430 /* attribute type is an OID */
431 if (*body.ptr != ASN1_OID)
432 {
433 return "attributeType is not an OID";
434 }
435
436 /* extract OID */
437 oid->len = asn1_length(&body);
438
439 if (oid->len == ASN1_INVALID_LENGTH)
440 {
441 return "Invalid attribute OID length";
442 }
443 oid->ptr = body.ptr;
444
445 /* advance to the attribute value */
446 body.ptr += oid->len;
447 body.len -= oid->len;
448
449 /* extract string type */
450 *type = *body.ptr;
451
452 /* extract string value */
453 value->len = asn1_length(&body);
454
455 if (value->len == ASN1_INVALID_LENGTH)
456 {
457 return "Invalid attribute string length";
458 }
459 value->ptr = body.ptr;
460
461 /* are there any RDNs left? */
462 *next = rdn->len > 0 || attribute->len > 0;
463
464 return NULL;
465 }
466
467 /**
468 * Parses an ASN.1 distinguished name int its OID/value pairs
469 */
470 static err_t dn_parse(chunk_t dn, chunk_t *str)
471 {
472 chunk_t rdn, oid, attribute, value;
473 asn1_t type;
474 int oid_code;
475 bool next;
476 bool first = TRUE;
477
478 err_t ugh = init_rdn(dn, &rdn, &attribute, &next);
479
480 if (ugh != NULL) /* a parsing error has occured */
481 {
482 return ugh;
483 }
484
485 while (next)
486 {
487 ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
488
489 if (ugh != NULL) /* a parsing error has occured */
490 {
491 return ugh;
492 }
493
494 if (first) /* first OID/value pair */
495 {
496 first = FALSE;
497 }
498 else /* separate OID/value pair by a comma */
499 {
500 update_chunk(str, snprintf(str->ptr,str->len,", "));
501 }
502
503 /* print OID */
504 oid_code = asn1_known_oid(oid);
505 if (oid_code == OID_UNKNOWN) /* OID not found in list */
506 {
507 hex_str(oid, str);
508 }
509 else
510 {
511 update_chunk(str, snprintf(str->ptr,str->len,"%s",
512 oid_names[oid_code].name));
513 }
514
515 /* print value */
516 update_chunk(str, snprintf(str->ptr,str->len,"=%.*s",
517 (int)value.len,value.ptr));
518 }
519 return NULL;
520 }
521
522 /**
523 * Count the number of wildcard RDNs in a distinguished name
524 */
525 int dn_count_wildcards(chunk_t dn)
526 {
527 chunk_t rdn, attribute, oid, value;
528 asn1_t type;
529 bool next;
530 int wildcards = 0;
531
532 err_t ugh = init_rdn(dn, &rdn, &attribute, &next);
533
534 if (ugh != NULL) /* a parsing error has occured */
535 {
536 return -1;
537 }
538
539 while (next)
540 {
541 ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
542
543 if (ugh != NULL) /* a parsing error has occured */
544 {
545 return -1;
546 }
547 if (value.len == 1 && *value.ptr == '*')
548 {
549 wildcards++; /* we have found a wildcard RDN */
550 }
551 }
552 return wildcards;
553 }
554
555 /**
556 * Prints a binary string in hexadecimal form
557 */
558 void hex_str(chunk_t bin, chunk_t *str)
559 {
560 u_int i;
561 update_chunk(str, snprintf(str->ptr,str->len,"0x"));
562 for (i=0; i < bin.len; i++)
563 update_chunk(str, snprintf(str->ptr,str->len,"%02X",*bin.ptr++));
564 }
565
566
567 /** Converts a binary DER-encoded ASN.1 distinguished name
568 * into LDAP-style human-readable ASCII format
569 */
570 int dntoa(char *dst, size_t dstlen, chunk_t dn)
571 {
572 err_t ugh = NULL;
573 chunk_t str;
574
575 str.ptr = dst;
576 str.len = dstlen;
577 ugh = dn_parse(dn, &str);
578
579 if (ugh != NULL) /* error, print DN as hex string */
580 {
581 DBG(DBG_PARSING,
582 DBG_log("error in DN parsing: %s", ugh)
583 )
584 str.ptr = dst;
585 str.len = dstlen;
586 hex_str(dn, &str);
587 }
588 return (int)(dstlen - str.len);
589 }
590
591 /**
592 * Same as dntoa but prints a special string for a null dn
593 */
594 int dntoa_or_null(char *dst, size_t dstlen, chunk_t dn, const char* null_dn)
595 {
596 if (dn.ptr == NULL)
597 {
598 return snprintf(dst, dstlen, "%s", null_dn);
599 }
600 else
601 {
602 return dntoa(dst, dstlen, dn);
603 }
604 }
605
606
607 /**
608 * Codes ASN.1 lengths up to a size of 16'777'215 bytes
609 */
610 static void code_asn1_length(size_t length, chunk_t *code)
611 {
612 if (length < 128)
613 {
614 code->ptr[0] = length;
615 code->len = 1;
616 }
617 else if (length < 256)
618 {
619 code->ptr[0] = 0x81;
620 code->ptr[1] = (u_char) length;
621 code->len = 2;
622 }
623 else if (length < 65536)
624 {
625 code->ptr[0] = 0x82;
626 code->ptr[1] = length >> 8;
627 code->ptr[2] = length & 0x00ff;
628 code->len = 3;
629 }
630 else
631 {
632 code->ptr[0] = 0x83;
633 code->ptr[1] = length >> 16;
634 code->ptr[2] = (length >> 8) & 0x00ff;
635 code->ptr[3] = length & 0x0000ff;
636 code->len = 4;
637 }
638 }
639
640 /**
641 * Converts an LDAP-style human-readable ASCII-encoded
642 * ASN.1 distinguished name into binary DER-encoded format
643 */
644 err_t atodn(char *src, chunk_t *dn)
645 {
646 /* finite state machine for atodn */
647
648 typedef enum {
649 SEARCH_OID = 0,
650 READ_OID = 1,
651 SEARCH_NAME = 2,
652 READ_NAME = 3,
653 UNKNOWN_OID = 4
654 } state_t;
655
656 u_char oid_len_buf[3];
657 u_char name_len_buf[3];
658 u_char rdn_seq_len_buf[3];
659 u_char rdn_set_len_buf[3];
660 u_char dn_seq_len_buf[3];
661
662 chunk_t asn1_oid_len = { oid_len_buf, 0 };
663 chunk_t asn1_name_len = { name_len_buf, 0 };
664 chunk_t asn1_rdn_seq_len = { rdn_seq_len_buf, 0 };
665 chunk_t asn1_rdn_set_len = { rdn_set_len_buf, 0 };
666 chunk_t asn1_dn_seq_len = { dn_seq_len_buf, 0 };
667 chunk_t oid = chunk_empty;
668 chunk_t name = chunk_empty;
669
670 int whitespace = 0;
671 int rdn_seq_len = 0;
672 int rdn_set_len = 0;
673 int dn_seq_len = 0;
674 int pos = 0;
675
676 err_t ugh = NULL;
677
678 u_char *dn_ptr = dn->ptr + 4;
679
680 state_t state = SEARCH_OID;
681
682 do
683 {
684 switch (state)
685 {
686 case SEARCH_OID:
687 if (*src != ' ' && *src != '/' && *src != ',')
688 {
689 oid.ptr = src;
690 oid.len = 1;
691 state = READ_OID;
692 }
693 break;
694 case READ_OID:
695 if (*src != ' ' && *src != '=')
696 {
697 oid.len++;
698 }
699 else
700 {
701 for (pos = 0; pos < X501_RDN_ROOF; pos++)
702 {
703 if (strlen(x501rdns[pos].name) == oid.len &&
704 strncasecmp(x501rdns[pos].name, oid.ptr, oid.len) == 0)
705 {
706 break; /* found a valid OID */
707 }
708 }
709 if (pos == X501_RDN_ROOF)
710 {
711 ugh = "unknown OID in distinguished name";
712 state = UNKNOWN_OID;
713 break;
714 }
715 code_asn1_length(x501rdns[pos].oid.len, &asn1_oid_len);
716
717 /* reset oid and change state */
718 oid = chunk_empty;
719 state = SEARCH_NAME;
720 }
721 break;
722 case SEARCH_NAME:
723 if (*src != ' ' && *src != '=')
724 {
725 name.ptr = src;
726 name.len = 1;
727 whitespace = 0;
728 state = READ_NAME;
729 }
730 break;
731 case READ_NAME:
732 if (*src != ',' && *src != '/' && *src != '\0')
733 {
734 name.len++;
735 if (*src == ' ')
736 {
737 whitespace++;
738 }
739 else
740 {
741 whitespace = 0;
742 }
743 }
744 else
745 {
746 name.len -= whitespace;
747 code_asn1_length(name.len, &asn1_name_len);
748
749 /* compute the length of the relative distinguished name sequence */
750 rdn_seq_len = 1 + asn1_oid_len.len + x501rdns[pos].oid.len +
751 1 + asn1_name_len.len + name.len;
752 code_asn1_length(rdn_seq_len, &asn1_rdn_seq_len);
753
754 /* compute the length of the relative distinguished name set */
755 rdn_set_len = 1 + asn1_rdn_seq_len.len + rdn_seq_len;
756 code_asn1_length(rdn_set_len, &asn1_rdn_set_len);
757
758 /* encode the relative distinguished name */
759 *dn_ptr++ = ASN1_SET;
760 chunkcpy(dn_ptr, asn1_rdn_set_len);
761 *dn_ptr++ = ASN1_SEQUENCE;
762 chunkcpy(dn_ptr, asn1_rdn_seq_len);
763 *dn_ptr++ = ASN1_OID;
764 chunkcpy(dn_ptr, asn1_oid_len);
765 chunkcpy(dn_ptr, x501rdns[pos].oid);
766 /* encode the ASN.1 character string type of the name */
767 *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
768 && !asn1_is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
769 chunkcpy(dn_ptr, asn1_name_len);
770 chunkcpy(dn_ptr, name);
771
772 /* accumulate the length of the distinguished name sequence */
773 dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
774
775 /* reset name and change state */
776 name = chunk_empty;
777 state = SEARCH_OID;
778 }
779 break;
780 case UNKNOWN_OID:
781 break;
782 }
783 } while (*src++ != '\0');
784
785 /* complete the distinguished name sequence*/
786 code_asn1_length(dn_seq_len, &asn1_dn_seq_len);
787 dn->ptr += 3 - asn1_dn_seq_len.len;
788 dn->len = 1 + asn1_dn_seq_len.len + dn_seq_len;
789 dn_ptr = dn->ptr;
790 *dn_ptr++ = ASN1_SEQUENCE;
791 chunkcpy(dn_ptr, asn1_dn_seq_len);
792 return ugh;
793 }
794
795 /**
796 * compare two distinguished names by comparing the individual RDNs
797 */
798 bool same_dn(chunk_t a, chunk_t b)
799 {
800 chunk_t rdn_a, rdn_b, attribute_a, attribute_b;
801 chunk_t oid_a, oid_b, value_a, value_b;
802 asn1_t type_a, type_b;
803 bool next_a, next_b;
804
805 /* same lengths for the DNs */
806 if (a.len != b.len)
807 {
808 return FALSE;
809 }
810
811 /* try a binary comparison first */
812 if (memeq(a.ptr, b.ptr, b.len))
813 {
814 return TRUE;
815 }
816
817 /* initialize DN parsing */
818 if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != NULL
819 || init_rdn(b, &rdn_b, &attribute_b, &next_b) != NULL)
820 {
821 return FALSE;
822 }
823
824 /* fetch next RDN pair */
825 while (next_a && next_b)
826 {
827 /* parse next RDNs and check for errors */
828 if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != NULL
829 || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != NULL)
830 {
831 return FALSE;
832 }
833
834 /* OIDs must agree */
835 if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
836 {
837 return FALSE;
838 }
839
840 /* same lengths for values */
841 if (value_a.len != value_b.len)
842 {
843 return FALSE;
844 }
845
846 /* printableStrings and email RDNs require uppercase comparison */
847 if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
848 (type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_EMAIL_ADDRESS)))
849 {
850 if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
851 {
852 return FALSE;
853 }
854 }
855 else
856 {
857 if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
858 {
859 return FALSE;
860 }
861 }
862 }
863 /* both DNs must have same number of RDNs */
864 if (next_a || next_b)
865 {
866 return FALSE;
867 }
868
869 /* the two DNs are equal! */
870 return TRUE;
871 }
872
873
874 /**
875 * Compare two distinguished names by comparing the individual RDNs.
876 * A single'*' character designates a wildcard RDN in DN b.
877 */
878 bool match_dn(chunk_t a, chunk_t b, int *wildcards)
879 {
880 chunk_t rdn_a, rdn_b, attribute_a, attribute_b;
881 chunk_t oid_a, oid_b, value_a, value_b;
882 asn1_t type_a, type_b;
883 bool next_a, next_b;
884
885 /* initialize wildcard counter */
886 *wildcards = 0;
887
888 /* initialize DN parsing */
889 if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != NULL
890 || init_rdn(b, &rdn_b, &attribute_b, &next_b) != NULL)
891 {
892 return FALSE;
893 }
894
895 /* fetch next RDN pair */
896 while (next_a && next_b)
897 {
898 /* parse next RDNs and check for errors */
899 if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != NULL
900 || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != NULL)
901 {
902 return FALSE;
903 }
904
905 /* OIDs must agree */
906 if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
907 {
908 return FALSE;
909 }
910
911 /* does rdn_b contain a wildcard? */
912 if (value_b.len == 1 && *value_b.ptr == '*')
913 {
914 (*wildcards)++;
915 continue;
916 }
917
918 /* same lengths for values */
919 if (value_a.len != value_b.len)
920 {
921 return FALSE;
922 }
923
924 /* printableStrings and email RDNs require uppercase comparison */
925 if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
926 (type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_EMAIL_ADDRESS)))
927 {
928 if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
929 {
930 return FALSE;
931 }
932 }
933 else
934 {
935 if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
936 {
937 return FALSE;
938 }
939 }
940 }
941
942 /* both DNs must have same number of RDNs */
943 if (next_a || next_b)
944 {
945 return FALSE;
946 }
947
948 /* the two DNs match! */
949 return TRUE;
950 }
951
952 /**
953 * Compare two X.509 certificates by comparing their signatures
954 */
955 bool same_x509cert(const x509cert_t *a, const x509cert_t *b)
956 {
957 return chunk_equals(a->signature, b->signature);
958 }
959
960 /**
961 * For each link pointing to the certificate increase the count by one
962 */
963 void share_x509cert(x509cert_t *cert)
964 {
965 if (cert != NULL)
966 {
967 cert->count++;
968 }
969 }
970
971 /**
972 * Add a X.509 user/host certificate to the chained list
973 */
974 x509cert_t* add_x509cert(x509cert_t *cert)
975 {
976 x509cert_t *c = x509certs;
977
978 while (c != NULL)
979 {
980 if (same_x509cert(c, cert)) /* already in chain, free cert */
981 {
982 free_x509cert(cert);
983 return c;
984 }
985 c = c->next;
986 }
987
988 /* insert new cert at the root of the chain */
989 lock_certs_and_keys("add_x509cert");
990 cert->next = x509certs;
991 x509certs = cert;
992 DBG(DBG_CONTROL | DBG_PARSING,
993 DBG_log(" x509 cert inserted")
994 )
995 unlock_certs_and_keys("add_x509cert");
996 return cert;
997 }
998
999 /**
1000 * Choose either subject DN or a subjectAltName as connection end ID
1001 */
1002 void select_x509cert_id(x509cert_t *cert, struct id *end_id)
1003 {
1004 bool copy_subject_dn = TRUE; /* ID is subject DN */
1005
1006 if (end_id->kind != ID_ANY) /* check for matching subjectAltName */
1007 {
1008 generalName_t *gn = cert->subjectAltName;
1009
1010 while (gn != NULL)
1011 {
1012 struct id id = empty_id;
1013
1014 gntoid(&id, gn);
1015 if (same_id(&id, end_id))
1016 {
1017 copy_subject_dn = FALSE; /* take subjectAltName instead */
1018 break;
1019 }
1020 gn = gn->next;
1021 }
1022 }
1023
1024 if (copy_subject_dn)
1025 {
1026 if (end_id->kind != ID_ANY && end_id->kind != ID_DER_ASN1_DN)
1027 {
1028 char buf[BUF_LEN];
1029
1030 idtoa(end_id, buf, BUF_LEN);
1031 plog(" no subjectAltName matches ID '%s', replaced by subject DN", buf);
1032 }
1033 end_id->kind = ID_DER_ASN1_DN;
1034 end_id->name.len = cert->subject.len;
1035 end_id->name.ptr = temporary_cyclic_buffer();
1036 memcpy(end_id->name.ptr, cert->subject.ptr, cert->subject.len);
1037 }
1038 }
1039
1040 /**
1041 * Check for equality between two key identifiers
1042 */
1043 bool same_keyid(chunk_t a, chunk_t b)
1044 {
1045 if (a.ptr == NULL || b.ptr == NULL)
1046 {
1047 return FALSE;
1048 }
1049 return chunk_equals(a, b);
1050 }
1051
1052 /**
1053 * Check for equality between two serial numbers
1054 */
1055 bool same_serial(chunk_t a, chunk_t b)
1056 {
1057 /* do not compare serial numbers if one of them is not defined */
1058 if (a.ptr == NULL || b.ptr == NULL)
1059 {
1060 return TRUE;
1061 }
1062 return chunk_equals(a, b);
1063 }
1064
1065 /**
1066 * Get a X.509 certificate with a given issuer found at a certain position
1067 */
1068 x509cert_t* get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid,
1069 x509cert_t *chain)
1070 {
1071 x509cert_t *cert = (chain != NULL)? chain->next : x509certs;
1072
1073 while (cert != NULL)
1074 {
1075 if ((keyid.ptr != NULL) ? same_keyid(keyid, cert->authKeyID)
1076 : (same_dn(issuer, cert->issuer)
1077 && same_serial(serial, cert->authKeySerialNumber)))
1078 {
1079 return cert;
1080 }
1081 cert = cert->next;
1082 }
1083 return NULL;
1084 }
1085
1086 /**
1087 * Encode a linked list of subjectAltNames
1088 */
1089 chunk_t build_subjectAltNames(generalName_t *subjectAltNames)
1090 {
1091 u_char *pos;
1092 chunk_t names;
1093 size_t len = 0;
1094 generalName_t *gn = subjectAltNames;
1095
1096 /* compute the total size of the ASN.1 attributes object */
1097 while (gn != NULL)
1098 {
1099 len += gn->name.len;
1100 gn = gn->next;
1101 }
1102
1103 pos = asn1_build_object(&names, ASN1_SEQUENCE, len);
1104
1105 gn = subjectAltNames;
1106 while (gn != NULL)
1107 {
1108 chunkcpy(pos, gn->name);
1109 gn = gn->next;
1110 }
1111
1112 return asn1_wrap(ASN1_SEQUENCE, "cm"
1113 , ASN1_subjectAltName_oid
1114 , asn1_wrap(ASN1_OCTET_STRING, "m", names));
1115 }
1116
1117 /**
1118 * Build a to-be-signed X.509 certificate body
1119 */
1120 static chunk_t build_tbs_x509cert(x509cert_t *cert, public_key_t *rsa)
1121 {
1122 /* version is always X.509v3 */
1123 chunk_t version = asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2);
1124 chunk_t key = chunk_empty;
1125 chunk_t extensions = chunk_empty;
1126
1127 rsa->get_encoding(rsa, KEY_PUB_ASN1_DER, &key);
1128
1129 chunk_t keyInfo = asn1_wrap(ASN1_SEQUENCE, "mm",
1130 asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
1131 asn1_bitstring("m", key));
1132
1133 if (cert->subjectAltName != NULL)
1134 {
1135 extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m"
1136 , asn1_wrap(ASN1_SEQUENCE, "m"
1137 , build_subjectAltNames(cert->subjectAltName)));
1138 }
1139
1140 return asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm"
1141 , version
1142 , asn1_integer("c", cert->serialNumber)
1143 , asn1_algorithmIdentifier(cert->sigAlg)
1144 , cert->issuer
1145 , asn1_wrap(ASN1_SEQUENCE, "mm"
1146 , asn1_from_time(&cert->notBefore, ASN1_UTCTIME)
1147 , asn1_from_time(&cert->notAfter, ASN1_UTCTIME)
1148 )
1149 , cert->subject
1150 , keyInfo
1151 , extensions
1152 );
1153 }
1154
1155 /**
1156 * Build a DER-encoded X.509 certificate
1157 */
1158 void build_x509cert(x509cert_t *cert, public_key_t *cert_key,
1159 private_key_t *signer_key)
1160 {
1161 chunk_t tbs_cert = build_tbs_x509cert(cert, cert_key);
1162
1163 chunk_t signature = x509_build_signature(tbs_cert, cert->sigAlg
1164 , signer_key, TRUE);
1165
1166 cert->certificate = asn1_wrap(ASN1_SEQUENCE, "mmm"
1167 , tbs_cert
1168 , asn1_algorithmIdentifier(cert->sigAlg)
1169 , signature);
1170 }
1171
1172 /**
1173 * Free the dynamic memory used to store generalNames
1174 */
1175 void free_generalNames(generalName_t* gn, bool free_name)
1176 {
1177 while (gn != NULL)
1178 {
1179 generalName_t *gn_top = gn;
1180 if (free_name)
1181 {
1182 free(gn->name.ptr);
1183 }
1184 gn = gn->next;
1185 free(gn_top);
1186 }
1187 }
1188
1189 /**
1190 * Free a X.509 certificate
1191 */
1192 void free_x509cert(x509cert_t *cert)
1193 {
1194 if (cert != NULL)
1195 {
1196 DESTROY_IF(cert->public_key);
1197 free_generalNames(cert->subjectAltName, FALSE);
1198 free_generalNames(cert->crlDistributionPoints, FALSE);
1199 free(cert->certificate.ptr);
1200 free(cert);
1201 cert = NULL;
1202 }
1203 }
1204
1205 /**
1206 * Release of a certificate decreases the count by one
1207 * the certificate is freed when the counter reaches zero
1208 */
1209 void release_x509cert(x509cert_t *cert)
1210 {
1211 if (cert != NULL && --cert->count == 0)
1212 {
1213 x509cert_t **pp = &x509certs;
1214 while (*pp != cert)
1215 {
1216 pp = &(*pp)->next;
1217 }
1218 *pp = cert->next;
1219 free_x509cert(cert);
1220 }
1221 }
1222
1223 /**
1224 * Stores a chained list of end certs and CA certs
1225 */
1226 void store_x509certs(x509cert_t **firstcert, bool strict)
1227 {
1228 x509cert_t *cacerts = NULL;
1229 x509cert_t **pp = firstcert;
1230
1231 /* first extract CA certs, discarding root CA certs */
1232
1233 while (*pp != NULL)
1234 {
1235 x509cert_t *cert = *pp;
1236
1237 if (cert->isCA)
1238 {
1239 *pp = cert->next;
1240
1241 /* we don't accept self-signed CA certs */
1242 if (same_dn(cert->issuer, cert->subject))
1243 {
1244 plog("self-signed cacert rejected");
1245 free_x509cert(cert);
1246 }
1247 else
1248 {
1249 /* insertion into temporary chain of candidate CA certs */
1250 cert->next = cacerts;
1251 cacerts = cert;
1252 }
1253 }
1254 else
1255 {
1256 pp = &cert->next;
1257 }
1258 }
1259
1260 /* now verify the candidate CA certs */
1261
1262 while (cacerts != NULL)
1263 {
1264 x509cert_t *cert = cacerts;
1265
1266 cacerts = cacerts->next;
1267
1268 if (trust_authcert_candidate(cert, cacerts))
1269 {
1270 add_authcert(cert, AUTH_CA);
1271 }
1272 else
1273 {
1274 plog("intermediate cacert rejected");
1275 free_x509cert(cert);
1276 }
1277 }
1278
1279 /* now verify the end certificates */
1280
1281 pp = firstcert;
1282
1283 while (*pp != NULL)
1284 {
1285 time_t valid_until;
1286 x509cert_t *cert = *pp;
1287
1288 if (verify_x509cert(cert, strict, &valid_until))
1289 {
1290 DBG(DBG_CONTROL | DBG_PARSING,
1291 DBG_log("public key validated")
1292 )
1293 add_x509_public_key(cert, valid_until, DAL_SIGNED);
1294 }
1295 else
1296 {
1297 plog("X.509 certificate rejected");
1298 }
1299 *pp = cert->next;
1300 free_x509cert(cert);
1301 }
1302 }
1303
1304 /**
1305 * Check if a signature over binary blob is genuine
1306 */
1307 bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm,
1308 const x509cert_t *issuer_cert)
1309 {
1310 public_key_t *key = issuer_cert->public_key;
1311 signature_scheme_t scheme = signature_scheme_from_oid(algorithm);
1312
1313 if (scheme == SIGN_UNKNOWN)
1314 {
1315 return FALSE;
1316 }
1317 return key->verify(key, scheme, tbs, sig);
1318 }
1319
1320 /**
1321 * Build an ASN.1 encoded PKCS#1 signature over a binary blob
1322 */
1323 chunk_t x509_build_signature(chunk_t tbs, int algorithm, private_key_t *key,
1324 bool bit_string)
1325 {
1326 chunk_t signature;
1327 signature_scheme_t scheme = signature_scheme_from_oid(algorithm);
1328
1329 if (scheme == SIGN_UNKNOWN || !key->sign(key, scheme, tbs, &signature))
1330 {
1331 return chunk_empty;
1332 }
1333 return (bit_string) ? asn1_bitstring("m", signature)
1334 : asn1_wrap(ASN1_OCTET_STRING, "m", signature);
1335 }
1336
1337 /**
1338 * Extracts the basicConstraints extension
1339 */
1340 static bool parse_basicConstraints(chunk_t blob, int level0)
1341 {
1342 asn1_parser_t *parser;
1343 chunk_t object;
1344 int objectID;
1345 bool isCA = FALSE;
1346
1347 parser = asn1_parser_create(basicConstraintsObjects, blob);
1348 parser->set_top_level(parser, level0);
1349
1350 while (parser->iterate(parser, &objectID, &object))
1351 {
1352 if (objectID == BASIC_CONSTRAINTS_CA)
1353 {
1354 isCA = object.len && *object.ptr;
1355 DBG(DBG_PARSING,
1356 DBG_log(" %s",(isCA)?"TRUE":"FALSE");
1357 )
1358 }
1359 }
1360 parser->destroy(parser);
1361
1362 return isCA;
1363 }
1364
1365 /**
1366 * Converts a X.500 generalName into an ID
1367 */
1368 void gntoid(struct id *id, const generalName_t *gn)
1369 {
1370 switch(gn->kind)
1371 {
1372 case GN_DNS_NAME: /* ID type: ID_FQDN */
1373 id->kind = ID_FQDN;
1374 id->name = gn->name;
1375 break;
1376 case GN_IP_ADDRESS: /* ID type: ID_IPV4_ADDR */
1377 {
1378 const struct af_info *afi = &af_inet4_info;
1379 err_t ugh = NULL;
1380
1381 id->kind = afi->id_addr;
1382 ugh = initaddr(gn->name.ptr, gn->name.len, afi->af, &id->ip_addr);
1383 }
1384 break;
1385 case GN_RFC822_NAME: /* ID type: ID_USER_FQDN */
1386 id->kind = ID_USER_FQDN;
1387 id->name = gn->name;
1388 break;
1389 default:
1390 id->kind = ID_ANY;
1391 id->name = chunk_empty;
1392 }
1393 }
1394
1395 /**
1396 * Compute the subjectKeyIdentifier according to section 4.2.1.2 of RFC 3280
1397 * as the 160 bit SHA-1 hash of the public key
1398 */
1399 bool compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID)
1400 {
1401 chunk_t fingerprint;
1402
1403 if (!cert->public_key->get_fingerprint(cert->public_key, KEY_ID_PUBKEY_SHA1,
1404 &fingerprint))
1405 {
1406 plog(" unable to compute subjectKeyID");
1407 return FALSE;
1408 }
1409 memcpy(subjectKeyID.ptr, fingerprint.ptr, subjectKeyID.len);
1410 return TRUE;
1411 }
1412
1413 /**
1414 * Extracts an otherName
1415 */
1416 static bool parse_otherName(chunk_t blob, int level0)
1417 {
1418 asn1_parser_t *parser;
1419 chunk_t object;
1420 int objectID;
1421 int oid = OID_UNKNOWN;
1422 bool success = FALSE;
1423
1424 parser = asn1_parser_create(otherNameObjects, blob);
1425 parser->set_top_level(parser, level0);
1426
1427 while (parser->iterate(parser, &objectID, &object))
1428 {
1429 switch (objectID)
1430 {
1431 case ON_OBJ_ID_TYPE:
1432 oid = asn1_known_oid(object);
1433 break;
1434 case ON_OBJ_VALUE:
1435 if (oid == OID_XMPP_ADDR)
1436 {
1437 if (!asn1_parse_simple_object(&object, ASN1_UTF8STRING,
1438 parser->get_level(parser) + 1, "xmppAddr"))
1439 {
1440 goto end;
1441 }
1442 }
1443 break;
1444 default:
1445 break;
1446 }
1447 }
1448 success = parser->success(parser);
1449
1450 end:
1451 parser->destroy(parser);
1452 return success;
1453 }
1454
1455
1456 /**
1457 * Extracts a generalName
1458 */
1459 static generalName_t* parse_generalName(chunk_t blob, int level0)
1460 {
1461 u_char buf[BUF_LEN];
1462 asn1_parser_t *parser;
1463 chunk_t object;
1464 generalName_t *gn = NULL;
1465 int objectID;
1466
1467 parser = asn1_parser_create(generalNameObjects, blob);
1468 parser->set_top_level(parser, level0);
1469
1470 while (parser->iterate(parser, &objectID, &object))
1471 {
1472 bool valid_gn = FALSE;
1473
1474 switch (objectID) {
1475 case GN_OBJ_RFC822_NAME:
1476 case GN_OBJ_DNS_NAME:
1477 case GN_OBJ_URI:
1478 DBG(DBG_PARSING,
1479 DBG_log(" '%.*s'", (int)object.len, object.ptr);
1480 )
1481 valid_gn = TRUE;
1482 break;
1483 case GN_OBJ_DIRECTORY_NAME:
1484 DBG(DBG_PARSING,
1485 dntoa(buf, BUF_LEN, object);
1486 DBG_log(" '%s'", buf)
1487 )
1488 valid_gn = TRUE;
1489 break;
1490 case GN_OBJ_IP_ADDRESS:
1491 DBG(DBG_PARSING,
1492 DBG_log(" '%d.%d.%d.%d'", *object.ptr, *(object.ptr+1),
1493 *(object.ptr+2), *(object.ptr+3));
1494 )
1495 valid_gn = TRUE;
1496 break;
1497 case GN_OBJ_OTHER_NAME:
1498 if (!parse_otherName(object, parser->get_level(parser)+1))
1499 {
1500 goto end;
1501 }
1502 break;
1503 case GN_OBJ_X400_ADDRESS:
1504 case GN_OBJ_EDI_PARTY_NAME:
1505 case GN_OBJ_REGISTERED_ID:
1506 break;
1507 default:
1508 break;
1509 }
1510
1511 if (valid_gn)
1512 {
1513 gn = malloc_thing(generalName_t);
1514 gn->kind = (objectID - GN_OBJ_OTHER_NAME) / 2;
1515 gn->name = object;
1516 gn->next = NULL;
1517 goto end;
1518 }
1519 }
1520
1521 end:
1522 parser->destroy(parser);
1523 return gn;
1524 }
1525
1526 /**
1527 * Extracts one or several GNs and puts them into a chained list
1528 */
1529 static generalName_t* parse_generalNames(chunk_t blob, int level0, bool implicit)
1530 {
1531 asn1_parser_t *parser;
1532 chunk_t object;
1533 int objectID;
1534 generalName_t *top_gn = NULL;
1535
1536 parser = asn1_parser_create(generalNamesObjects, blob);
1537 parser->set_top_level(parser, level0);
1538 parser->set_flags(parser, implicit, FALSE);
1539
1540 while (parser->iterate(parser, &objectID, &object))
1541 {
1542 if (objectID == GENERAL_NAMES_GN)
1543 {
1544 generalName_t *gn = parse_generalName(object,
1545 parser->get_level(parser)+1);
1546 if (gn)
1547 {
1548 gn->next = top_gn;
1549 top_gn = gn;
1550 }
1551 }
1552 }
1553 parser->destroy(parser);
1554
1555 return top_gn;
1556 }
1557
1558 /**
1559 * Returns a directoryName
1560 */
1561 chunk_t get_directoryName(chunk_t blob, int level, bool implicit)
1562 {
1563 chunk_t name = chunk_empty;
1564 generalName_t * gn = parse_generalNames(blob, level, implicit);
1565
1566 if (gn != NULL && gn->kind == GN_DIRECTORY_NAME)
1567 {
1568 name= gn->name;
1569 }
1570 free_generalNames(gn, FALSE);
1571 return name;
1572 }
1573
1574 /**
1575 * Extracts an authoritykeyIdentifier
1576 */
1577 void parse_authorityKeyIdentifier(chunk_t blob, int level0,
1578 chunk_t *authKeyID,
1579 chunk_t *authKeySerialNumber)
1580 {
1581 asn1_parser_t *parser;
1582 chunk_t object;
1583 int objectID;
1584
1585 parser = asn1_parser_create(authKeyIdentifierObjects, blob);
1586 parser->set_top_level(parser, level0);
1587
1588 while (parser->iterate(parser, &objectID, &object))
1589 {
1590 switch (objectID)
1591 {
1592 case AUTH_KEY_ID_KEY_ID:
1593 *authKeyID = object;
1594 break;
1595 case AUTH_KEY_ID_CERT_ISSUER:
1596 {
1597 generalName_t * gn = parse_generalNames(object,
1598 parser->get_level(parser) + 1, TRUE);
1599
1600 free_generalNames(gn, FALSE);
1601 }
1602 break;
1603 case AUTH_KEY_ID_CERT_SERIAL:
1604 *authKeySerialNumber = object;
1605 break;
1606 default:
1607 break;
1608 }
1609 }
1610 parser->destroy(parser);
1611 }
1612
1613 /**
1614 * Extracts an authorityInfoAcess location
1615 */
1616 static void parse_authorityInfoAccess(chunk_t blob, int level0,
1617 chunk_t *accessLocation)
1618 {
1619 asn1_parser_t *parser;
1620 chunk_t object;
1621 int objectID;
1622 int accessMethod = OID_UNKNOWN;
1623
1624 parser = asn1_parser_create(authInfoAccessObjects, blob);
1625 parser->set_top_level(parser, level0);
1626
1627 while (parser->iterate(parser, &objectID, &object))
1628 {
1629 switch (objectID)
1630 {
1631 case AUTH_INFO_ACCESS_METHOD:
1632 accessMethod = asn1_known_oid(object);
1633 break;
1634 case AUTH_INFO_ACCESS_LOCATION:
1635 {
1636 switch (accessMethod)
1637 {
1638 case OID_OCSP:
1639 if (*object.ptr == ASN1_CONTEXT_S_6)
1640 {
1641 if (asn1_length(&object) == ASN1_INVALID_LENGTH)
1642 {
1643 goto end;
1644 }
1645 DBG(DBG_PARSING,
1646 DBG_log(" '%.*s'",(int)object.len, object.ptr)
1647 )
1648
1649 /* only HTTP(S) URIs accepted */
1650 if (strncasecmp(object.ptr, "http", 4) == 0)
1651 {
1652 *accessLocation = object;
1653 goto end;
1654 }
1655 }
1656 plog("warning: ignoring OCSP InfoAccessLocation with unkown protocol");
1657 break;
1658 default:
1659 /* unkown accessMethod, ignoring */
1660 break;
1661 }
1662 }
1663 break;
1664 default:
1665 break;
1666 }
1667 }
1668
1669 end:
1670 parser->destroy(parser);
1671 }
1672
1673 /**
1674 * Extracts extendedKeyUsage OIDs
1675 */
1676 static bool parse_extendedKeyUsage(chunk_t blob, int level0)
1677 {
1678 asn1_parser_t *parser;
1679 chunk_t object;
1680 int objectID;
1681 bool ocsp_signing = FALSE;
1682
1683 parser = asn1_parser_create(extendedKeyUsageObjects, blob);
1684 parser->set_top_level(parser, level0);
1685
1686 while (parser->iterate(parser, &objectID, &object))
1687 {
1688 if (objectID == EXT_KEY_USAGE_PURPOSE_ID
1689 && asn1_known_oid(object) == OID_OCSP_SIGNING)
1690 {
1691 ocsp_signing = TRUE;
1692 }
1693 }
1694 parser->destroy(parser);
1695
1696 return ocsp_signing;
1697 }
1698
1699 /**
1700 * Extracts one or several crlDistributionPoints
1701 * and puts them into a chained list
1702 */
1703 static generalName_t* parse_crlDistributionPoints(chunk_t blob, int level0)
1704 {
1705 asn1_parser_t *parser;
1706 chunk_t object;
1707 int objectID;
1708
1709 generalName_t *top_gn = NULL; /* top of the chained list */
1710 generalName_t **tail_gn = &top_gn; /* tail of the chained list */
1711
1712 parser = asn1_parser_create(crlDistributionPointsObjects, blob);
1713 parser->set_top_level(parser, level0);
1714
1715 while (parser->iterate(parser, &objectID, &object))
1716 {
1717 if (objectID == CRL_DIST_POINTS_FULLNAME)
1718 {
1719 generalName_t *gn;
1720
1721 gn = parse_generalNames(object, parser->get_level(parser)+1, TRUE);
1722 /* append extracted generalNames to existing chained list */
1723 *tail_gn = gn;
1724 /* find new tail of the chained list */
1725 while (gn != NULL)
1726 {
1727 tail_gn = &gn->next; gn = gn->next;
1728 }
1729 }
1730 }
1731 parser->destroy(parser);
1732
1733 return top_gn;
1734 }
1735
1736 /**
1737 * Parses an X.509v3 certificate
1738 */
1739 bool parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
1740 {
1741 u_char buf[BUF_LEN];
1742 asn1_parser_t *parser;
1743 chunk_t object;
1744 int objectID;
1745 int extn_oid = OID_UNKNOWN;
1746 bool critical;
1747 bool success = FALSE;
1748
1749 parser = asn1_parser_create(certObjects, blob);
1750 parser->set_top_level(parser, level0);
1751
1752 while (parser->iterate(parser, &objectID, &object))
1753 {
1754 u_int level = parser->get_level(parser) + 1;
1755
1756 switch (objectID) {
1757 case X509_OBJ_CERTIFICATE:
1758 cert->certificate = object;
1759 break;
1760 case X509_OBJ_TBS_CERTIFICATE:
1761 cert->tbsCertificate = object;
1762 break;
1763 case X509_OBJ_VERSION:
1764 cert->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
1765 DBG(DBG_PARSING,
1766 DBG_log(" v%d", cert->version);
1767 )
1768 break;
1769 case X509_OBJ_SERIAL_NUMBER:
1770 cert->serialNumber = object;
1771 break;
1772 case X509_OBJ_SIG_ALG:
1773 cert->sigAlg = asn1_parse_algorithmIdentifier(object, level, NULL);
1774 break;
1775 case X509_OBJ_ISSUER:
1776 cert->issuer = object;
1777 DBG(DBG_PARSING,
1778 dntoa(buf, BUF_LEN, object);
1779 DBG_log(" '%s'",buf)
1780 )
1781 break;
1782 case X509_OBJ_NOT_BEFORE:
1783 cert->notBefore = asn1_parse_time(object, level);
1784 break;
1785 case X509_OBJ_NOT_AFTER:
1786 cert->notAfter = asn1_parse_time(object, level);
1787 break;
1788 case X509_OBJ_SUBJECT:
1789 cert->subject = object;
1790 DBG(DBG_PARSING,
1791 dntoa(buf, BUF_LEN, object);
1792 DBG_log(" '%s'",buf)
1793 )
1794 break;
1795 case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO:
1796 cert->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
1797 KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
1798 if (cert->public_key == NULL)
1799 {
1800 goto end;
1801 }
1802 break;
1803 case X509_OBJ_EXTN_ID:
1804 extn_oid = asn1_known_oid(object);
1805 break;
1806 case X509_OBJ_CRITICAL:
1807 critical = object.len && *object.ptr;
1808 DBG(DBG_PARSING,
1809 DBG_log(" %s",(critical)?"TRUE":"FALSE");
1810 )
1811 break;
1812 case X509_OBJ_EXTN_VALUE:
1813 {
1814 switch (extn_oid) {
1815 case OID_SUBJECT_KEY_ID:
1816 if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
1817 level, "keyIdentifier"))
1818 {
1819 goto end;
1820 }
1821 cert->subjectKeyID = object;
1822 break;
1823 case OID_SUBJECT_ALT_NAME:
1824 cert->subjectAltName =
1825 parse_generalNames(object, level, FALSE);
1826 break;
1827 case OID_BASIC_CONSTRAINTS:
1828 cert->isCA =
1829 parse_basicConstraints(object, level);
1830 break;
1831 case OID_CRL_DISTRIBUTION_POINTS:
1832 cert->crlDistributionPoints =
1833 parse_crlDistributionPoints(object, level);
1834 break;
1835 case OID_AUTHORITY_KEY_ID:
1836 parse_authorityKeyIdentifier(object, level
1837 , &cert->authKeyID, &cert->authKeySerialNumber);
1838 break;
1839 case OID_AUTHORITY_INFO_ACCESS:
1840 parse_authorityInfoAccess(object, level, &cert->accessLocation);
1841 break;
1842 case OID_EXTENDED_KEY_USAGE:
1843 cert->isOcspSigner = parse_extendedKeyUsage(object, level);
1844 break;
1845 case OID_NS_REVOCATION_URL:
1846 case OID_NS_CA_REVOCATION_URL:
1847 case OID_NS_CA_POLICY_URL:
1848 case OID_NS_COMMENT:
1849 if (!asn1_parse_simple_object(&object, ASN1_IA5STRING
1850 , level, oid_names[extn_oid].name))
1851 {
1852 goto end;
1853 }
1854 break;
1855 default:
1856 break;
1857 }
1858 }
1859 break;
1860 case X509_OBJ_ALGORITHM:
1861 cert->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
1862 break;
1863 case X509_OBJ_SIGNATURE:
1864 cert->signature = object;
1865 break;
1866 default:
1867 break;
1868 }
1869 }
1870 success = parser->success(parser);
1871 time(&cert->installed);
1872
1873 end:
1874 parser->destroy(parser);
1875 return success;
1876 }
1877
1878 /**
1879 * Verify the validity of a certificate by
1880 * checking the notBefore and notAfter dates
1881 */
1882 err_t check_validity(const x509cert_t *cert, time_t *until)
1883 {
1884 time_t current_time;
1885
1886 time(&current_time);
1887 DBG(DBG_CONTROL | DBG_PARSING ,
1888 DBG_log(" not before : %T", &cert->notBefore, TRUE);
1889 DBG_log(" current time: %T", &current_time, TRUE);
1890 DBG_log(" not after : %T", &cert->notAfter, TRUE);
1891 )
1892
1893 if (cert->notAfter < *until)
1894 {
1895 *until = cert->notAfter;
1896 }
1897 if (current_time < cert->notBefore)
1898 {
1899 return "certificate is not valid yet";
1900 }
1901 if (current_time > cert->notAfter)
1902 {
1903 return "certificate has expired";
1904 }
1905 else
1906 {
1907 return NULL;
1908 }
1909 }
1910
1911 /**
1912 * Verifies a X.509 certificate
1913 */
1914 bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
1915 {
1916 int pathlen;
1917
1918 *until = cert->notAfter;
1919
1920 for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
1921 {
1922 x509cert_t *issuer_cert;
1923 u_char buf[BUF_LEN];
1924 err_t ugh = NULL;
1925
1926 DBG(DBG_CONTROL,
1927 dntoa(buf, BUF_LEN, cert->subject);
1928 DBG_log("subject: '%s'",buf);
1929 dntoa(buf, BUF_LEN, cert->issuer);
1930 DBG_log("issuer: '%s'",buf);
1931 if (cert->authKeyID.ptr != NULL)
1932 {
1933 datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
1934 , buf, BUF_LEN);
1935 DBG_log("authkey: %s", buf);
1936 }
1937 )
1938
1939 ugh = check_validity(cert, until);
1940
1941 if (ugh != NULL)
1942 {
1943 plog("%s", ugh);
1944 return FALSE;
1945 }
1946
1947 DBG(DBG_CONTROL,
1948 DBG_log("certificate is valid")
1949 )
1950
1951 lock_authcert_list("verify_x509cert");
1952 issuer_cert = get_authcert(cert->issuer, cert->authKeySerialNumber
1953 , cert->authKeyID, AUTH_CA);
1954
1955 if (issuer_cert == NULL)
1956 {
1957 plog("issuer cacert not found");
1958 unlock_authcert_list("verify_x509cert");
1959 return FALSE;
1960 }
1961 DBG(DBG_CONTROL,
1962 DBG_log("issuer cacert found")
1963 )
1964
1965 if (!x509_check_signature(cert->tbsCertificate, cert->signature,
1966 cert->algorithm, issuer_cert))
1967 {
1968 plog("certificate signature is invalid");
1969 unlock_authcert_list("verify_x509cert");
1970 return FALSE;
1971 }
1972 DBG(DBG_CONTROL,
1973 DBG_log("certificate signature is valid")
1974 )
1975 unlock_authcert_list("verify_x509cert");
1976
1977 /* check if cert is a self-signed root ca */
1978 if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
1979 {
1980 DBG(DBG_CONTROL,
1981 DBG_log("reached self-signed root ca")
1982 )
1983 return TRUE;
1984 }
1985 else
1986 {
1987 time_t nextUpdate = *until;
1988 time_t revocationDate = UNDEFINED_TIME;
1989 crl_reason_t revocationReason = CRL_REASON_UNSPECIFIED;
1990
1991 /* first check certificate revocation using ocsp */
1992 cert_status_t status = verify_by_ocsp(cert, &nextUpdate
1993 , &revocationDate, &revocationReason);
1994
1995 /* if ocsp service is not available then fall back to crl */
1996 if ((status == CERT_UNDEFINED)
1997 || (status == CERT_UNKNOWN && strict))
1998 {
1999 status = verify_by_crl(cert, &nextUpdate, &revocationDate
2000 , &revocationReason);
2001 }
2002
2003 switch (status)
2004 {
2005 case CERT_GOOD:
2006 /* if status information is stale */
2007 if (strict && nextUpdate < time(NULL))
2008 {
2009 DBG(DBG_CONTROL,
2010 DBG_log("certificate is good but status is stale")
2011 )
2012 remove_x509_public_key(cert);
2013 return FALSE;
2014 }
2015 DBG(DBG_CONTROL,
2016 DBG_log("certificate is good")
2017 )
2018
2019 /* with strict crl policy the public key must have the same
2020 * lifetime as the validity of the ocsp status or crl lifetime
2021 */
2022 if (strict && nextUpdate < *until)
2023 {
2024 *until = nextUpdate;
2025 }
2026 break;
2027 case CERT_REVOKED:
2028 plog("certificate was revoked on %T, reason: %N"
2029 , &revocationDate, TRUE
2030 , crl_reason_names, revocationReason);
2031 remove_x509_public_key(cert);
2032 return FALSE;
2033 case CERT_UNKNOWN:
2034 case CERT_UNDEFINED:
2035 default:
2036 plog("certificate status unknown");
2037 if (strict)
2038 {
2039 remove_x509_public_key(cert);
2040 return FALSE;
2041 }
2042 break;
2043 }
2044 }
2045
2046 /* go up one step in the trust chain */
2047 cert = issuer_cert;
2048 }
2049 plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
2050 return FALSE;
2051 }
2052
2053 /**
2054 * List all X.509 certs in a chained list
2055 */
2056 void list_x509cert_chain(const char *caption, x509cert_t* cert,
2057 u_char auth_flags, bool utc)
2058 {
2059 bool first = TRUE;
2060 time_t now;
2061
2062 /* determine the current time */
2063 time(&now);
2064
2065 while (cert != NULL)
2066 {
2067 if (auth_flags == AUTH_NONE || (auth_flags & cert->authority_flags))
2068 {
2069 u_char buf[BUF_LEN];
2070 public_key_t *key = cert->public_key;
2071 chunk_t keyid;
2072 cert_t c;
2073
2074 c.type = CERT_X509_SIGNATURE;
2075 c.u.x509 = cert;
2076
2077 if (first)
2078 {
2079 whack_log(RC_COMMENT, " ");
2080 whack_log(RC_COMMENT, "List of X.509 %s Certificates:", caption);
2081 whack_log(RC_COMMENT, " ");
2082 first = FALSE;
2083 }
2084
2085 whack_log(RC_COMMENT, "%T, count: %d", &cert->installed, utc,
2086 cert->count);
2087 dntoa(buf, BUF_LEN, cert->subject);
2088 whack_log(RC_COMMENT, " subject: '%s'", buf);
2089 dntoa(buf, BUF_LEN, cert->issuer);
2090 whack_log(RC_COMMENT, " issuer: '%s'", buf);
2091 datatot(cert->serialNumber.ptr, cert->serialNumber.len, ':',
2092 buf, BUF_LEN);
2093 whack_log(RC_COMMENT, " serial: %s", buf);
2094 whack_log(RC_COMMENT, " validity: not before %T %s",
2095 &cert->notBefore, utc,
2096 (cert->notBefore < now)?"ok":"fatal (not valid yet)");
2097 whack_log(RC_COMMENT, " not after %T %s",
2098 &cert->notAfter, utc,
2099 check_expiry(cert->notAfter, CA_CERT_WARNING_INTERVAL, TRUE));
2100 whack_log(RC_COMMENT, " pubkey: %N %4d bits%s",
2101 key_type_names, key->get_type(key),
2102 key->get_keysize(key) * BITS_PER_BYTE,
2103 cert->smartcard ? ", on smartcard" :
2104 (has_private_key(c)? ", has private key" : ""));
2105 if (key->get_fingerprint(key, KEY_ID_PUBKEY_INFO_SHA1, &keyid))
2106 {
2107 whack_log(RC_COMMENT, " keyid: %#B", &keyid);
2108 }
2109 if (cert->subjectKeyID.ptr != NULL)
2110 {
2111 datatot(cert->subjectKeyID.ptr, cert->subjectKeyID.len, ':',
2112 buf, BUF_LEN);
2113 whack_log(RC_COMMENT, " subjkey: %s", buf);
2114 }
2115 if (cert->authKeyID.ptr != NULL)
2116 {
2117 datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':',
2118 buf, BUF_LEN);
2119 whack_log(RC_COMMENT, " authkey: %s", buf);
2120 }
2121 if (cert->authKeySerialNumber.ptr != NULL)
2122 {
2123 datatot(cert->authKeySerialNumber.ptr,
2124 cert->authKeySerialNumber.len, ':', buf, BUF_LEN);
2125 whack_log(RC_COMMENT, " aserial: %s", buf);
2126 }
2127 }
2128 cert = cert->next;
2129 }
2130 }
2131
2132 /**
2133 * List all X.509 end certificates in a chained list
2134 */
2135 void list_x509_end_certs(bool utc)
2136 {
2137 list_x509cert_chain("End", x509certs, AUTH_NONE, utc);
2138 }