Register a certexpire listener collecting trustchain information
[strongswan.git] / src / libcharon / plugins / certexpire / certexpire_listener.c
1 /*
2 * Copyright (C) 2011 Martin Willi
3 * Copyright (C) 2011 revosec AG
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "certexpire_listener.h"
17
18 #include <daemon.h>
19
20 typedef struct private_certexpire_listener_t private_certexpire_listener_t;
21
22 /**
23 * Private data of an certexpire_listener_t object.
24 */
25 struct private_certexpire_listener_t {
26
27 /**
28 * Public certexpire_listener_t interface.
29 */
30 certexpire_listener_t public;
31 };
32
33 METHOD(listener_t, authorize, bool,
34 private_certexpire_listener_t *this, ike_sa_t *ike_sa,
35 bool final, bool *success)
36 {
37 enumerator_t *rounds, *enumerator;
38 certificate_t *cert, *ca = NULL;
39 linked_list_t *trustchain;
40 auth_cfg_t *auth;
41 auth_rule_t rule;
42
43 /* Check all rounds in final hook, as local authentication data are
44 * not completely available after round-invocation. */
45 if (!final)
46 {
47 return TRUE;
48 }
49
50 /* collect local certificates */
51 trustchain = linked_list_create();
52 rounds = ike_sa->create_auth_cfg_enumerator(ike_sa, TRUE);
53 while (rounds->enumerate(rounds, &auth))
54 {
55 cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
56 if (cert)
57 {
58 trustchain->insert_last(trustchain, cert);
59
60 enumerator = auth->create_enumerator(auth);
61 while (enumerator->enumerate(enumerator, &rule, &cert))
62 {
63 if (rule == AUTH_RULE_IM_CERT)
64 {
65 trustchain->insert_last(trustchain, cert);
66 }
67 if (rule == AUTH_RULE_CA_CERT)
68 {
69 /* the last CA cert is the one used in the trustchain.
70 * Previous CA certificates have been received as cert
71 * requests. */
72 ca = cert;
73 }
74 }
75 enumerator->destroy(enumerator);
76 if (ca)
77 {
78 trustchain->insert_last(trustchain, ca);
79 }
80 }
81 }
82 rounds->destroy(rounds);
83 /* TODO: handle trustchain expiry information */
84 trustchain->destroy(trustchain);
85
86 /* collect remote certificates */
87 trustchain = linked_list_create();
88 rounds = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE);
89 while (rounds->enumerate(rounds, &auth))
90 {
91 cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
92 if (cert)
93 {
94 trustchain->insert_last(trustchain, cert);
95
96 enumerator = auth->create_enumerator(auth);
97 while (enumerator->enumerate(enumerator, &rule, &cert))
98 {
99 if (rule == AUTH_RULE_IM_CERT)
100 {
101 trustchain->insert_last(trustchain, cert);
102 }
103 }
104 enumerator->destroy(enumerator);
105
106 cert = auth->get(auth, AUTH_RULE_CA_CERT);
107 if (cert)
108 {
109 trustchain->insert_last(trustchain, cert);
110 }
111 }
112 }
113 rounds->destroy(rounds);
114 /* TODO: handle trustchain expiry information */
115 trustchain->destroy(trustchain);
116 return TRUE;
117 }
118
119 METHOD(certexpire_listener_t, destroy, void,
120 private_certexpire_listener_t *this)
121 {
122 free(this);
123 }
124
125 /**
126 * See header
127 */
128 certexpire_listener_t *certexpire_listener_create()
129 {
130 private_certexpire_listener_t *this;
131
132 INIT(this,
133 .public = {
134 .listener = {
135 .authorize = _authorize,
136 },
137 .destroy = _destroy,
138 },
139 );
140
141 return &this->public;
142 }