removed unwanted commits
[strongswan.git] / ca.diff
1 diff --git a/src/pluto/ca.c b/src/pluto/ca.c
2 index 2f59a90..d9db082 100644
3 --- a/src/pluto/ca.c
4 +++ b/src/pluto/ca.c
5 @@ -27,7 +27,6 @@
6  #include "constants.h"
7  #include "defs.h"
8  #include "log.h"
9 -#include "x509.h"
10  #include "ca.h"
11  #include "certs.h"
12  #include "whack.h"
13 @@ -36,13 +35,180 @@
14  
15  /* chained list of X.509 authority certificates (ca, aa, and ocsp) */
16  
17 -static x509cert_t *x509authcerts = NULL;
18 +static linked_list_t *authcerts = NULL;
19  
20  /* chained list of X.509 certification authority information records */
21  
22  static ca_info_t *ca_infos = NULL;
23  
24 +/**
25 + * Initialize the linked list of authority certificates
26 + */
27 +void ca_initialize(void)
28 +{
29 +       authcerts = linked_list_create();
30 +}
31 +
32 +/**
33 + * Free the linked list of authority certificates
34 + */
35 +void ca_finalize(void)
36 +{
37 +       lock_authcert_list("free_authcerts");
38 +       authcerts->destroy_offset(authcerts, offsetof(certificate_t, destroy));
39 +       unlock_authcert_list("free_authcerts");
40 +}
41 +
42  /*
43 + *  get a X.509 authority certificate with a given subject or keyid
44 + */
45 +certificate_t* ca_get_cert(identification_t *subject, chunk_t keyid,
46 +                                                  x509_flag_t auth_flags)
47 +{
48 +       enumerator_t *enumerator;
49 +       certificate_t *cert, *found = NULL;
50 +
51 +       enumerator = authcerts->create_enumerator(authcerts);
52 +       while (enumerator->enumerate(enumerator, &cert))
53 +       {
54 +               x509_t *x509 = (x509_t*)cert;
55 +
56 +               /* skip non-matching types of authority certificates */
57 +               if (!(x509->get_flags(x509) & auth_flags))
58 +               {
59 +                       continue;
60 +               }
61 +
62 +               /* compare the keyid with the certificate's subjectKeyIdentifier */
63 +               if (keyid.ptr)
64 +               {
65 +                       chunk_t subjectKeyId;
66 +
67 +                       subjectKeyId = x509->get_subjectKeyIdentifier(x509);
68 +                       if (subjectKeyId.ptr && !chunk_equals(keyid, subjectKeyId))
69 +                       {
70 +                               continue;
71 +                       }
72 +               }
73 +
74 +               /* compare the subjectDistinguishedNames */
75 +               if (cert->has_subject(cert, subject))
76 +               {
77 +                       found = cert;
78 +                       break;
79 +               }
80 +       }
81 +       enumerator->destroy(enumerator);
82 +       return found;
83 +}
84 +
85 +/**
86 + * Add an authority certificate to the chained list
87 + */
88 +certificate_t* ca_add_cert(certificate_t *cert)
89 +{
90 +       identification_t *subject = cert->get_subject(cert);
91 +       x509_t *x509 = (x509_t*)cert;
92 +       x509_flag_t flags = x509->get_flags(x509);
93 +       chunk_t keyid = x509->get_subjectKeyIdentifier(x509);
94 +
95 +       certificate_t *old_cert;
96 +       enumerator_t *enumerator;
97 +       bool add = TRUE;
98 +
99 +       lock_authcert_list("add_authcert");
100 +
101 +       enumerator = acerts->create_enumerator(acerts);
102 +       while (enumerator->enumerate(enumerator, &cert_old))
103 +       {
104 +               x509_t *x509_old = (x509_t*)cert_old;
105 +
106 +               /* skip non-matching types of authority certificates */
107 +               if (!(x509_old->get_flags(x509_old) & flags))
108 +               {
109 +                       continue;
110 +               }
111 +
112 +               /* compare the keyid with the certificate's subjectKeyIdentifier */
113 +               if (keyid.ptr)
114 +               {
115 +                       chunk_t subjectKeyId;
116 +
117 +                       subjectKeyId = x509_old->get_subjectKeyIdentifier(x509_old);
118 +                       if (subjectKeyId.ptr && !chunk_equals(keyid, subjectKeyId))
119 +                       {
120 +                               continue;
121 +                       }
122 +               }
123 +
124 +               /* compare the subjectDistinguishedNames */
125 +               if (!cert_old->has_subject(cert_old, subject))
126 +               {
127 +                       continue,
128 +               }
129 +
130 +               if (cert->equals(cert, cert_old))
131 +               {
132 +                       DBG1("  authcert is already present and identical")
133 +
134 +                       cert->destroy(cert);
135 +                       cert = cert_old;
136 +                       add = FALSE;
137 +               }
138 +               else
139 +               {
140 +                       authcerts->remove_at(authcerts, enumerator);
141 +                       DBG1("  existing authcert replaced");
142 +               }
143 +               break;
144 +       }
145 +       enumerator->destroy(enumerator);
146 +
147 +       if (add)
148 +       {
149 +               authcerts->insert_last(authcerts, cert);
150 +       }
151 +       unlock_authcert_list("add_authcert");
152 +
153 +       return cert;
154 +}
155 +
156 +/**
157 + *  Loads authority certificates
158 + */
159 +void ca_load_authcerts(char *type, char *path, x509_flag_t auth_flags)
160 +{
161 +       enumerator_t *enumerator;
162 +       struct stat st;
163 +       char *file;
164 +
165 +       DBG1("loading %s certificates from '%s'", type, path);
166 +
167 +       enumerator = enumerator_create_directory(path);
168 +       if (!enumerator)
169 +       {
170 +               DBG1("  reading directory '%s' failed");
171 +               return;
172 +       }
173 +
174 +       while (enumerator->enumerate(enumerator, NULL, &file, &st))
175 +       {
176 +               cert_t cert;
177 +
178 +               if (!S_ISREG(st.st_mode))
179 +               {
180 +                       /* skip special file */
181 +                       continue;
182 +               }
183 +               if (load_cert(file, type, auth_flags, &cert))
184 +               {
185 +                       add_authcert(cert.u.x509, auth_flags);
186 +               }
187 +       }
188 +       enumerator->destroy(enumerator);
189 +}
190 +
191 +/**
192   * Checks if CA a is trusted by CA b
193   */
194  bool trusted_ca(identification_t *a, identification_t *b, int *pathlen)
195 @@ -76,20 +242,18 @@ bool trusted_ca(identification_t *a, identification_t *b, int *pathlen)
196  
197         while ((*pathlen)++ < MAX_CA_PATH_LEN)
198         {
199 -               certificate_t *certificate;
200 +               certificate_t *cacert;
201                 identification_t *issuer;
202 -               x509cert_t *cacert;
203  
204 -               cacert = get_authcert(a, chunk_empty, X509_CA);
205 +               cacert = ca_get_cert(a, chunk_empty, X509_CA);
206                 if (cacert == NULL)
207                 {
208                         break;
209                 }
210 -               certificate = cacert->cert;
211                 
212                 /* is the certificate self-signed? */
213                 {
214 -                       x509_t *x509 = (x509_t*)certificate;
215 +                       x509_t *x509 = (x509_t*)cacert;
216  
217                         if (x509->get_flags(x509) & X509_SELF_SIGNED)
218                         {
219 @@ -98,7 +262,7 @@ bool trusted_ca(identification_t *a, identification_t *b, int *pathlen)
220                 }
221  
222                 /* does the issuer of CA a match CA b? */
223 -               issuer = certificate->get_issuer(certificate);
224 +               issuer = cert->get_issuer(cert);
225                 match = b->equals(b, issuer);
226  
227                 /* we have a match and exit the loop */
228 @@ -114,8 +278,8 @@ bool trusted_ca(identification_t *a, identification_t *b, int *pathlen)
229         return match;
230  }
231  
232 -/*
233 - * does our CA match one of the requested CAs?
234 +/**
235 + * Does our CA match one of the requested CAs?
236   */
237  bool match_requested_ca(linked_list_t *requested_ca, identification_t *our_ca,
238                                                 int *our_pathlen)
239 @@ -156,167 +320,6 @@ bool match_requested_ca(linked_list_t *requested_ca, identification_t *our_ca,
240  }
241  
242  /*
243 - *  free the first authority certificate in the chain
244 - */
245 -static void free_first_authcert(void)
246 -{
247 -       x509cert_t *first = x509authcerts;
248 -       x509authcerts = first->next;
249 -       free_x509cert(first);
250 -}
251 -
252 -/*
253 - *  free  all CA certificates
254 - */
255 -void free_authcerts(void)
256 -{
257 -       lock_authcert_list("free_authcerts");
258 -
259 -       while (x509authcerts != NULL)
260 -               free_first_authcert();
261 -
262 -       unlock_authcert_list("free_authcerts");
263 -}
264 -
265 -/*
266 - *  get a X.509 authority certificate with a given subject or keyid
267 - */
268 -x509cert_t* get_authcert(identification_t *subject, chunk_t keyid,
269 -                                                x509_flag_t auth_flags)
270 -{
271 -       x509cert_t *cert, *prev_cert = NULL;
272 -
273 -       /* the authority certificate list is empty */
274 -       if (x509authcerts == NULL)
275 -       {
276 -               return NULL;
277 -       }
278 -
279 -       for (cert = x509authcerts; cert != NULL; prev_cert = cert, cert = cert->next)
280 -       {
281 -               certificate_t *certificate = cert->cert;
282 -               x509_t *x509 = (x509_t*)certificate;
283 -
284 -               /* skip non-matching types of authority certificates */
285 -               if (!(x509->get_flags(x509) & auth_flags))
286 -               {
287 -                       continue;
288 -               }
289 -
290 -               /* compare the keyid with the certificate's subjectKeyIdentifier */
291 -               if (keyid.ptr)
292 -               {
293 -                       chunk_t subjectKeyId;
294 -
295 -                       subjectKeyId = x509->get_subjectKeyIdentifier(x509);
296 -                       if (subjectKeyId.ptr && !chunk_equals(keyid, subjectKeyId))
297 -                       {
298 -                               continue;
299 -                       }
300 -               }
301 -
302 -               /* compare the subjectDistinguishedNames */
303 -               if (!certificate->has_subject(certificate, subject))
304 -               {
305 -                       continue;
306 -               }
307 -
308 -               /* found the authcert */
309 -               if (cert != x509authcerts)
310 -               {
311 -                       /* bring the certificate up front */
312 -                       prev_cert->next = cert->next;
313 -                       cert->next = x509authcerts;
314 -                       x509authcerts = cert;
315 -               }
316 -               return cert;
317 -       }
318 -       return NULL;
319 -}
320 -
321 -/*
322 - * add an authority certificate to the chained list
323 - */
324 -x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags)
325 -{
326 -       certificate_t *certificate = cert->cert;
327 -       x509_t *x509 = (x509_t*)certificate;
328 -       x509cert_t *old_cert;
329 -
330 -       lock_authcert_list("add_authcert");
331 -
332 -       old_cert = get_authcert(certificate->get_subject(certificate), 
333 -                                                       x509->get_subjectKeyIdentifier(x509),
334 -                                                       auth_flags);
335 -       if (old_cert)
336 -       {
337 -               if (certificate->equals(certificate, old_cert->cert))
338 -               {
339 -                       DBG(DBG_CONTROL | DBG_PARSING ,
340 -                               DBG_log("  authcert is already present and identical")
341 -                       )
342 -                       unlock_authcert_list("add_authcert");
343 -
344 -                       free_x509cert(cert);
345 -                       return old_cert;
346 -               }
347 -               else
348 -               {
349 -                       /* cert is already present but will be replaced by new cert */
350 -                       free_first_authcert();
351 -                       DBG(DBG_CONTROL | DBG_PARSING ,
352 -                               DBG_log("  existing authcert deleted")
353 -                       )
354 -               }
355 -       }
356 -
357 -       /* add new authcert to chained list */
358 -       cert->next = x509authcerts;
359 -       x509authcerts = cert;
360 -       share_x509cert(cert);  /* set count to one */
361 -       DBG(DBG_CONTROL | DBG_PARSING,
362 -               DBG_log("  authcert inserted")
363 -       )
364 -       unlock_authcert_list("add_authcert");
365 -       return cert;
366 -}
367 -
368 -/*
369 - *  Loads authority certificates
370 - */
371 -void load_authcerts(char *type, char *path, x509_flag_t auth_flags)
372 -{
373 -       enumerator_t *enumerator;
374 -       struct stat st;
375 -       char *file;
376 -
377 -       DBG1("loading %s certificates from '%s'", type, path);
378 -
379 -       enumerator = enumerator_create_directory(path);
380 -       if (!enumerator)
381 -       {
382 -               DBG1("  reading directory '%s' failed");
383 -               return;
384 -       }
385 -
386 -       while (enumerator->enumerate(enumerator, NULL, &file, &st))
387 -       {
388 -               cert_t cert;
389 -
390 -               if (!S_ISREG(st.st_mode))
391 -               {
392 -                       /* skip special file */
393 -                       continue;
394 -               }
395 -               if (load_cert(file, type, auth_flags, &cert))
396 -               {
397 -                       add_authcert(cert.u.x509, auth_flags);
398 -               }
399 -       }
400 -       enumerator->destroy(enumerator);
401 -}
402 -
403 -/*
404   *  list all X.509 authcerts with given auth flags in a chained list
405   */
406  void list_authcerts(const char *caption, x509_flag_t auth_flags, bool utc)
407 @@ -368,7 +371,7 @@ static const x509cert_t* get_alt_cacert(identification_t *subject, chunk_t keyid
408  /* establish trust into a candidate authcert by going up the trust chain.
409   * validity and revocation status are not checked.
410   */
411 -bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
412 +bool trust_authcert_candidate(certificate_t *cert, linked_list_t *alt_chain)
413  {
414         int pathlen;
415  
416 @@ -448,8 +451,8 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai
417         return FALSE;
418  }
419  
420 -/*
421 - *  get a CA info record with a given authName or authKeyID
422 +/**
423 + *  Get a CA info record with a given authName or authKeyID
424   */
425  ca_info_t* get_ca_info(identification_t *name, chunk_t keyid)
426  {
427 @@ -468,11 +471,10 @@ ca_info_t* get_ca_info(identification_t *name, chunk_t keyid)
428  }
429  
430  
431 -/*
432 - *  free the dynamic memory used by a ca_info record
433 +/**
434 + *  Free the dynamic memory used by a ca_info record
435   */
436 -static void
437 -free_ca_info(ca_info_t* ca_info)
438 +static void free_ca_info(ca_info_t* ca_info)
439  {
440         if (ca_info == NULL)
441         {
442 @@ -502,8 +504,8 @@ void free_ca_infos(void)
443         }
444  }
445  
446 -/*
447 - * find a CA information record by name and optionally delete it
448 +/**
449 + * Find a CA information record by name and optionally delete it
450   */
451  bool find_ca_info_by_name(const char *name, bool delete)
452  {
453 @@ -531,7 +533,7 @@ bool find_ca_info_by_name(const char *name, bool delete)
454         return FALSE;
455  }
456  
457 -/*
458 +/**
459   * Create an empty ca_info_t record
460   */
461  ca_info_t* create_ca_info(void)
462 @@ -659,8 +661,8 @@ void add_ca_info(const whack_message_t *msg)
463         }
464  }
465  
466 -/*
467 - * list all ca_info records in the chained list
468 +/**
469 + * List all ca_info records in the chained list
470   */
471  void list_ca_infos(bool utc)
472  {
473 diff --git a/src/pluto/ca.h b/src/pluto/ca.h
474 index 77dfe33..3b9e4c9 100644
475 --- a/src/pluto/ca.h
476 +++ b/src/pluto/ca.h
477 @@ -17,8 +17,8 @@
478  
479  #include <utils/linked_list.h>
480  #include <utils/identification.h>
481 +#include <credentials/certificates/certificate.h>
482  
483 -#include "x509.h"
484  #include "whack.h"
485  
486  #define MAX_CA_PATH_LEN         7
487 @@ -39,17 +39,21 @@ struct ca_info {
488         bool              strictcrlpolicy;
489  };
490  
491 +extern void ca_initialize(void);
492 +extern void ca_finalize(void);
493 +extern void ca_load_certs(char *type, char *path, x509_flag_t auth_flags);
494 +extern void ca_list_certs(const char *caption, x509_flag_t auth_flags, bool utc);
495 +
496 +extern certificate_t* ca_add_cert(certificate_t *cert);
497 +
498 +extern certificate_t* ca_get_cert(identification_t *subject, chunk_t keyid,
499 +                                                                 x509_flag_t auth_flags)
500 +
501  extern bool trusted_ca(identification_t *a, identification_t *b, int *pathlen);
502  extern bool match_requested_ca(linked_list_t *requested_ca,
503                                                            identification_t *our_ca, int *our_pathlen);
504 -extern x509cert_t* get_authcert(identification_t *subject, chunk_t keyid,
505 -                                                               x509_flag_t auth_flags);
506 -extern void load_authcerts(char *type, char *path, x509_flag_t auth_flags);
507 -extern x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags);
508 -extern void free_authcerts(void);
509 -extern void list_authcerts(const char *caption, x509_flag_t auth_flags, bool utc);
510 -extern bool trust_authcert_candidate(const x509cert_t *cert,
511 -                                                                        const x509cert_t *alt_chain);
512 +extern bool trust_authcert_candidate(certificate_t *cert,
513 +                                                                        linked_list_t *alt_chain);
514  extern ca_info_t* get_ca_info(identification_t *name, chunk_t keyid);
515  extern bool find_ca_info_by_name(const char *name, bool delete);
516  extern void add_ca_info(const whack_message_t *msg);
517 diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c
518 index 0471d26..a9e3aa0 100644
519 --- a/src/pluto/plutomain.c
520 +++ b/src/pluto/plutomain.c
521 @@ -675,6 +675,7 @@ int main(int argc, char **argv)
522         init_adns();
523         init_myid();
524         init_fetch();
525 +       ca_initialize();
526         ac_initialize();
527  
528         /* drop unneeded capabilities and change UID/GID */
529 @@ -752,12 +753,12 @@ void exit_pluto(int status)
530         delete_every_connection();
531         free_crl_fetch();           /* free chain of crl fetch requests */
532         free_ocsp_fetch();          /* free chain of ocsp fetch requests */
533 -       free_authcerts();           /* free chain of X.509 authority certificates */
534         free_crls();                /* free chain of X.509 CRLs */
535         free_ca_infos();            /* free chain of X.509 CA information records */
536         free_ocsp();                /* free ocsp cache */
537         free_ifaces();
538         ac_finalize();              /* free X.509 attribute certificates */
539 +       ca_finalize();              /* free X.509 authority certificates */
540         scx_finalize();             /* finalize and unload PKCS #11 module */
541         xauth_finalize();           /* finalize and unload XAUTH module */
542         stop_adns();