Fixed pluto certificate parsing
[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
24 #include <freeswan.h>
25
26 #include <library.h>
27 #include <credentials/certificates/certificate.h>
28
29 #include "constants.h"
30 #include "defs.h"
31 #include "log.h"
32 #include "id.h"
33 #include "certs.h"
34 #include "ac.h"
35 #include "crl.h"
36
37 /**
38 * Load a certificate
39 */
40 static cert_t *builder_load_cert(certificate_type_t type, va_list args)
41 {
42 chunk_t blob = chunk_empty;
43 bool pgp = FALSE;
44
45 while (TRUE)
46 {
47 switch (va_arg(args, builder_part_t))
48 {
49 case BUILD_BLOB_PGP:
50 pgp = TRUE;
51 /* FALL */
52 case BUILD_BLOB_ASN1_DER:
53 blob = va_arg(args, chunk_t);
54 continue;
55 case BUILD_END:
56 break;
57 default:
58 return NULL;
59 }
60 break;
61 }
62 if (blob.ptr)
63 {
64 if (pgp)
65 {
66 pgpcert_t *pgpcert = malloc_thing(pgpcert_t);
67 *pgpcert = pgpcert_empty;
68 if (parse_pgp(chunk_clone(blob), pgpcert))
69 {
70 cert_t *cert = malloc_thing(cert_t);
71 *cert = cert_empty;
72 cert->type = CERT_PGP;
73 cert->u.pgp = pgpcert;
74 return cert;
75 }
76 plog(" error in OpenPGP certificate");
77 free_pgpcert(pgpcert);
78 }
79 else
80 {
81 x509cert_t *x509cert = malloc_thing(x509cert_t);
82 *x509cert = empty_x509cert;
83 if (parse_x509cert(chunk_clone(blob), 0, x509cert))
84 {
85 cert_t *cert = malloc_thing(cert_t);
86 *cert = cert_empty;
87 cert->type = CERT_X509_SIGNATURE;
88 cert->u.x509 = x509cert;
89 return cert;
90 }
91 plog(" error in X.509 certificate");
92 free_x509cert(x509cert);
93 }
94 }
95 return NULL;
96 }
97
98 /**
99 * Load a attribute certificate
100 */
101 static x509acert_t *builder_load_ac(certificate_type_t type, va_list args)
102 {
103 chunk_t blob = chunk_empty;
104 x509acert_t *ac;
105
106 while (TRUE)
107 {
108 switch (va_arg(args, builder_part_t))
109 {
110 case BUILD_BLOB_ASN1_DER:
111 blob = va_arg(args, chunk_t);
112 continue;
113 case BUILD_END:
114 break;
115 default:
116 return NULL;
117 }
118 break;
119 }
120 if (blob.ptr)
121 {
122 ac = malloc_thing(x509acert_t);
123 *ac = empty_ac;
124 if (parse_ac(chunk_clone(blob), ac) &&
125 verify_x509acert(ac, FALSE))
126 {
127 return ac;
128 }
129 plog(" error in X.509 AC");
130 free_acert(ac);
131 }
132 return NULL;
133 }
134
135 /**
136 * Load a CRL
137 */
138 static x509crl_t *builder_load_crl(certificate_type_t type, va_list args)
139 {
140 chunk_t blob = chunk_empty;
141 x509crl_t *crl;
142
143 while (TRUE)
144 {
145 switch (va_arg(args, builder_part_t))
146 {
147 case BUILD_BLOB_ASN1_DER:
148 blob = va_arg(args, chunk_t);
149 continue;
150 case BUILD_END:
151 break;
152 default:
153 return NULL;
154 }
155 break;
156 }
157 if (blob.ptr)
158 {
159 crl = malloc_thing(x509crl_t);
160 *crl = empty_x509crl;
161 if (parse_x509crl(chunk_clone(blob), 0, crl))
162 {
163 return crl;
164 }
165 plog(" error in X.509 crl");
166 free_crl(crl);
167 }
168 return NULL;
169 }
170
171 void init_builder(void)
172 {
173 lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CERT,
174 (builder_function_t)builder_load_cert);
175 lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_AC,
176 (builder_function_t)builder_load_ac);
177 lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CRL,
178 (builder_function_t)builder_load_crl);
179 }
180
181 void free_builder(void)
182 {
183 lib->creds->remove_builder(lib->creds, (builder_function_t)builder_load_cert);
184 lib->creds->remove_builder(lib->creds, (builder_function_t)builder_load_ac);
185 lib->creds->remove_builder(lib->creds, (builder_function_t)builder_load_crl);
186 }
187