OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / pluto / x509.c
1 /* Support of X.509 certificates and CRLs
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-2002 Andreas Steffen, Zuercher Hochschule Winterthur
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  * RCSID $Id: x509.c,v 1.16 2005-06-08 05:06:38 matthewn Exp $
18  */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <dirent.h>
25 #include <time.h>
26 #include <sys/types.h>
27
28 #include <freeswan.h>
29
30 #include "constants.h"
31 #include "defs.h"
32 #include "log.h"
33 #include "id.h"
34 #include "asn1.h"
35 #include "x509.h"
36 #include "preshared.h"
37 #include "md2.h"
38 #include "md5.h"
39 #include "sha1.h"
40 #include "whack.h"
41
42 /* path definitions for cacerts and crls */
43
44 #include <config/autoconf.h>
45
46 #ifdef CONFIG_USER_FLATFSD_FLATFSD
47 #define __IPSEC__PREFIX__ "/etc/config"
48 #else
49 #define __IPSEC__PREFIX__ "/etc"
50 #endif
51
52 #define X509_CERT_PATH  __IPSEC__PREFIX__ "/"
53 #define PGP_CERT_PATH   __IPSEC__PREFIX__ "/pgpcert.pgp"
54 #define CA_CERT_PATH    __IPSEC__PREFIX__
55 #define CRL_PATH        __IPSEC__PREFIX__
56
57 /* chained lists of host/user and ca certificates and crls */
58
59 static x509cert_t *x509certs   = NULL;
60 static x509cert_t *x509cacerts = NULL;
61 static x509crl_t  *x509crls    = NULL;
62
63 /* contains my X.509 or OpenPGP certificate
64  " not used for X.509 certs anymore, backward compatibility only
65  */
66
67 static cert_t my_default_cert;
68
69 /* ASN.1 definition of a basicConstraints extension */
70
71 static const asn1Object_t basicConstraintsObjects[] = {
72   { 0, "basicConstraints",              ASN1_SEQUENCE,     ASN1_NONE  }, /*  0 */
73   { 1,   "CA",                          ASN1_BOOLEAN,      ASN1_DEF |
74                                                            ASN1_BODY }, /*  1 */
75   { 1,   "pathLenConstraint",           ASN1_INTEGER,      ASN1_OPT |
76                                                            ASN1_BODY }, /*  2 */
77   { 1,   "end opt",                     ASN1_EOC,          ASN1_END  }, /*  3 */
78 };
79
80 #define BASIC_CONSTRAINTS_CA    1
81 #define BASIC_CONSTRAINTS_ROOF  4
82
83 /* ASN.1 definition of generalNames */
84
85 static const asn1Object_t generalNamesObjects[] = {
86   { 0, "generalNames",                  ASN1_SEQUENCE,     ASN1_LOOP }, /*  0 */
87   { 1,   "otherName",                   ASN1_CONTEXT_C_0,  ASN1_OPT |
88                                                            ASN1_BODY }, /*  1 */
89   { 1,   "end choice",                  ASN1_EOC,          ASN1_END  }, /*  2 */
90   { 1,   "rfc822Name",                  ASN1_CONTEXT_S_1,  ASN1_OPT |
91                                                            ASN1_BODY }, /*  3 */
92   { 1,   "end choice",                  ASN1_EOC,          ASN1_END  }, /*  4 */
93   { 1,   "dnsName",                     ASN1_CONTEXT_S_2,  ASN1_OPT |
94                                                            ASN1_BODY }, /*  5 */
95   { 1,   "end choice",                  ASN1_EOC,          ASN1_END  }, /*  6 */
96   { 1,   "x400Address",                 ASN1_CONTEXT_S_3,  ASN1_OPT |
97                                                            ASN1_BODY }, /*  7 */
98   { 1,   "end choice",                  ASN1_EOC,          ASN1_END  }, /*  8 */
99   { 1,   "directoryName",               ASN1_CONTEXT_C_4,  ASN1_OPT |
100                                                            ASN1_BODY }, /*  9 */
101   { 1,   "end choice",                  ASN1_EOC,          ASN1_END  }, /* 10 */
102   { 1,   "ediPartyName",                ASN1_CONTEXT_C_5,  ASN1_OPT |
103                                                            ASN1_BODY }, /* 11 */
104   { 1,   "end choice",                  ASN1_EOC,          ASN1_END  }, /* 12 */
105   { 1,   "uniformResourceIdentifier",   ASN1_CONTEXT_S_6,  ASN1_OPT |
106                                                            ASN1_BODY }, /* 13 */
107   { 1,   "end choice",                  ASN1_EOC,          ASN1_END  }, /* 14 */
108   { 1,   "ipAddress",                   ASN1_CONTEXT_S_7,  ASN1_OPT |
109                                                            ASN1_BODY }, /* 15 */
110   { 1,   "end choice",                  ASN1_EOC,          ASN1_END  }, /* 16 */
111   { 1,   "registeredID",                ASN1_CONTEXT_S_8,  ASN1_OPT |
112                                                            ASN1_BODY }, /* 17 */
113   { 1,   "end choice",                  ASN1_EOC,          ASN1_END  }, /* 18 */
114   { 0, "end loop",                      ASN1_EOC,          ASN1_END  }, /* 19 */
115 };
116
117 #define GN_OBJ_OTHER_NAME        1
118 #define GN_OBJ_RFC822_NAME       3
119 #define GN_OBJ_DNS_NAME          5
120 #define GN_OBJ_X400_ADDRESS      7
121 #define GN_OBJ_DIRECTORY_NAME    9
122 #define GN_OBJ_EDI_PARTY_NAME   11
123 #define GN_OBJ_URI              13
124 #define GN_OBJ_IP_ADDRESS       15
125 #define GN_OBJ_REGISTERED_ID    17
126 #define GN_OBJ_ROOF             20
127
128 /* ASN.1 definition of crlDistributionPoints */
129
130 static const asn1Object_t crlDistributionPointsObjects[] = {
131   { 0, "crlDistributionPoints",         ASN1_SEQUENCE,     ASN1_LOOP }, /*  0 */
132   { 1,   "DistributionPoint",           ASN1_SEQUENCE,     ASN1_NONE }, /*  1 */
133   { 2,     "distributionPoint",         ASN1_CONTEXT_C_0,  ASN1_OPT |
134                                                            ASN1_LOOP }, /*  2 */
135   { 3,       "fullName",                ASN1_CONTEXT_C_0,  ASN1_OPT |
136                                                            ASN1_OBJ  }, /*  3 */
137   { 3,       "end choice",              ASN1_EOC,          ASN1_END  }, /*  4 */
138   { 3,       "nameRelativeToCRLIssuer", ASN1_CONTEXT_C_1,  ASN1_OPT |
139                                                            ASN1_BODY }, /*  5 */
140   { 3,       "end choice",              ASN1_EOC,          ASN1_END  }, /*  6 */
141   { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /*  7 */
142   { 2,     "reasons",                   ASN1_CONTEXT_C_1,  ASN1_OPT |
143                                                            ASN1_BODY }, /*  8 */
144   { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /*  9 */
145   { 2,     "crlIssuer",                 ASN1_CONTEXT_C_2,  ASN1_OPT |
146                                                            ASN1_BODY }, /* 10 */
147   { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 11 */
148   { 0, "end loop",                      ASN1_EOC,          ASN1_END  }, /* 12 */
149 };
150
151 #define CRL_DIST_POINTS_FULLNAME         3
152 #define CRL_DIST_POINTS_ROOF            13
153
154 /* ASN.1 definition of an X.509v3 certificate */
155
156 static const asn1Object_t certObjects[] = {
157   { 0, "certificate",                   ASN1_SEQUENCE,     ASN1_OBJ  }, /*  0 */
158   { 1,   "tbsCertificate",              ASN1_SEQUENCE,     ASN1_OBJ  }, /*  1 */
159   { 2,     "DEFAULT v1",                ASN1_CONTEXT_C_0,  ASN1_DEF  }, /*  2 */
160   { 3,       "version",                 ASN1_INTEGER,      ASN1_BODY }, /*  3 */
161   { 2,     "serialNumber",              ASN1_INTEGER,      ASN1_BODY }, /*  4 */
162   { 2,     "signature",                 ASN1_SEQUENCE,     ASN1_NONE }, /*  5 */
163   { 3,       "sigAlg",                  ASN1_OID,          ASN1_BODY }, /*  6 */
164   { 2,     "issuer",                    ASN1_SEQUENCE,     ASN1_OBJ  }, /*  7 */
165   { 2,     "validity",                  ASN1_SEQUENCE,     ASN1_NONE }, /*  8 */
166   { 3,       "notBefore",               ASN1_UTCTIME,      ASN1_BODY }, /*  9 */
167   { 3,       "notAfter",                ASN1_UTCTIME,      ASN1_BODY }, /* 10 */
168   { 2,     "subject",                   ASN1_SEQUENCE,     ASN1_OBJ  }, /* 11 */
169   { 2,     "subjectPublicKeyInfo",      ASN1_SEQUENCE,     ASN1_NONE }, /* 12 */
170   { 3,       "algorithm",               ASN1_SEQUENCE,     ASN1_NONE }, /* 13 */
171   { 4,          "algorithm",            ASN1_OID,          ASN1_BODY }, /* 14 */
172   { 3,       "subjectPublicKey",        ASN1_BIT_STRING,   ASN1_NONE }, /* 15 */
173   { 4,         "RSAPublicKey",          ASN1_SEQUENCE,     ASN1_NONE }, /* 16 */
174   { 5,           "modulus",             ASN1_INTEGER,      ASN1_BODY }, /* 17 */
175   { 5,           "publicExponent",      ASN1_INTEGER,      ASN1_BODY }, /* 18 */
176   { 2,     "issuerUniqueID",            ASN1_CONTEXT_C_1,  ASN1_OPT  }, /* 19 */
177   { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 20 */
178   { 2,     "subjectUniqueID",           ASN1_CONTEXT_C_2,  ASN1_OPT  }, /* 21 */
179   { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 22 */
180   { 2,     "optional extensions",       ASN1_CONTEXT_C_3,  ASN1_OPT  }, /* 23 */
181   { 3,       "extensions",              ASN1_SEQUENCE,     ASN1_LOOP }, /* 24 */
182   { 4,         "extension",             ASN1_SEQUENCE,     ASN1_NONE }, /* 25 */
183   { 5,           "extnID",              ASN1_OID,          ASN1_BODY }, /* 26 */
184   { 5,           "critical",            ASN1_BOOLEAN,      ASN1_DEF |
185                                                            ASN1_BODY }, /* 27 */
186   { 5,           "extnValue",           ASN1_OCTET_STRING, ASN1_BODY }, /* 28 */
187   { 3,       "end loop",                ASN1_EOC,          ASN1_END  }, /* 29 */
188   { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 30 */
189   { 1,   "signatureAlgorithm",          ASN1_SEQUENCE,     ASN1_NONE }, /* 31 */
190   { 2,     "algorithm",                 ASN1_OID,          ASN1_BODY }, /* 32 */
191   { 1,   "signature",                   ASN1_BIT_STRING,   ASN1_BODY }  /* 33 */
192 };
193
194 #define X509_OBJ_CERTIFICATE                     0
195 #define X509_OBJ_TBS_CERTIFICATE                 1
196 #define X509_OBJ_VERSION                         3
197 #define X509_OBJ_SERIAL_NUMBER                   4
198 #define X509_OBJ_SIG_ALG                         6
199 #define X509_OBJ_ISSUER                          7
200 #define X509_OBJ_NOT_BEFORE                      9
201 #define X509_OBJ_NOT_AFTER                      10
202 #define X509_OBJ_SUBJECT                        11
203 #define X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM   14
204 #define X509_OBJ_SUBJECT_PUBLIC_KEY             15
205 #define X509_OBJ_MODULUS                        17
206 #define X509_OBJ_PUBLIC_EXPONENT                18
207 #define X509_OBJ_EXTN_ID                        26
208 #define X509_OBJ_CRITICAL                       27
209 #define X509_OBJ_EXTN_VALUE                     28
210 #define X509_OBJ_ALGORITHM                      32
211 #define X509_OBJ_SIGNATURE                      33
212 #define X509_OBJ_ROOF                           34
213
214
215 /* ASN.1 definition of an X.509 certificate list */
216
217 static const asn1Object_t crlObjects[] = {
218   { 0, "certificateList",               ASN1_SEQUENCE,     ASN1_OBJ  }, /*  0 */
219   { 1,   "tbsCertList",                 ASN1_SEQUENCE,     ASN1_OBJ  }, /*  1 */
220   { 2,     "version",                   ASN1_INTEGER,      ASN1_OPT |
221                                                            ASN1_BODY }, /*  2 */
222   { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /*  3 */
223   { 2,     "signature",                 ASN1_SEQUENCE,     ASN1_NONE }, /*  4 */
224   { 3,       "sigAlg",                  ASN1_OID,          ASN1_BODY }, /*  5 */
225   { 2,     "issuer",                    ASN1_SEQUENCE,     ASN1_OBJ  }, /*  6 */
226   { 2,     "thisUpdate",                ASN1_UTCTIME,      ASN1_BODY }, /*  7 */
227   { 2,     "nextUpdate",                ASN1_UTCTIME,      ASN1_OPT |
228                                                            ASN1_BODY }, /*  8 */
229   { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /*  9 */
230   { 2,     "revokedCertificates",       ASN1_SEQUENCE,     ASN1_OPT |
231                                                            ASN1_LOOP }, /* 10 */
232   { 3,       "certList",                ASN1_SEQUENCE,     ASN1_NONE }, /* 11 */
233   { 4,         "userCertificate",       ASN1_INTEGER,      ASN1_BODY }, /* 12 */
234   { 4,         "revocationDate",        ASN1_UTCTIME,      ASN1_BODY }, /* 13 */
235   { 4,         "crlEntryExtensions",    ASN1_SEQUENCE,     ASN1_OPT |
236                                                            ASN1_LOOP }, /* 14 */
237   { 5,           "extension",           ASN1_SEQUENCE,     ASN1_NONE }, /* 15 */
238   { 6,             "extnID",            ASN1_OID,          ASN1_BODY }, /* 16 */
239   { 6,             "critical",          ASN1_BOOLEAN,      ASN1_DEF |
240                                                            ASN1_BODY }, /* 17 */
241   { 6,             "extnValue",         ASN1_OCTET_STRING, ASN1_BODY }, /* 18 */
242   { 4,         "end opt or loop",       ASN1_EOC,          ASN1_END  }, /* 19 */
243   { 2,     "end opt or loop",           ASN1_EOC,          ASN1_END  }, /* 20 */
244   { 2,     "optional extensions",       ASN1_CONTEXT_C_0,  ASN1_OPT  }, /* 21 */
245   { 3,       "crlExtensions",           ASN1_SEQUENCE,     ASN1_LOOP }, /* 22 */
246   { 4,         "extension",             ASN1_SEQUENCE,     ASN1_NONE }, /* 23 */
247   { 5,           "extnID",              ASN1_OID,          ASN1_BODY }, /* 24 */
248   { 5,           "critical",            ASN1_BOOLEAN,      ASN1_DEF |
249                                                            ASN1_BODY }, /* 25 */
250   { 3,       "end loop",                ASN1_EOC,          ASN1_END  }, /* 26 */
251   { 2,     "end opt",                   ASN1_EOC,          ASN1_END  }, /* 27 */
252   { 1,   "signatureAlgorithm",          ASN1_SEQUENCE,     ASN1_NONE }, /* 28 */
253   { 2,     "algorithm",                 ASN1_OID,          ASN1_BODY }, /* 29 */
254   { 1,   "signature",                   ASN1_BIT_STRING,   ASN1_BODY }  /* 30 */
255  };
256
257 #define CRL_OBJ_CERTIFICATE_LIST                 0
258 #define CRL_OBJ_TBS_CERT_LIST                    1
259 #define CRL_OBJ_VERSION                          2
260 #define CRL_OBJ_SIG_ALG                          5
261 #define CRL_OBJ_ISSUER                           6
262 #define CRL_OBJ_THIS_UPDATE                      7
263 #define CRL_OBJ_NEXT_UPDATE                      8
264 #define CRL_OBJ_USER_CERTIFICATE                12
265 #define CRL_OBJ_REVOCATION_DATE                 13
266 #define CRL_OBJ_CRITICAL                        17
267 #define CRL_OBJ_ALGORITHM                       29
268 #define CRL_OBJ_SIGNATURE                       30
269 #define CRL_OBJ_ROOF                            31
270
271
272 const x509cert_t empty_x509cert = {
273       NULL     , /* *next */
274             0  , /* installed */
275             0  , /* count */
276     { NULL, 0 }, /* certificate */
277     { NULL, 0 }, /*   tbsCertificate */
278             1  , /*     version */
279     { NULL, 0 }, /*     serialNumber */
280                  /*     signature */
281     { NULL, 0 }, /*       sigAlg */
282     { NULL, 0 }, /*     issuer */
283                  /*     validity */
284             0  , /*       notBefore */
285             0  , /*       notAfter */
286     { NULL, 0 }, /*     subject */
287                  /*     subjectPublicKeyInfo */
288             0  , /*       subjectPublicKeyAlgorithm */
289                  /*     subjectPublicKey */
290     { NULL, 0 }, /*       modulus */
291     { NULL, 0 }, /*       publicExponent */
292     { NULL, 0 }, /*     issuerUniqueID */
293     { NULL, 0 }, /*     subjectUniqueID */
294                  /*     extensions */
295                  /*       extension */
296                  /*         extnID */
297                  /*         critical */
298                  /*         extnValue */
299       FALSE    , /*           isCA */
300       NULL     , /*           subjectAltName */
301       NULL     , /*           crlDistributionPoints */
302                  /*   signatureAlgorithm */
303     { NULL, 0 }, /*     algorithm */
304     { NULL, 0 }  /*   signature */
305 };
306
307 const x509crl_t empty_x509crl = {
308       NULL     , /* *next */
309             0  , /* installed */
310     { NULL, 0 }, /* certificateList */
311     { NULL, 0 }, /*   tbsCertList */
312             1  , /*     version */
313     { NULL, 0 }, /*     sigAlg */
314     { NULL, 0 }, /*     issuer */
315             0  , /*     thisUpdate */
316             0  , /*     nextUpdate */
317       NULL     , /*     revokedCertificates */
318                  /*     crlExtensions*/
319                  /*   signatureAlgorithm*/
320     { NULL, 0 }, /*     algorithm*/
321     { NULL, 0 }  /*   signature*/
322 };
323
324
325 /* coding of X.501 distinguished name */
326
327 typedef struct {
328     u_char *name;
329     chunk_t oid;
330     u_char type;
331 } x501rdn_t;
332
333
334 /* X.501 acronyms for well known object identifiers (OIDs) */
335
336 static const u_char oid_CN[] = {0x55, 0x04, 0x03};
337 static const u_char oid_S[]  = {0x55, 0x04, 0x04};
338 static const u_char oid_SN[] = {0x55, 0x04, 0x05};
339 static const u_char oid_C[]  = {0x55, 0x04, 0x06};
340 static const u_char oid_L[]  = {0x55, 0x04, 0x07};
341 static const u_char oid_ST[] = {0x55, 0x04, 0x08};
342 static const u_char oid_O[]  = {0x55, 0x04, 0x0A};
343 static const u_char oid_OU[] = {0x55, 0x04, 0x0B};
344 static const u_char oid_T[]  = {0x55, 0x04, 0x0C};
345 static const u_char oid_D[]  = {0x55, 0x04, 0x0D};
346 static const u_char oid_N[]  = {0x55, 0x04, 0x29};
347 static const u_char oid_G[]  = {0x55, 0x04, 0x2A};
348 static const u_char oid_I[]  = {0x55, 0x04, 0x2B};
349 static const u_char oid_E[]  = {0x2A, 0x86, 0x48, 0x86, 0xF7,
350                                       0x0D, 0x01, 0x09, 0x01};
351 static const u_char oid_TCGID[] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x89,
352                                    0x31, 0x01, 0x01, 0x02, 0x02, 0x4B};
353
354 static const x501rdn_t x501rdns[] = {
355   {"CN"    , {oid_CN,     3}, ASN1_PRINTABLESTRING},
356   {"S"     , {oid_S,      3}, ASN1_PRINTABLESTRING},
357   {"SN"    , {oid_SN,     3}, ASN1_PRINTABLESTRING},
358   {"C"     , {oid_C,      3}, ASN1_PRINTABLESTRING},
359   {"L"     , {oid_L,      3}, ASN1_PRINTABLESTRING},
360   {"ST"    , {oid_ST,     3}, ASN1_PRINTABLESTRING},
361   {"O"     , {oid_O,      3}, ASN1_PRINTABLESTRING},
362   {"OU"    , {oid_OU,     3}, ASN1_PRINTABLESTRING},
363   {"T"     , {oid_T,      3}, ASN1_PRINTABLESTRING},
364   {"D"     , {oid_D,      3}, ASN1_PRINTABLESTRING},
365   {"N"     , {oid_N,      3}, ASN1_PRINTABLESTRING},
366   {"G"     , {oid_G,      3}, ASN1_PRINTABLESTRING},
367   {"I"     , {oid_I,      3}, ASN1_PRINTABLESTRING},
368   {"E"     , {oid_E,      9}, ASN1_IA5STRING},
369   {"Email" , {oid_E,      9}, ASN1_IA5STRING},
370   {"emailAddress" , {oid_E,      9}, ASN1_IA5STRING},
371   {"TCGID" , {oid_TCGID, 12}, ASN1_PRINTABLESTRING}
372 };
373
374 #define X501_RDN_ROOF   16
375
376 /* Maximum length of ASN.1 distinquished name */
377
378 #define BUF_LEN       512
379
380 static void
381 code_asn1_length(u_int length, chunk_t *code)
382 {
383     if (length < 128)
384     {
385         code->ptr[0] = length;
386         code->len = 1;
387     }
388     else if (length < 256)
389     {
390         code->ptr[0] = 0x81;
391         code->ptr[1] = length;
392         code->len = 2;
393     }
394     else
395     {
396         code->ptr[0] = 0x82;
397         code->ptr[1] = length >> 8;
398         code->ptr[2] = length & 0xff;
399         code->len = 3;
400     }
401 }
402
403
404 static void
405 update_chunk(chunk_t *ch, int n)
406 {
407     n = (n > -1 && n < ch->len)? n : ch->len-1;
408     ch->ptr += n; ch->len -= n;
409 }
410
411
412 /*
413  *  Pointer is set to the first RDN in a DN
414  */
415 static err_t
416 init_rdn(chunk_t dn, chunk_t *rdn)
417 {
418     *rdn = empty_chunk;
419
420     /* a DN is a SEQUENCE OF RDNs */
421
422     if (*dn.ptr != ASN1_SEQUENCE)
423     {
424         return "DN is not a SEQUENCE";
425     }
426
427     rdn->len = asn1_length(&dn);
428     rdn->ptr = dn.ptr;
429
430     return NULL;
431 }
432
433 /*
434  *  Fetches the next RDN in a DN
435  */
436 static err_t
437 get_next_rdn(chunk_t *rdn, chunk_t *oid, chunk_t *value, asn1_t *type)
438 {
439     chunk_t attribute;
440
441     /* initialize return values */
442     *oid   = empty_chunk;
443     *value = empty_chunk;
444
445     /* an RDN is a SET OF attributeTypeAndValue */
446     if (*rdn->ptr != ASN1_SET)
447         return "RDN is not a SET";
448
449     attribute.len = asn1_length(rdn);
450     attribute.ptr = rdn->ptr;
451
452     /* advance to start of next RDN */
453     rdn->ptr += attribute.len;
454     rdn->len -= attribute.len;
455
456     /* an attributeTypeAndValue is a SEQUENCE */
457     if (*attribute.ptr != ASN1_SEQUENCE)
458         return "attributeTypeAndValue is not a SEQUENCE";
459
460     /* extract the attribute body */
461     attribute.len = asn1_length(&attribute);
462
463     /* attribute type is an OID */
464     if (*attribute.ptr != ASN1_OID)
465         return "attributeType is not an OID";
466
467     /* extract OID */
468     oid->len = asn1_length(&attribute);
469     oid->ptr = attribute.ptr;
470
471     /* advance to the attribute value */
472     attribute.ptr += oid->len;
473     attribute.len -= oid->len;
474
475     /* extract string type */
476     *type = *attribute.ptr;
477
478     /* extract string value */
479     value->len = asn1_length(&attribute);
480     value->ptr = attribute.ptr;
481
482     return NULL;
483 }
484
485 /*
486  *  Parses an ASN.1 distinguished name int its OID/value pairs
487  */
488 static err_t
489 dn_parse(chunk_t dn, chunk_t *str)
490 {
491     chunk_t rdn, oid, value;
492     asn1_t type;
493     int oid_code;
494     int first = TRUE;
495
496     err_t ugh = init_rdn(dn, &rdn);
497
498     if (ugh != NULL) /* a parsing error has occured */
499         return ugh;
500
501     while (rdn.len > 0)
502     {
503         ugh = get_next_rdn(&rdn, &oid, &value, &type);
504
505         if (ugh != NULL) /* a parsing error has occured */
506             return ugh;
507
508         if (first)              /* first OID/value pair */
509             first = FALSE;
510         else                    /* separate OID/value pair by a comma */
511             update_chunk(str, snprintf(str->ptr,str->len,", "));
512
513         /* print OID */
514         oid_code = known_oid(oid);
515         if (oid_code == -1)     /* OID not found in list */
516             hex_str(oid, str);
517         else
518             update_chunk(str, snprintf(str->ptr,str->len,"%s",
519                               oid_names[oid_code].name));
520
521         /* print value */
522         update_chunk(str, snprintf(str->ptr,str->len,"=%.*s",
523                               (int)value.len,value.ptr));
524     }
525     return NULL;
526 }
527
528 /*
529  * Prints a binary string in hexadecimal form
530  */
531 void
532 hex_str(chunk_t bin, chunk_t *str)
533 {
534     u_int i;
535     update_chunk(str, snprintf(str->ptr,str->len,"0x"));
536     for (i=0; i < bin.len; i++)
537         update_chunk(str, snprintf(str->ptr,str->len,"%02X",*bin.ptr++));
538 }
539
540
541 /*  Converts a binary DER-encoded ASN.1 distinguished name
542  *  into LDAP-style human-readable ASCII format
543  */
544 int
545 dntoa(char *dst, size_t dstlen, chunk_t dn)
546 {
547     err_t ugh = NULL;
548     chunk_t str;
549
550     str.ptr = dst;
551     str.len = dstlen;
552     ugh = dn_parse(dn, &str);
553
554     if (ugh != NULL) /* error, print DN as hex string */
555     {
556         DBG(DBG_PARSING,
557             DBG_log("error in DN parsing: %s", ugh)
558         )
559         str.ptr = dst;
560         str.len = dstlen;
561         hex_str(dn, &str);
562     }
563     return (int)(dstlen - str.len);
564 }
565
566 /*  Converts an LDAP-style human-readable ASCII-encoded
567  *  ASN.1 distinguished name into binary DER-encoded format
568  */
569 err_t
570 atodn(char *src, chunk_t *dn)
571 {
572   /* finite state machine for atodn */
573
574     typedef enum {
575         SEARCH_OID =    0,
576         READ_OID =      1,
577         SEARCH_NAME =   2,
578         READ_NAME =     3,
579         UNKNOWN_OID =   4
580     } state_t;
581
582     u_char oid_len_buf[3];
583     u_char name_len_buf[3];
584     u_char rdn_seq_len_buf[3];
585     u_char rdn_set_len_buf[3];
586     u_char dn_seq_len_buf[3];
587
588     chunk_t asn1_oid_len     = { oid_len_buf,     0 };
589     chunk_t asn1_name_len    = { name_len_buf,    0 };
590     chunk_t asn1_rdn_seq_len = { rdn_seq_len_buf, 0 };
591     chunk_t asn1_rdn_set_len = { rdn_set_len_buf, 0 };
592     chunk_t asn1_dn_seq_len  = { dn_seq_len_buf,  0 };
593     chunk_t oid  = empty_chunk;
594     chunk_t name = empty_chunk;
595
596     int whitespace  = 0;
597     int rdn_seq_len = 0;
598     int rdn_set_len = 0;
599     int dn_seq_len  = 0;
600     int pos         = 0;
601
602     err_t ugh = NULL;
603
604     u_char *dn_ptr = dn->ptr + 4;
605
606     state_t state = SEARCH_OID;
607
608     do
609     {
610         switch (state)
611         {
612         case SEARCH_OID:
613             if (*src != ' ' && *src != '/' && *src !=  ',')
614             {
615                 oid.ptr = src;
616                 oid.len = 1;
617                 state = READ_OID;
618             }
619             break;
620         case READ_OID:
621             if (*src != ' ' && *src != '=')
622                 oid.len++;
623             else
624             {
625                 for (pos = 0; pos < X501_RDN_ROOF; pos++)
626                 {
627                     if (strlen(x501rdns[pos].name) == oid.len &&
628                         strncasecmp(x501rdns[pos].name, oid.ptr, oid.len) == 0)
629                         break; /* found a valid OID */
630                 }
631                 if (pos == X501_RDN_ROOF)
632                 {
633                     ugh = "unknown OID in ID_DER_ASN1_DN";
634                     state = UNKNOWN_OID;
635                     break;
636                 }
637                 code_asn1_length(x501rdns[pos].oid.len, &asn1_oid_len);
638
639                 /* reset oid and change state */
640                 oid = empty_chunk;
641                 state = SEARCH_NAME;
642             }
643             break;
644         case SEARCH_NAME:
645             if (*src != ' ' && *src != '=')
646             {
647                 name.ptr = src;
648                 name.len = 1;
649                 whitespace = 0;
650                 state = READ_NAME;
651             }
652             break;
653         case READ_NAME:
654             if (*src != ',' && *src != '/' && *src != '\0')
655             {
656                 name.len++;
657                 if (*src == ' ')
658                     whitespace++;
659                 else
660                     whitespace = 0;
661             }
662             else
663             {
664                 name.len -= whitespace;
665                 code_asn1_length(name.len, &asn1_name_len);
666
667                 /* compute the length of the relative distinguished name sequence */
668                 rdn_seq_len = 1 + asn1_oid_len.len + x501rdns[pos].oid.len +
669                               1 + asn1_name_len.len + name.len;
670                 code_asn1_length(rdn_seq_len, &asn1_rdn_seq_len);
671
672                 /* compute the length of the relative distinguished name set */
673                 rdn_set_len = 1 + asn1_rdn_seq_len.len + rdn_seq_len;
674                 code_asn1_length(rdn_set_len, &asn1_rdn_set_len);
675
676                 /* encode the relative distinguished name */
677                 *dn_ptr++ = ASN1_SET;
678                 chunkcpy(dn_ptr, asn1_rdn_set_len);
679                 *dn_ptr++ = ASN1_SEQUENCE;
680                 chunkcpy(dn_ptr, asn1_rdn_seq_len);
681                 *dn_ptr++ = ASN1_OID;
682                 chunkcpy(dn_ptr, asn1_oid_len);
683                 chunkcpy(dn_ptr, x501rdns[pos].oid);
684                 /* encode the ASN.1 character string type of the name */
685                 *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
686                     && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
687                 chunkcpy(dn_ptr, asn1_name_len);
688                 chunkcpy(dn_ptr, name);
689
690                 /* accumulate the length of the distinguished name sequence */
691                 dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
692
693                 /* reset name and change state */
694                 name = empty_chunk;
695                 state = SEARCH_OID;
696             }
697             break;
698         case UNKNOWN_OID:
699             break;
700         }
701     } while (*src++ != '\0');
702
703     /* complete the distinguished name sequence*/
704     code_asn1_length(dn_seq_len, &asn1_dn_seq_len);
705     dn->ptr += 3 - asn1_dn_seq_len.len;
706     dn->len =  1 + asn1_dn_seq_len.len + dn_seq_len;
707     dn_ptr = dn->ptr;
708     *dn_ptr++ = ASN1_SEQUENCE;
709     chunkcpy(dn_ptr, asn1_dn_seq_len);
710     return ugh;
711 }
712
713 /*  compare two distinguished names by
714  *  comparing the individual RDNs
715  */
716 bool
717 same_dn(chunk_t a, chunk_t b)
718 {
719     chunk_t rdn_a,   rdn_b;
720     chunk_t oid_a,   oid_b;
721     chunk_t value_a, value_b;
722     asn1_t  type_a,  type_b;
723
724     /* same lengths for the DNs */
725     if (a.len != b.len)
726         return FALSE;
727
728     /* initialize DN parsing */
729     if (init_rdn(a, &rdn_a) != NULL || init_rdn(b, &rdn_b) != NULL)
730         return FALSE;
731
732     /* fetch next RDN pair */
733     while (rdn_a.len > 0 && rdn_b.len > 0)
734     {
735         /* parse next RDNs and check for errors */
736         if (get_next_rdn(&rdn_a, &oid_a, &value_a, &type_a) != NULL ||
737             get_next_rdn(&rdn_b, &oid_b, &value_b, &type_b) != NULL)
738         {
739             return FALSE;
740         }
741
742         /* OIDs must agree */
743         if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
744             return FALSE;
745
746         /* same lengths for values */
747         if (value_a.len != value_b.len)
748             return FALSE;
749
750         /* printableStrings and email RDNs require uppercase comparison */
751         if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
752            (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
753         {
754             if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
755                 return FALSE;
756         }
757         else
758         {
759             if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
760                 return FALSE;
761         }
762     }
763     /* both DNs must have same number of RDNs */
764     if (rdn_a.len != 0 || rdn_b.len != 0)
765         return FALSE;
766
767     /* the two DNs are equal! */
768     return TRUE;
769 }
770
771 /*
772  *  compare two certificates by comparing their signatures
773  */
774 static bool
775 same_cert(x509cert_t *a, x509cert_t *b)
776 {
777     return a->signature.len == b->signature.len &&
778         memcmp(a->signature.ptr, b->signature.ptr, b->signature.len) == 0;
779 }
780
781 /*  for each link pointing to the certificate
782  "  increase the count by one
783  */
784 void
785 share_x509cert(x509cert_t *cert)
786 {
787     if (cert != NULL)
788         cert->count++;
789 }
790
791 /*
792  *  add a X.509 user/host certificate to the chained list
793  */
794 x509cert_t*
795 add_x509cert(x509cert_t *cert)
796 {
797     x509cert_t *c = x509certs;
798
799     while (c != NULL)
800     {
801         if (same_cert(c, cert)) /* already in chain, free cert */
802         {
803             free_x509cert(cert);
804             return c;
805         }
806         c = c->next;
807     }
808
809     /* insert new cert at the root of the chain */
810     cert->next = x509certs;
811     x509certs = cert;
812     return cert;
813 }
814
815 /*
816  *  get the X.509 CA certificate with a given subject
817  */
818 static x509cert_t*
819 get_x509cacert(chunk_t subject)
820 {
821     x509cert_t *cert = x509cacerts;
822     x509cert_t *prev_cert = NULL;
823
824     while(cert != NULL)
825    {
826         if (same_dn(cert->subject, subject))
827         {
828             if (cert != x509cacerts)
829             {
830                 /* bring the certificate up front */
831                 prev_cert->next = cert->next;
832                 cert->next = x509cacerts;
833                 x509cacerts = cert;
834             }
835             return cert;
836         }
837         prev_cert = cert;
838         cert = cert->next;
839     }
840     return NULL;
841 }
842
843 /*
844  *  get the X.509 CRL with a given issuer
845  */
846 static x509crl_t*
847 get_x509crl(chunk_t issuer)
848 {
849     x509crl_t *crl = x509crls;
850     x509crl_t *prev_crl = NULL;
851
852     while(crl != NULL)
853    {
854         if (same_dn(crl->issuer, issuer))
855         {
856             if (crl != x509crls)
857             {
858                 /* bring the CRL up front */
859                 prev_crl->next = crl->next;
860                 crl->next = x509crls;
861                 x509crls = crl;
862             }
863             return crl;
864         }
865         prev_crl = crl;
866         crl = crl->next;
867     }
868     return NULL;
869 }
870
871 /*  Send my certificate either defined and loaded via
872  *  /etc/ipsec.conf or by default loaded from /etc/x509cert.der
873  *  (deprecated for X.509 certificates)
874  */
875 bool
876 get_mycert(cert_t *mycert, x509cert_t *cert)
877 {
878     *mycert = my_default_cert;
879
880     if (cert != NULL)
881     {
882         mycert->type = CERT_X509_SIGNATURE;
883         mycert->cert = cert->certificate;
884     }
885     return mycert->type != CERT_NONE;
886 }
887
888 /*
889  *  free the dynamic memory used to store generalNames
890  */
891 void
892 free_generalNames(generalName_t* gn)
893 {
894     while (gn != NULL)
895     {
896         generalName_t *gn_top = gn;
897         gn = gn->next;
898         pfree(gn_top);
899     }
900 }
901
902 /*
903  *  free a X.509 certificate
904  */
905 void
906 free_x509cert(x509cert_t *cert)
907 {
908     if (cert != NULL)
909     {
910         free_generalNames(cert->subjectAltName);
911         free_generalNames(cert->crlDistributionPoints);
912         if (cert->certificate.ptr != NULL)
913             pfree(cert->certificate.ptr);
914         pfree(cert);
915         cert = NULL;
916     }
917 }
918
919 /*  release of a certificate decreases the count by one
920  "  the certificate is freed when the counter reaches zero
921  */
922 void
923 release_x509cert(x509cert_t *cert)
924 {
925     if (cert != NULL && --cert->count == 0)
926     {
927         x509cert_t **pp = &x509certs;
928         while (*pp != cert)
929             pp = &(*pp)->next;
930         *pp = cert->next;
931         free_x509cert(cert);
932     }
933 }
934
935 /*
936  *  free the first CA certificate in the chain
937  */
938 static void
939 free_first_cacert(void)
940 {
941     x509cert_t *first = x509cacerts;
942     x509cacerts = first->next;
943     free_x509cert(first);
944 }
945
946 /*
947  *  free  all CA certificates
948  */
949 void
950 free_cacerts(void)
951 {
952     while (x509cacerts != NULL)
953         free_first_cacert();
954 }
955
956 /*
957  *  free the dynamic memory used to store revoked certificates
958  */
959 static void
960 free_revoked_certs(revokedCert_t* revokedCerts)
961 {
962     while (revokedCerts != NULL)
963     {
964         revokedCert_t * revokedCert = revokedCerts;
965         revokedCerts = revokedCert->next;
966         pfree(revokedCert);
967     }
968 }
969
970 /*
971  *  free the dynamic memory used to store CRLs
972  */
973 static void
974 free_first_crl(void)
975 {
976     x509crl_t * crl = x509crls;
977     x509crls = crl->next;
978     free_revoked_certs(crl->revokedCertificates);
979     pfree(crl->certificateList.ptr);
980     pfree(crl);
981 }
982
983 void
984 free_crls(void)
985 {
986     while (x509crls != NULL)
987         free_first_crl();
988 }
989
990 /*
991  *  free the dynamic memory used to store my X.509 or OpenPGP certificate
992  */
993 void
994 free_mycert(void)
995 {
996     freeanychunk(my_default_cert.cert);
997 }
998
999 /*
1000  *  Filter eliminating the directory entries '.' and '..'
1001  */
1002 static int
1003 file_select(const struct dirent *entry)
1004 {
1005     return strcmp(entry->d_name, "." ) &&
1006            strcmp(entry->d_name, "..");
1007 }
1008
1009 /*
1010  * stores a chained list of user/host and CA certs
1011  */
1012 void
1013 store_x509certs(x509cert_t **firstcert)
1014 {
1015     x509cert_t **pp = firstcert;
1016
1017     /* first store CA certs */
1018
1019     while (*pp != NULL)
1020     {
1021         x509cert_t *cert = *pp;
1022
1023         if (cert->isCA)
1024         {
1025             /* we don't accept self-signed CA certs */
1026             if (same_dn(cert->issuer, cert->subject))
1027             {
1028                 log("self-signed cacert rejected");
1029                 *pp = cert->next;
1030                 free_x509cert(cert);
1031             }
1032             else
1033             {
1034                 if (get_x509cacert(cert->subject))
1035                 {
1036                     free_first_cacert();
1037                     DBG(DBG_PARSING,
1038                         DBG_log("existing cacert deleted")
1039                     )
1040                 }
1041                 share_x509cert(cert);  /* set count to one */
1042
1043                 /* insert into chained cacert list*/
1044                 *pp = cert->next;
1045                 cert->next = x509cacerts;
1046                 x509cacerts = cert;
1047                 DBG(DBG_PARSING,
1048                     DBG_log("cacert inserted")
1049                 )
1050             }
1051         }
1052         else
1053             pp = &cert->next;
1054     }
1055
1056     /* now verify user/host certificates */
1057
1058     pp = firstcert;
1059
1060     while (*pp != NULL)
1061     {
1062         x509cert_t *cert = *pp;
1063
1064         if (verify_x509cert(cert))
1065         {
1066             DBG(DBG_PARSING,
1067                 DBG_log("Public key validated")
1068             )
1069             add_x509_public_key(cert, DAL_SIGNED);
1070         }
1071         else
1072         {
1073             log("X.509 certificate rejected");
1074         }
1075         *pp = cert->next;
1076         free_x509cert(cert);
1077     }
1078 }
1079
1080 /*
1081  *  Loads a X.509 certificate
1082  */
1083 x509cert_t*
1084 load_x509cert(const char* filename, const char* label)
1085 {
1086     chunk_t blob = empty_chunk;
1087     if (load_asn1_file(filename, "", label, &blob))
1088     {
1089         x509cert_t *cert = alloc_thing(x509cert_t, "x509cert");
1090         *cert = empty_x509cert;
1091         if (parse_x509cert(blob, 0, cert)) {
1092             log("  X.509 loaded: %s", filename);
1093             return cert;
1094         } else
1095         {
1096             log("  error in X.509 certificate: %s", filename);
1097             free_x509cert(cert);
1098         }
1099     }
1100     return NULL;
1101 }
1102
1103 /*
1104  *  Loads a host certificate
1105  */
1106 x509cert_t*
1107 load_host_cert(const char* filename)
1108 {
1109     char path[BUF_LEN];
1110
1111     if (*filename == '/')       /* absolute pathname */
1112         strncpy(path, filename, BUF_LEN);
1113     else                        /* relative pathname */
1114         snprintf(path, BUF_LEN, "%s/%s", HOST_CERT_PATH, filename);
1115
1116     return load_x509cert(path, "host cert");
1117 }
1118
1119 /*
1120  *  Loads CA certificates
1121  */
1122 void
1123 load_cacerts(void)
1124 {
1125     struct dirent **filelist;
1126     u_char buf[BUF_LEN];
1127     u_char *save_dir;
1128     int n;
1129
1130     /* change directory to specified path */
1131     save_dir = getcwd(buf, BUF_LEN);
1132     if (chdir(CA_CERT_PATH))
1133     {
1134         log("Could not change to directory '%s'", CA_CERT_PATH);
1135     }
1136     else
1137     {
1138         log("Changing to directory '%s'",CA_CERT_PATH);
1139         n = scandir(CA_CERT_PATH, &filelist, file_select, alphasort);
1140
1141         if (n <= 0)
1142             log("  Warning: empty directory");
1143         else
1144         {
1145             while (n--)
1146             {
1147                 x509cert_t *cacert = load_x509cert(filelist[n]->d_name, "cacert");
1148                 if (cacert != NULL)
1149                 {
1150                     if (get_x509cacert(cacert->subject))
1151                     {
1152                         free_first_cacert();
1153                         DBG(DBG_PARSING,
1154                             DBG_log("  existing cacert deleted")
1155                         )
1156                     }
1157                     share_x509cert(cacert);  /* set count to one */
1158                     cacert->next = x509cacerts;
1159                     x509cacerts = cacert;
1160                 }
1161                 free(filelist[n]);
1162             }
1163             free(filelist);
1164         }
1165     }
1166     /* restore directory path */
1167     chdir(save_dir);
1168 }
1169
1170 /*
1171  *  Loads CRLs
1172  */
1173 void
1174 load_crls(void)
1175 {
1176     struct dirent **filelist;
1177     u_char buf[BUF_LEN];
1178     u_char *save_dir;
1179     int n;
1180
1181     /* change directory to specified path */
1182     save_dir = getcwd(buf, BUF_LEN);
1183     if (chdir(CRL_PATH))
1184     {
1185         log("Could not change to directory '%s'", CRL_PATH);
1186     }
1187     else
1188     {
1189 //      log("Changing to directory '%s'", CRL_PATH);
1190         n = scandir(CRL_PATH, &filelist, file_select, alphasort);
1191
1192         if (n <= 0)
1193             log("  Warning: empty directory");
1194         else
1195         {
1196             while (n--)
1197             {
1198                 chunk_t blob = empty_chunk;
1199                 if (load_asn1_file(filelist[n]->d_name, "", "crl", &blob))
1200                 {
1201                     x509crl_t *crl = alloc_thing(x509crl_t, "x509crl");
1202                     *crl = empty_x509crl;
1203                     if (parse_x509crl(blob, 0, crl))
1204                     {
1205                         if (get_x509crl(crl->issuer))
1206                         {
1207                             free_first_crl();
1208                             DBG(DBG_PARSING,
1209                                 DBG_log("  existing CRL deleted")
1210                             )
1211                         }
1212                         log("  X.509 CRL loaded: %s",filelist[n]->d_name);
1213                         crl->next = x509crls;
1214                         x509crls = crl;
1215                     }
1216                     else
1217                     {
1218                         log("  error in X.509 CRL: %s",filelist[n]->d_name);
1219                         free_revoked_certs(crl->revokedCertificates);
1220                         pfree(blob.ptr);
1221                         pfree(crl);
1222                     }
1223                 }
1224                 else
1225                 free(filelist[n]);
1226             }
1227             free(filelist);
1228         }
1229     }
1230     /* restore directory path */
1231     chdir(save_dir);
1232 }
1233
1234 /*  Loads the X.509 or OpenPGP certificate sent by FreeS/WAN to
1235  *  its peers during ISAKMP Phase 1
1236  */
1237 void
1238 load_mycert(void)
1239 {
1240     x509cert_t *myX509cert = NULL;
1241
1242     /* deleting old certificate, if present */
1243     pfreeany(my_default_cert.cert.ptr);
1244
1245     /* initializing certificate */
1246     my_default_cert.type = CERT_NONE;
1247     my_default_cert.cert = empty_chunk;
1248
1249     /* loading a default X.509 certificate, if available */
1250     myX509cert = load_x509cert(X509_CERT_PATH, "my default X.509 cert");
1251
1252     if (myX509cert != NULL)
1253     {
1254         my_default_cert.type = CERT_X509_SIGNATURE;
1255         my_default_cert.cert = myX509cert->certificate;
1256         myX509cert->certificate = empty_chunk;
1257         free_x509cert(myX509cert);
1258     }
1259     else
1260     {
1261         /* loading an OpenPGP certificate, if available */
1262         FILE *fd = NULL;
1263         int i;
1264
1265         fd = fopen(PGP_CERT_PATH, "r");
1266         if (fd)
1267         {
1268             my_default_cert.type = CERT_PGP;
1269             fseek(fd, 0, SEEK_END );
1270             my_default_cert.cert.len = ftell(fd);
1271             rewind(fd);
1272             my_default_cert.cert.ptr = alloc_bytes(my_default_cert.cert.len, "cert");
1273             i = fread(my_default_cert.cert.ptr, 1, my_default_cert.cert.len, fd);
1274             fclose(fd);
1275             log("Loaded my OpenPGP certificate file '%s' (%d bytes)",
1276                 PGP_CERT_PATH, i);
1277         }
1278         else
1279         {
1280 //          log("OpenPGP certificate file '%s' not found", PGP_CERT_PATH);
1281         }
1282     }
1283 }
1284
1285 /*
1286  * extracts the basicConstraints extension
1287  */
1288 static bool
1289 parse_basicConstraints(chunk_t blob, int level0)
1290 {
1291     asn1_ctx_t ctx;
1292     chunk_t object;
1293     int objectID = 0;
1294     bool isCA = FALSE;
1295
1296     asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
1297
1298     while (objectID < BASIC_CONSTRAINTS_ROOF) {
1299
1300         if (!extract_object(basicConstraintsObjects, &objectID,
1301                             &object, &ctx))
1302              break;
1303
1304         if (objectID == BASIC_CONSTRAINTS_CA)
1305         {
1306             isCA = object.len && *object.ptr;
1307             DBG(DBG_PARSING,
1308                 DBG_log("  %s",(isCA)?"TRUE":"FALSE");
1309             )
1310         }
1311         objectID++;
1312     }
1313     return isCA;
1314 }
1315
1316 /*
1317  *  Converts a X.500 generalName into an ID
1318  */
1319 void
1320 gntoid(struct id *id, const generalName_t *gn)
1321 {
1322     switch(gn->kind)
1323     {
1324     case GN_DNS_NAME:           /* ID type: ID_FQDN */
1325         id->kind = ID_FQDN;
1326         id->name = gn->name;
1327         break;
1328     case GN_IP_ADDRESS:         /* ID type: ID_IPV4_ADDR */
1329         {
1330             const struct af_info *afi = &af_inet4_info;
1331             err_t ugh = NULL;
1332
1333             id->kind = afi->id_addr;
1334             ugh = initaddr(gn->name.ptr, gn->name.len, afi->af, &id->ip_addr);
1335         }
1336         break;
1337     case GN_RFC822_NAME:        /* ID type: ID_USER_FQDN */
1338         id->kind = ID_USER_FQDN;
1339         id->name = gn->name;
1340         break;
1341     default:
1342         id->kind = ID_NONE;
1343         id->name = empty_chunk;
1344         break;
1345     }
1346 }
1347
1348 /*
1349  * extracts one or several GNs and puts them into a chained list
1350  */
1351 static generalName_t*
1352 parse_generalNames(chunk_t blob, int level0, bool implicit)
1353 {
1354     u_char buf[BUF_LEN];
1355     asn1_ctx_t ctx;
1356     chunk_t object;
1357     int objectID = 0;
1358    
1359     generalName_t *top_gn = NULL;
1360
1361     asn1_init(&ctx, blob, level0, implicit, DBG_RAW);
1362  
1363     while (objectID < GN_OBJ_ROOF) {
1364         bool valid_gn = FALSE;
1365
1366         if (!extract_object(generalNamesObjects, &objectID, &object, &ctx))
1367              return NULL;
1368
1369         switch (objectID) {
1370         case GN_OBJ_RFC822_NAME:
1371         case GN_OBJ_DNS_NAME:
1372         case GN_OBJ_URI:
1373             DBG(DBG_PARSING,
1374                 DBG_log("  '%.*s'", (int)object.len, object.ptr);
1375             )
1376             valid_gn = TRUE;
1377             break;
1378         case GN_OBJ_DIRECTORY_NAME:
1379             dntoa(buf, BUF_LEN, object);
1380             DBG(DBG_PARSING,
1381                 DBG_log("  '%s'", buf);
1382             )
1383             valid_gn = TRUE;
1384             break;
1385         case GN_OBJ_IP_ADDRESS:
1386             DBG(DBG_PARSING,
1387                 DBG_log("  '%d.%d.%d.%d'", *object.ptr, *(object.ptr+1),
1388                                       *(object.ptr+2), *(object.ptr+3));
1389             )
1390             valid_gn = TRUE;
1391             break;
1392         case GN_OBJ_OTHER_NAME:
1393         case GN_OBJ_X400_ADDRESS:
1394         case GN_OBJ_EDI_PARTY_NAME:
1395         case GN_OBJ_REGISTERED_ID:
1396             break;
1397         default:
1398             break;
1399         }
1400
1401         if (valid_gn)
1402         {
1403             generalName_t *gn = alloc_thing(generalName_t, "generalName");
1404             gn->kind = (objectID - GN_OBJ_OTHER_NAME) / 2;
1405             gn->name = object;
1406             gn->next = top_gn;
1407             top_gn = gn;
1408         }
1409         objectID++;
1410     }
1411     return top_gn;
1412 }
1413
1414 /*  extracts one or several crlDistributionPoints and puts them into
1415  *  a chained list
1416  */
1417 static generalName_t*
1418 parse_crlDistributionPoints(chunk_t blob, int level0)
1419 {
1420     asn1_ctx_t ctx;
1421     chunk_t object;
1422     int objectID = 0;
1423
1424     generalName_t *top_gn = NULL;      /* top of the chained list */
1425     generalName_t **tail_gn = &top_gn; /* tail of the chained list */
1426
1427     asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
1428
1429     while (objectID < CRL_DIST_POINTS_ROOF) {
1430
1431         if (!extract_object(crlDistributionPointsObjects, &objectID,
1432                             &object, &ctx))
1433              return NULL;
1434
1435         if (objectID == CRL_DIST_POINTS_FULLNAME)
1436         {
1437             u_int level = crlDistributionPointsObjects[objectID].level + level0;
1438             generalName_t *gn = parse_generalNames(object, level, TRUE);
1439             /* append extracted generalNames to existing chained list */
1440             *tail_gn = gn;
1441             /* find new tail of the chained list */
1442             while (gn != NULL)
1443             {
1444                 tail_gn = &gn->next;  gn = gn->next;
1445             }
1446         }
1447         objectID++;
1448     }
1449     return top_gn;
1450 }
1451
1452
1453 /*
1454  *  Parses an X.509v3 certificate
1455  */
1456 bool
1457 parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
1458 {
1459     u_char  buf[BUF_LEN];
1460     asn1_ctx_t ctx;
1461     bool critical;
1462     chunk_t extnID;
1463     chunk_t object;
1464     int objectID = 0;
1465
1466     asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
1467
1468     while (objectID < X509_OBJ_ROOF) {
1469
1470         if (!extract_object(certObjects, &objectID, &object, &ctx))
1471              return FALSE;
1472
1473         switch (objectID) {
1474         case X509_OBJ_CERTIFICATE:
1475             cert->certificate = object;
1476             break;
1477         case X509_OBJ_TBS_CERTIFICATE:
1478             cert->tbsCertificate = object;
1479             break;
1480         case X509_OBJ_VERSION:
1481             cert->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
1482             DBG(DBG_PARSING,
1483                 DBG_log("  v%d", cert->version);
1484             )
1485             break;
1486         case X509_OBJ_SERIAL_NUMBER:
1487             cert->serialNumber = object;
1488             break;
1489         case X509_OBJ_SIG_ALG:
1490             cert->sigAlg = object;
1491             break;
1492         case X509_OBJ_ISSUER:
1493             cert->issuer = object;
1494             dntoa(buf, BUF_LEN, object);
1495             DBG(DBG_PARSING,
1496                 DBG_log("  '%s'",buf);
1497             )
1498             break;
1499         case X509_OBJ_NOT_BEFORE:
1500             cert->notBefore = asn1totime(&object, ASN1_UTCTIME);
1501             break;
1502         case X509_OBJ_NOT_AFTER:
1503             cert->notAfter = asn1totime(&object, ASN1_UTCTIME);
1504             break;
1505         case X509_OBJ_SUBJECT:
1506             cert->subject = object;
1507             dntoa(buf, BUF_LEN, object);
1508             DBG(DBG_PARSING,
1509                 DBG_log("  '%s'",buf);
1510             )
1511             break;
1512         case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM:
1513             if ( known_oid(object) == OID_RSA_ENCRYPTION )
1514                 cert->subjectPublicKeyAlgorithm = PUBKEY_ALG_RSA;
1515             break;
1516         case X509_OBJ_SUBJECT_PUBLIC_KEY:
1517             if (cert->subjectPublicKeyAlgorithm == PUBKEY_ALG_RSA)
1518             {
1519                 ctx.blobs[4].ptr++; ctx.blobs[4].len--;
1520             }
1521             else
1522                 objectID = X509_OBJ_MODULUS;
1523             break;
1524         case X509_OBJ_MODULUS:
1525             cert->modulus = object;
1526             break;
1527         case X509_OBJ_PUBLIC_EXPONENT:
1528             cert->publicExponent = object;
1529             break;
1530         case X509_OBJ_EXTN_ID:
1531             extnID = object;
1532             break;
1533         case X509_OBJ_CRITICAL:
1534             critical = object.len && *object.ptr;
1535             DBG(DBG_PARSING,
1536                 DBG_log("  %s",(critical)?"TRUE":"FALSE");
1537             )
1538             break;
1539         case X509_OBJ_EXTN_VALUE:
1540             {
1541                 u_int extn_oid = known_oid(extnID);
1542                 u_int level = level0 + certObjects[objectID].level + 1;
1543
1544                 if (extn_oid == OID_BASIC_CONSTRAINTS)
1545                     cert->isCA =
1546                         parse_basicConstraints(object, level);
1547                 else if (extn_oid == OID_SUBJECT_ALT_NAME)
1548                     cert->subjectAltName =
1549                         parse_generalNames(object, level, FALSE);
1550                 else if (extn_oid == OID_CRL_DISTRIBUTION_POINTS)
1551                     cert->crlDistributionPoints =
1552                         parse_crlDistributionPoints(object, level);
1553             }
1554             break;
1555         case X509_OBJ_ALGORITHM:
1556             cert->algorithm = object;
1557             break;
1558         case X509_OBJ_SIGNATURE:
1559             cert->signature = object;
1560             break;
1561         default:
1562             break;
1563         }
1564         objectID++;
1565     }
1566     time(&cert->installed);
1567     return TRUE;
1568 }
1569
1570
1571 /*
1572  *  Parses an X.509 CRL
1573  */
1574 bool
1575 parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
1576 {
1577     u_char buf[BUF_LEN];
1578     asn1_ctx_t ctx;
1579     bool critical;
1580     chunk_t userCertificate;
1581     chunk_t object;
1582     int objectID = 0;
1583
1584     asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
1585  
1586     while (objectID < CRL_OBJ_ROOF) {
1587
1588         if (!extract_object(crlObjects, &objectID, &object, &ctx))
1589              return FALSE;
1590
1591         switch (objectID) {
1592         case CRL_OBJ_CERTIFICATE_LIST:
1593             crl->certificateList = object;
1594             break;
1595         case CRL_OBJ_TBS_CERT_LIST:
1596             crl->tbsCertList = object;
1597             break;
1598         case CRL_OBJ_VERSION:
1599             crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
1600             DBG(DBG_PARSING,
1601                 DBG_log("  v%d", crl->version);
1602             )
1603             break;
1604         case CRL_OBJ_SIG_ALG:
1605             crl->sigAlg = object;
1606             break;
1607         case CRL_OBJ_ISSUER:
1608             crl->issuer = object;
1609             dntoa(buf, BUF_LEN, object);
1610             DBG(DBG_PARSING,
1611                 DBG_log("  '%s'",buf);
1612             )
1613             break;
1614         case CRL_OBJ_THIS_UPDATE:
1615             crl->thisUpdate = asn1totime(&object, ASN1_UTCTIME);
1616             break;
1617         case CRL_OBJ_NEXT_UPDATE:
1618             crl->nextUpdate = asn1totime(&object, ASN1_UTCTIME);
1619             break;
1620         case CRL_OBJ_USER_CERTIFICATE:
1621             userCertificate = object;
1622             break;
1623         case CRL_OBJ_REVOCATION_DATE:
1624             {
1625                 /* put all the serial numbers and the revocation date in a chained list
1626                    with revocedCertificates pointing to the first revoked certificate */
1627
1628                 revokedCert_t *revokedCert = alloc_thing(revokedCert_t, "revokedCert");
1629                 revokedCert->userCertificate = userCertificate;
1630                 revokedCert->revocationDate = asn1totime(&object, ASN1_UTCTIME);
1631                 revokedCert->next = crl->revokedCertificates;
1632                 crl->revokedCertificates = revokedCert;
1633             }
1634             break;
1635         case CRL_OBJ_CRITICAL:
1636             critical = object.len && *object.ptr;
1637             DBG(DBG_PARSING,
1638                 DBG_log("  %s",(critical)?"TRUE":"FALSE");
1639             )
1640             break;
1641         case CRL_OBJ_ALGORITHM:
1642             crl->algorithm = object;
1643             break;
1644         case CRL_OBJ_SIGNATURE:
1645             crl->signature = object;
1646             break;
1647         default:
1648             break;
1649         }
1650         objectID++;
1651     }
1652     time(&crl->installed);
1653     return TRUE;
1654 }
1655
1656 /* verify the validity of a certificate by
1657  * checking the notBefore and notAfter dates
1658 */
1659 bool
1660 check_validity(const x509cert_t *cert)
1661 {
1662     time_t current_time;
1663
1664     time(&current_time);
1665 #define DNDEBUG
1666 #ifdef DNDEBUG
1667         {
1668         // FIXME - This is probabaly not the best place to put this
1669         // however it makes debugging certificate problems much easier
1670         struct id id = empty_id;
1671         char buf[IDTOA_BUF];
1672
1673         id.kind = ID_DER_ASN1_DN;
1674         id.name.len = (&cert->subject)->len;
1675         id.name.ptr = temporary_cyclic_buffer();
1676         memcpy(id.name.ptr, cert->subject.ptr, cert->subject.len);
1677         idtoa(&id, buf, IDTOA_BUF);
1678
1679         log("  Certificate DN: %s", buf);
1680         log("  valid from: %s", timetoa(&cert->notBefore, TRUE)); 
1681         log("          to: %s", timetoa(&cert->notAfter, TRUE));
1682         }
1683 #endif
1684 #undef DNDEBUG
1685     DBG(DBG_PARSING,
1686         DBG_log("  not before  : %s", timetoa(&cert->notBefore, TRUE));
1687         DBG_log("  current time: %s", timetoa(&current_time, TRUE));
1688         DBG_log("  not after   : %s", timetoa(&cert->notAfter, TRUE));
1689     )
1690
1691    return (current_time >= cert->notBefore) &&
1692           (current_time <= cert->notAfter);
1693 }
1694
1695
1696 /*
1697  *  compute a digest over a binary blob
1698  */
1699 static bool
1700 compute_digest(chunk_t tbs, int alg, chunk_t *digest)
1701 {
1702     switch (alg)
1703     {
1704         case OID_MD2:
1705         case OID_MD2_WITH_RSA:
1706         {
1707             MD2_CTX context;
1708             MD2Init(&context);
1709             MD2Update(&context, tbs.ptr, tbs.len);
1710             MD2Final(digest->ptr, &context);
1711             digest->len = MD2_DIGEST_SIZE;
1712             return TRUE;
1713         }
1714         case OID_MD5:
1715         case OID_MD5_WITH_RSA:
1716         {
1717             MD5_CTX context;
1718             MD5Init(&context);
1719             MD5Update(&context, tbs.ptr, tbs.len);
1720             MD5Final(digest->ptr, &context);
1721             digest->len = MD5_DIGEST_SIZE;
1722             return TRUE;
1723         }
1724         case OID_SHA1:
1725         case OID_SHA1_WITH_RSA:
1726         {
1727             SHA1_CTX context;
1728             SHA1Init(&context);
1729             SHA1Update(&context, tbs.ptr, tbs.len);
1730             SHA1Final(digest->ptr, &context);
1731             digest->len = SHA1_DIGEST_SIZE;
1732             return TRUE;
1733         }
1734         default:
1735             digest->len = 0;
1736             return FALSE;
1737     }
1738 }
1739
1740 /*
1741  *  decrypts an RSA signature using the issuer's certificate
1742  */
1743 static bool
1744 decrypt_sig(chunk_t sig, int alg, const x509cert_t *issuer_cert,
1745             chunk_t *digest)
1746 {
1747     switch (alg)
1748     {
1749         chunk_t decrypted;
1750         case OID_RSA_ENCRYPTION:
1751         case OID_MD2_WITH_RSA:
1752         case OID_MD5_WITH_RSA:
1753         case OID_SHA1_WITH_RSA:
1754         case OID_SHA256_WITH_RSA:
1755         case OID_SHA384_WITH_RSA:
1756         case OID_SHA512_WITH_RSA:
1757         {
1758             mpz_t s;
1759             mpz_t e;
1760             mpz_t n;
1761
1762             n_to_mpz(s, sig.ptr, sig.len);
1763             n_to_mpz(e, issuer_cert->publicExponent.ptr,
1764                         issuer_cert->publicExponent.len);
1765             n_to_mpz(n, issuer_cert->modulus.ptr,
1766                         issuer_cert->modulus.len);
1767
1768             /* decrypt the signature s = s^e mod n */
1769             mpz_powm(s, s, e, n);
1770             /* convert back to bytes */
1771             decrypted = mpz_to_n(s, issuer_cert->modulus.len);
1772             DBG(DBG_PARSING,
1773                 DBG_dump_chunk("  decrypted signature: ", decrypted)
1774             )
1775
1776             /*  copy the least significant bits of decrypted signature
1777              *  into the digest string
1778             */
1779             memcpy(digest->ptr, decrypted.ptr + decrypted.len - digest->len,
1780                    digest->len);
1781
1782             /* free memory */
1783             pfree(decrypted.ptr);
1784             mpz_clear(s);
1785             mpz_clear(e);
1786             mpz_clear(n);
1787             return TRUE;
1788         }
1789         default:
1790             digest->len = 0;
1791             return FALSE;
1792     }
1793 }
1794
1795 /*
1796  *   Check if a signature over binary blob is genuine
1797  */
1798 static bool
1799 check_signature(chunk_t tbs, chunk_t sig, chunk_t algorithm,
1800                 const x509cert_t *issuer_cert)
1801 {
1802     u_char digest_buf[MAX_DIGEST_LEN];
1803     u_char decrypted_buf[MAX_DIGEST_LEN];
1804     chunk_t digest = {digest_buf, MAX_DIGEST_LEN};
1805     chunk_t decrypted = {decrypted_buf, MAX_DIGEST_LEN};
1806
1807     int alg = known_oid(algorithm);
1808
1809     if (alg != -1)
1810     {
1811         DBG(DBG_PARSING,
1812             DBG_log("Signature Algorithm: '%s'",oid_names[alg].name);
1813         )
1814     }
1815     else
1816     {
1817         u_char buf[BUF_LEN];
1818         chunk_t hex_oid = {buf, BUF_LEN};
1819         DBG(DBG_PARSING,
1820             hex_str(hex_oid, &algorithm);
1821             DBG_log("Signature Algorithm: '%s'", hex_oid.ptr);
1822         )
1823     }
1824
1825     if (!compute_digest(tbs, alg, &digest))
1826     {
1827         log("  digest algorithm not supported");
1828         return FALSE;
1829     }
1830
1831     DBG(DBG_PARSING,
1832         DBG_dump_chunk("  digest:", digest)
1833     )
1834
1835     decrypted.len = digest.len; /* we want the same digest length */
1836
1837     if (!decrypt_sig(sig, alg, issuer_cert, &decrypted))
1838     {
1839         log("  decryption algorithm not supported");
1840         return FALSE;
1841     }
1842
1843     /* check if digests are equal */
1844     return !memcmp(decrypted.ptr, digest.ptr, digest.len);
1845 }
1846
1847 /*  Checks if the current certificate is revoked. It goes through the
1848  *  list of revoked certificates of the corresponding crl. If the
1849  *  certificate is not found in the list, then the certificate is valid
1850  *  and FALSE is returned.
1851  */
1852 static bool
1853 check_crl(const x509crl_t *crl, chunk_t serial)
1854 {
1855     revokedCert_t *revokedCert = crl->revokedCertificates;
1856     time_t current_time;
1857
1858     time(&current_time);
1859     DBG(DBG_PARSING,
1860         DBG_log("Next CRL update:");
1861         DBG_log("  this update : %s", timetoa(&crl->thisUpdate, TRUE));
1862         DBG_log("  current time: %s", timetoa(&current_time, TRUE));
1863         DBG_log("  next update : %s", timetoa(&crl->nextUpdate, TRUE));
1864     )
1865     if (current_time > crl->nextUpdate)
1866         log("Next CRL update was expected on %s",
1867                 timetoa(&crl->nextUpdate, TRUE));
1868
1869     DBG(DBG_PARSING,
1870         DBG_dump_chunk("Serial number:", serial)
1871     )
1872
1873     while(revokedCert != NULL)
1874     {
1875         /* compare serial numbers */
1876         if (revokedCert->userCertificate.len == serial.len &&
1877             memcmp(revokedCert->userCertificate.ptr, serial.ptr, serial.len) == 0)
1878         {
1879             log("Revocation date: %s",
1880                 timetoa(&revokedCert->revocationDate, TRUE));
1881             return TRUE;
1882         }
1883         revokedCert = revokedCert->next;
1884     }
1885     return FALSE;
1886 }
1887
1888
1889 /*
1890  *  verifies a X.509 certificate
1891  */
1892 bool
1893 verify_x509cert(const x509cert_t *cert){
1894
1895     int pathlen;
1896
1897     if (same_dn(cert->issuer, cert->subject))
1898     {
1899         log("end certificate with identical subject and issuer not accepted");
1900         return FALSE;
1901     }
1902
1903     for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
1904     {
1905         u_char buf[BUF_LEN];
1906         x509cert_t *issuer_cert;
1907         x509crl_t  *crl;
1908
1909         DBG(DBG_PARSING,
1910             dntoa(buf, BUF_LEN, cert->subject);
1911             DBG_log("Subject: '%s'",buf);
1912         )
1913         if (!check_validity(cert))
1914         {
1915             log("Certificate is invalid");
1916             return FALSE;
1917         }
1918         DBG(DBG_PARSING,
1919             DBG_log("  certificate is valid")
1920         )
1921
1922         DBG(DBG_PARSING,
1923             dntoa(buf, BUF_LEN, cert->issuer);
1924             DBG_log("Issuer: '%s'",buf);
1925         )
1926
1927         issuer_cert = get_x509cacert(cert->issuer);
1928
1929         if (issuer_cert == NULL)
1930         {
1931             log("Issuer CA certificate not found");
1932             return FALSE;
1933         }
1934         DBG(DBG_PARSING,
1935             DBG_log("  issuer CA certificate found")
1936         )
1937
1938         if (!check_signature(cert->tbsCertificate, cert->signature,
1939                              cert->algorithm, issuer_cert))
1940         {
1941             log("Certificate signature is invalid");
1942             return FALSE;
1943         }
1944         DBG(DBG_PARSING,
1945             DBG_log("  certificate signature is valid")
1946         )
1947
1948         crl = get_x509crl(cert->issuer);
1949
1950         if (crl == NULL)
1951         {
1952             log("Issuer CRL not found");
1953         }
1954         else
1955         {
1956             DBG(DBG_PARSING,
1957                 DBG_log("  issuer CRL found")
1958             )
1959             if (check_signature(crl->tbsCertList, crl->signature,
1960                                 crl->algorithm, issuer_cert))
1961             {
1962                 DBG(DBG_PARSING,
1963                     DBG_log("  CRL signature is valid")
1964                 )
1965
1966                 if (check_crl(crl, cert->serialNumber))
1967                 {
1968                     log("Certificate has been revoked");
1969                     remove_x509_public_key(cert);
1970                     return FALSE;
1971                 }
1972                 DBG(DBG_PARSING,
1973                     DBG_log("  certificate not revoked")
1974                 )
1975             }
1976             else
1977             {
1978                 log("CRL signature is invalid");
1979             }
1980         }
1981         /* check if cert is a self-signed root ca */
1982         if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
1983         {
1984             DBG(DBG_CONTROL,
1985                 DBG_log("reached self-signed root ca")
1986             )
1987             return TRUE;
1988         }
1989         /* otherwise go up one step in the trust chain */
1990         cert = issuer_cert;
1991     }
1992     
1993     log("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
1994     return FALSE;
1995 }
1996
1997 /*
1998  *  list all certs in a chained list
1999  */
2000 static void
2001 list_cert_chain(const char * caption, x509cert_t* cert, bool utc)
2002 {
2003     time_t now;
2004
2005     /* determine the current time */
2006     time(&now);
2007
2008     whack_log(RC_COMMENT, " ");
2009     whack_log(RC_COMMENT, "List of %s:", caption);
2010     whack_log(RC_COMMENT, " ");
2011
2012     while (cert != NULL)
2013     {
2014         u_char buf[BUF_LEN];
2015
2016         whack_log(RC_COMMENT, "%s, count: %d", timetoa(&cert->installed, utc), cert->count);
2017         dntoa(buf, BUF_LEN, cert->subject);
2018         whack_log(RC_COMMENT, "       subject: '%s'", buf);
2019         dntoa(buf, BUF_LEN, cert->issuer);
2020         whack_log(RC_COMMENT, "       issuer:  '%s'", buf);
2021         whack_log(RC_COMMENT, "       validity: not before %s %s",
2022                 timetoa(&cert->notBefore, utc),
2023                 (cert->notBefore < now)?"ok":"fatal (not valid yet)");
2024         whack_log(RC_COMMENT, "                 not after  %s %s",
2025                 timetoa(&cert->notAfter, utc),
2026                 check_expiry(cert->notAfter, CA_CERT_WARNING_INTERVAL, TRUE));
2027         cert = cert->next;
2028     }
2029 }
2030
2031 /*
2032  *  list all user/host certs in a chained list
2033  */
2034 void
2035 list_certs(bool utc)
2036 {
2037     list_cert_chain("User/Host Certificates", x509certs, utc);
2038 }
2039
2040 /*
2041  *  list all user/host certs in a chained list
2042  */
2043 void
2044 list_cacerts(bool utc)
2045 {
2046     list_cert_chain("CA Certificates", x509cacerts, utc);
2047 }
2048
2049 /*
2050  *  list all crls in the chained list
2051  */
2052 void
2053 list_crls(bool utc)
2054 {
2055     const bool strict = FALSE; /*expiry of CRL is non-fatal */
2056
2057     x509crl_t* crl = x509crls;
2058
2059     whack_log(RC_COMMENT, " ");
2060     whack_log(RC_COMMENT, "List of CRLs:");
2061     whack_log(RC_COMMENT, " ");
2062
2063     while (crl != NULL)
2064     {
2065         u_char buf[BUF_LEN];
2066         u_int revoked = 0;
2067         revokedCert_t *revokedCert = crl->revokedCertificates;
2068
2069         /* count number of revoked certificates in CRL */
2070         while (revokedCert != NULL)
2071         {
2072             revoked++;
2073             revokedCert = revokedCert->next;
2074         }
2075
2076         whack_log(RC_COMMENT, "%s, revoked certs: %d",
2077                 timetoa(&crl->installed, utc), revoked);
2078         dntoa(buf, BUF_LEN, crl->issuer);
2079         whack_log(RC_COMMENT, "       issuer:  '%s'", buf);
2080         whack_log(RC_COMMENT, "       updates:  this %s",
2081                 timetoa(&crl->thisUpdate, utc));
2082         whack_log(RC_COMMENT, "                 next %s %s",
2083                 timetoa(&crl->nextUpdate, utc),
2084                 check_expiry(crl->nextUpdate, CRL_WARNING_INTERVAL, strict));
2085         crl = crl->next;
2086     }
2087 }