pluto now uses x509 plugin for attribute certificate handling
[strongswan.git] / src / pluto / builder.c
1 /* Pluto certificate/CRL/AC builder hooks.
2 * Copyright (C) 2002-2009 Andreas Steffen
3 * Copyright (C) 2009 Martin Willi
4 * HSR Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "builder.h"
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <time.h>
24
25 #include <freeswan.h>
26
27 #include <library.h>
28 #include <credentials/certificates/certificate.h>
29
30 #include "constants.h"
31 #include "defs.h"
32 #include "log.h"
33 #include "id.h"
34 #include "certs.h"
35 #include "ac.h"
36 #include "crl.h"
37
38 /**
39 * Load a certificate
40 */
41 static cert_t *builder_load_cert(certificate_type_t type, va_list args)
42 {
43 x509_flag_t flags = 0;
44 chunk_t blob = chunk_empty;
45 bool pgp = FALSE;
46
47 while (TRUE)
48 {
49 switch (va_arg(args, builder_part_t))
50 {
51 case BUILD_BLOB_PGP:
52 pgp = TRUE;
53 /* FALL */
54 case BUILD_BLOB_ASN1_DER:
55 blob = va_arg(args, chunk_t);
56 continue;
57 case BUILD_X509_FLAG:
58 flags |= va_arg(args, x509_flag_t);
59 continue;
60 case BUILD_END:
61 break;
62 default:
63 return NULL;
64 }
65 break;
66 }
67 if (blob.ptr)
68 {
69 if (pgp)
70 {
71 pgpcert_t *pgpcert = malloc_thing(pgpcert_t);
72 *pgpcert = pgpcert_empty;
73 if (parse_pgp(chunk_clone(blob), pgpcert))
74 {
75 cert_t *cert = malloc_thing(cert_t);
76 *cert = cert_empty;
77 cert->type = CERT_PGP;
78 cert->u.pgp = pgpcert;
79 return cert;
80 }
81 plog(" error in OpenPGP certificate");
82 free_pgpcert(pgpcert);
83 }
84 else
85 {
86 x509cert_t *x509cert = malloc_thing(x509cert_t);
87
88 *x509cert = empty_x509cert;
89 x509cert->cert = lib->creds->create(lib->creds,
90 CRED_CERTIFICATE, CERT_X509,
91 BUILD_BLOB_ASN1_DER, blob,
92 BUILD_X509_FLAG, flags,
93 BUILD_END);
94 if (x509cert->cert)
95 {
96 cert_t *cert = malloc_thing(cert_t);
97
98 *cert = cert_empty;
99 cert->type = CERT_X509_SIGNATURE;
100 cert->u.x509 = x509cert;
101 time(&x509cert->installed);
102 return cert;
103 }
104 plog(" error in X.509 certificate");
105 free_x509cert(x509cert);
106 }
107 }
108 return NULL;
109 }
110
111 /**
112 * Load a attribute certificate
113 */
114 static x509acert_t *builder_load_ac(certificate_type_t type, va_list args)
115 {
116 chunk_t blob = chunk_empty;
117 x509acert_t *ac;
118
119 while (TRUE)
120 {
121 switch (va_arg(args, builder_part_t))
122 {
123 case BUILD_BLOB_ASN1_DER:
124 blob = va_arg(args, chunk_t);
125 continue;
126 case BUILD_END:
127 break;
128 default:
129 return NULL;
130 }
131 break;
132 }
133 if (blob.ptr)
134 {
135 ac = malloc_thing(x509acert_t);
136 ac->next = NULL;
137 ac->installed = UNDEFINED_TIME;
138 ac->ac = lib->creds->create(lib->creds,
139 CRED_CERTIFICATE, CERT_X509_AC,
140 BUILD_BLOB_ASN1_DER, blob, BUILD_END);
141 if (ac->ac && verify_x509acert(ac, FALSE))
142 {
143 return ac;
144 }
145 plog(" error in X.509 AC");
146 free_acert(ac);
147 }
148 return NULL;
149 }
150
151 /**
152 * Load a CRL
153 */
154 static x509crl_t *builder_load_crl(certificate_type_t type, va_list args)
155 {
156 chunk_t blob = chunk_empty;
157 x509crl_t *crl;
158
159 while (TRUE)
160 {
161 switch (va_arg(args, builder_part_t))
162 {
163 case BUILD_BLOB_ASN1_DER:
164 blob = va_arg(args, chunk_t);
165 continue;
166 case BUILD_END:
167 break;
168 default:
169 return NULL;
170 }
171 break;
172 }
173 if (blob.ptr)
174 {
175 crl = malloc_thing(x509crl_t);
176 *crl = empty_x509crl;
177 crl->distributionPoints = linked_list_create();
178
179 crl->crl = lib->creds->create(lib->creds,
180 CRED_CERTIFICATE, CERT_X509_CRL,
181 BUILD_BLOB_ASN1_DER, blob,
182 BUILD_END);
183 if (crl->crl)
184 {
185 return crl;
186 }
187 plog(" error in X.509 crl");
188 free_crl(crl);
189 }
190 return NULL;
191 }
192
193 void init_builder(void)
194 {
195 lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CERT,
196 (builder_function_t)builder_load_cert);
197 lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_AC,
198 (builder_function_t)builder_load_ac);
199 lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CRL,
200 (builder_function_t)builder_load_crl);
201 }
202
203 void free_builder(void)
204 {
205 lib->creds->remove_builder(lib->creds, (builder_function_t)builder_load_cert);
206 lib->creds->remove_builder(lib->creds, (builder_function_t)builder_load_ac);
207 lib->creds->remove_builder(lib->creds, (builder_function_t)builder_load_crl);
208 }
209