1 diff --git a/src/pluto/ca.c b/src/pluto/ca.c
2 index 2f59a90..d9db082 100644
15 /* chained list of X.509 authority certificates (ca, aa, and ocsp) */
17 -static x509cert_t *x509authcerts = NULL;
18 +static linked_list_t *authcerts = NULL;
20 /* chained list of X.509 certification authority information records */
22 static ca_info_t *ca_infos = NULL;
25 + * Initialize the linked list of authority certificates
27 +void ca_initialize(void)
29 + authcerts = linked_list_create();
33 + * Free the linked list of authority certificates
35 +void ca_finalize(void)
37 + lock_authcert_list("free_authcerts");
38 + authcerts->destroy_offset(authcerts, offsetof(certificate_t, destroy));
39 + unlock_authcert_list("free_authcerts");
43 + * get a X.509 authority certificate with a given subject or keyid
45 +certificate_t* ca_get_cert(identification_t *subject, chunk_t keyid,
46 + x509_flag_t auth_flags)
48 + enumerator_t *enumerator;
49 + certificate_t *cert, *found = NULL;
51 + enumerator = authcerts->create_enumerator(authcerts);
52 + while (enumerator->enumerate(enumerator, &cert))
54 + x509_t *x509 = (x509_t*)cert;
56 + /* skip non-matching types of authority certificates */
57 + if (!(x509->get_flags(x509) & auth_flags))
62 + /* compare the keyid with the certificate's subjectKeyIdentifier */
65 + chunk_t subjectKeyId;
67 + subjectKeyId = x509->get_subjectKeyIdentifier(x509);
68 + if (subjectKeyId.ptr && !chunk_equals(keyid, subjectKeyId))
74 + /* compare the subjectDistinguishedNames */
75 + if (cert->has_subject(cert, subject))
81 + enumerator->destroy(enumerator);
86 + * Add an authority certificate to the chained list
88 +certificate_t* ca_add_cert(certificate_t *cert)
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);
95 + certificate_t *old_cert;
96 + enumerator_t *enumerator;
99 + lock_authcert_list("add_authcert");
101 + enumerator = acerts->create_enumerator(acerts);
102 + while (enumerator->enumerate(enumerator, &cert_old))
104 + x509_t *x509_old = (x509_t*)cert_old;
106 + /* skip non-matching types of authority certificates */
107 + if (!(x509_old->get_flags(x509_old) & flags))
112 + /* compare the keyid with the certificate's subjectKeyIdentifier */
115 + chunk_t subjectKeyId;
117 + subjectKeyId = x509_old->get_subjectKeyIdentifier(x509_old);
118 + if (subjectKeyId.ptr && !chunk_equals(keyid, subjectKeyId))
124 + /* compare the subjectDistinguishedNames */
125 + if (!cert_old->has_subject(cert_old, subject))
130 + if (cert->equals(cert, cert_old))
132 + DBG1(" authcert is already present and identical")
134 + cert->destroy(cert);
140 + authcerts->remove_at(authcerts, enumerator);
141 + DBG1(" existing authcert replaced");
145 + enumerator->destroy(enumerator);
149 + authcerts->insert_last(authcerts, cert);
151 + unlock_authcert_list("add_authcert");
157 + * Loads authority certificates
159 +void ca_load_authcerts(char *type, char *path, x509_flag_t auth_flags)
161 + enumerator_t *enumerator;
165 + DBG1("loading %s certificates from '%s'", type, path);
167 + enumerator = enumerator_create_directory(path);
170 + DBG1(" reading directory '%s' failed");
174 + while (enumerator->enumerate(enumerator, NULL, &file, &st))
178 + if (!S_ISREG(st.st_mode))
180 + /* skip special file */
183 + if (load_cert(file, type, auth_flags, &cert))
185 + add_authcert(cert.u.x509, auth_flags);
188 + enumerator->destroy(enumerator);
192 * Checks if CA a is trusted by CA b
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)
197 while ((*pathlen)++ < MAX_CA_PATH_LEN)
199 - certificate_t *certificate;
200 + certificate_t *cacert;
201 identification_t *issuer;
202 - x509cert_t *cacert;
204 - cacert = get_authcert(a, chunk_empty, X509_CA);
205 + cacert = ca_get_cert(a, chunk_empty, X509_CA);
210 - certificate = cacert->cert;
212 /* is the certificate self-signed? */
214 - x509_t *x509 = (x509_t*)certificate;
215 + x509_t *x509 = (x509_t*)cacert;
217 if (x509->get_flags(x509) & X509_SELF_SIGNED)
219 @@ -98,7 +262,7 @@ bool trusted_ca(identification_t *a, identification_t *b, int *pathlen)
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);
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)
233 - * does our CA match one of the requested CAs?
235 + * Does our CA match one of the requested CAs?
237 bool match_requested_ca(linked_list_t *requested_ca, identification_t *our_ca,
239 @@ -156,167 +320,6 @@ bool match_requested_ca(linked_list_t *requested_ca, identification_t *our_ca,
243 - * free the first authority certificate in the chain
245 -static void free_first_authcert(void)
247 - x509cert_t *first = x509authcerts;
248 - x509authcerts = first->next;
249 - free_x509cert(first);
253 - * free all CA certificates
255 -void free_authcerts(void)
257 - lock_authcert_list("free_authcerts");
259 - while (x509authcerts != NULL)
260 - free_first_authcert();
262 - unlock_authcert_list("free_authcerts");
266 - * get a X.509 authority certificate with a given subject or keyid
268 -x509cert_t* get_authcert(identification_t *subject, chunk_t keyid,
269 - x509_flag_t auth_flags)
271 - x509cert_t *cert, *prev_cert = NULL;
273 - /* the authority certificate list is empty */
274 - if (x509authcerts == NULL)
279 - for (cert = x509authcerts; cert != NULL; prev_cert = cert, cert = cert->next)
281 - certificate_t *certificate = cert->cert;
282 - x509_t *x509 = (x509_t*)certificate;
284 - /* skip non-matching types of authority certificates */
285 - if (!(x509->get_flags(x509) & auth_flags))
290 - /* compare the keyid with the certificate's subjectKeyIdentifier */
293 - chunk_t subjectKeyId;
295 - subjectKeyId = x509->get_subjectKeyIdentifier(x509);
296 - if (subjectKeyId.ptr && !chunk_equals(keyid, subjectKeyId))
302 - /* compare the subjectDistinguishedNames */
303 - if (!certificate->has_subject(certificate, subject))
308 - /* found the authcert */
309 - if (cert != x509authcerts)
311 - /* bring the certificate up front */
312 - prev_cert->next = cert->next;
313 - cert->next = x509authcerts;
314 - x509authcerts = cert;
322 - * add an authority certificate to the chained list
324 -x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags)
326 - certificate_t *certificate = cert->cert;
327 - x509_t *x509 = (x509_t*)certificate;
328 - x509cert_t *old_cert;
330 - lock_authcert_list("add_authcert");
332 - old_cert = get_authcert(certificate->get_subject(certificate),
333 - x509->get_subjectKeyIdentifier(x509),
337 - if (certificate->equals(certificate, old_cert->cert))
339 - DBG(DBG_CONTROL | DBG_PARSING ,
340 - DBG_log(" authcert is already present and identical")
342 - unlock_authcert_list("add_authcert");
344 - free_x509cert(cert);
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")
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")
364 - unlock_authcert_list("add_authcert");
369 - * Loads authority certificates
371 -void load_authcerts(char *type, char *path, x509_flag_t auth_flags)
373 - enumerator_t *enumerator;
377 - DBG1("loading %s certificates from '%s'", type, path);
379 - enumerator = enumerator_create_directory(path);
382 - DBG1(" reading directory '%s' failed");
386 - while (enumerator->enumerate(enumerator, NULL, &file, &st))
390 - if (!S_ISREG(st.st_mode))
392 - /* skip special file */
395 - if (load_cert(file, type, auth_flags, &cert))
397 - add_authcert(cert.u.x509, auth_flags);
400 - enumerator->destroy(enumerator);
404 * list all X.509 authcerts with given auth flags in a chained list
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.
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)
416 @@ -448,8 +451,8 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai
421 - * get a CA info record with a given authName or authKeyID
423 + * Get a CA info record with a given authName or authKeyID
425 ca_info_t* get_ca_info(identification_t *name, chunk_t keyid)
427 @@ -468,11 +471,10 @@ ca_info_t* get_ca_info(identification_t *name, chunk_t keyid)
432 - * free the dynamic memory used by a ca_info record
434 + * Free the dynamic memory used by a ca_info record
437 -free_ca_info(ca_info_t* ca_info)
438 +static void free_ca_info(ca_info_t* ca_info)
442 @@ -502,8 +504,8 @@ void free_ca_infos(void)
447 - * find a CA information record by name and optionally delete it
449 + * Find a CA information record by name and optionally delete it
451 bool find_ca_info_by_name(const char *name, bool delete)
453 @@ -531,7 +533,7 @@ bool find_ca_info_by_name(const char *name, bool delete)
459 * Create an empty ca_info_t record
461 ca_info_t* create_ca_info(void)
462 @@ -659,8 +661,8 @@ void add_ca_info(const whack_message_t *msg)
467 - * list all ca_info records in the chained list
469 + * List all ca_info records in the chained list
471 void list_ca_infos(bool utc)
473 diff --git a/src/pluto/ca.h b/src/pluto/ca.h
474 index 77dfe33..3b9e4c9 100644
479 #include <utils/linked_list.h>
480 #include <utils/identification.h>
481 +#include <credentials/certificates/certificate.h>
486 #define MAX_CA_PATH_LEN 7
487 @@ -39,17 +39,21 @@ struct ca_info {
488 bool strictcrlpolicy;
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);
496 +extern certificate_t* ca_add_cert(certificate_t *cert);
498 +extern certificate_t* ca_get_cert(identification_t *subject, chunk_t keyid,
499 + x509_flag_t auth_flags)
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)
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 */
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 */