load_private_key() loads all kinds of keys
[strongswan.git] / src / pluto / certs.c
1 /* Certificate support for IKE authentication
2 * Copyright (C) 2002-2009 Andreas Steffen
3 *
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 <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20
21 #include <freeswan.h>
22
23 #include "library.h"
24 #include "asn1/asn1.h"
25
26 #include "constants.h"
27 #include "defs.h"
28 #include "log.h"
29 #include "id.h"
30 #include "pem.h"
31 #include "certs.h"
32
33 /**
34 * used for initializatin of certs
35 */
36 const cert_t cert_empty = {CERT_NONE, {NULL}};
37
38 /**
39 * extracts the certificate to be sent to the peer
40 */
41 chunk_t cert_get_encoding(cert_t cert)
42 {
43 switch (cert.type)
44 {
45 case CERT_PGP:
46 return cert.u.pgp->certificate;
47 case CERT_X509_SIGNATURE:
48 return cert.u.x509->certificate;
49 default:
50 return chunk_empty;
51 }
52 }
53
54 public_key_t* cert_get_public_key(const cert_t cert)
55 {
56 switch (cert.type)
57 {
58 case CERT_PGP:
59 return cert.u.pgp->public_key;
60 break;
61 case CERT_X509_SIGNATURE:
62 return cert.u.x509->public_key;
63 break;
64 default:
65 return NULL;
66 }
67 }
68
69 /* load a coded key or certificate file with autodetection
70 * of binary DER or base64 PEM ASN.1 formats and armored PGP format
71 */
72 bool load_coded_file(char *filename, prompt_pass_t *pass, const char *type,
73 chunk_t *blob, bool *pgp)
74 {
75 err_t ugh = NULL;
76
77 FILE *fd = fopen(filename, "r");
78
79 if (fd)
80 {
81 int bytes;
82 fseek(fd, 0, SEEK_END );
83 blob->len = ftell(fd);
84 rewind(fd);
85 blob->ptr = malloc(blob->len);
86 bytes = fread(blob->ptr, 1, blob->len, fd);
87 fclose(fd);
88 plog(" loaded %s file '%s' (%d bytes)", type, filename, bytes);
89
90 *pgp = FALSE;
91
92 /* try DER format */
93 if (is_asn1(*blob))
94 {
95 DBG(DBG_PARSING,
96 DBG_log(" file coded in DER format");
97 )
98 return TRUE;
99 }
100
101 /* try PEM format */
102 ugh = pemtobin(blob, pass, filename, pgp);
103
104 if (ugh == NULL)
105 {
106 if (*pgp)
107 {
108 DBG(DBG_PARSING,
109 DBG_log(" file coded in armored PGP format");
110 )
111 return TRUE;
112 }
113 if (is_asn1(*blob))
114 {
115 DBG(DBG_PARSING,
116 DBG_log(" file coded in PEM format");
117 )
118 return TRUE;
119 }
120 ugh = "file coded in unknown format, discarded";
121 }
122
123 /* a conversion error has occured */
124 plog(" %s", ugh);
125 free(blob->ptr);
126 *blob = chunk_empty;
127 }
128 else
129 {
130 plog(" could not open %s file '%s'", type, filename);
131 }
132 return FALSE;
133 }
134
135 /**
136 * Loads a PKCS#1 or PGP privatekey file
137 */
138 private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
139 key_type_t type)
140 {
141 private_key_t *key = NULL;
142 chunk_t blob = chunk_empty;
143 bool pgp = FALSE;
144
145 char *path = concatenate_paths(PRIVATE_KEY_PATH, filename);
146
147 if (load_coded_file(path, pass, "private key", &blob, &pgp))
148 {
149 if (pgp)
150 {
151 parse_pgp(blob, NULL, &key);
152 }
153 else
154 {
155 key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
156 BUILD_BLOB_ASN1_DER, blob, BUILD_END);
157 }
158 if (key == NULL)
159 {
160 plog(" syntax error in %s private key file", pgp ? "PGP":"PKCS#");
161 }
162 free(blob.ptr);
163 }
164 else
165 {
166 plog(" error loading private key file");
167 }
168 return key;
169 }
170
171 /**
172 * Loads a X.509 or OpenPGP certificate
173 */
174 bool load_cert(char *filename, const char *label, cert_t *cert)
175 {
176 bool pgp = FALSE;
177 chunk_t blob = chunk_empty;
178
179 /* initialize cert struct */
180 cert->type = CERT_NONE;
181 cert->u.x509 = NULL;
182
183 if (load_coded_file(filename, NULL, label, &blob, &pgp))
184 {
185 if (pgp)
186 {
187 pgpcert_t *pgpcert = malloc_thing(pgpcert_t);
188 *pgpcert = pgpcert_empty;
189 if (parse_pgp(blob, pgpcert, NULL))
190 {
191 cert->type = CERT_PGP;
192 cert->u.pgp = pgpcert;
193 return TRUE;
194 }
195 else
196 {
197 plog(" error in OpenPGP certificate");
198 free_pgpcert(pgpcert);
199 return FALSE;
200 }
201 }
202 else
203 {
204 x509cert_t *x509cert = malloc_thing(x509cert_t);
205 *x509cert = empty_x509cert;
206 if (parse_x509cert(blob, 0, x509cert))
207 {
208 cert->type = CERT_X509_SIGNATURE;
209 cert->u.x509 = x509cert;
210 return TRUE;
211 }
212 else
213 {
214 plog(" error in X.509 certificate");
215 free_x509cert(x509cert);
216 return FALSE;
217 }
218 }
219 }
220 return FALSE;
221 }
222
223 /**
224 * Loads a host certificate
225 */
226 bool load_host_cert(char *filename, cert_t *cert)
227 {
228 char *path = concatenate_paths(HOST_CERT_PATH, filename);
229
230 return load_cert(path, "host cert", cert);
231 }
232
233 /**
234 * Loads a CA certificate
235 */
236 bool load_ca_cert(char *filename, cert_t *cert)
237 {
238 char *path = concatenate_paths(CA_CERT_PATH, filename);
239
240 return load_cert(path, "CA cert", cert);
241 }
242
243 /**
244 * establish equality of two certificates
245 */
246 bool same_cert(const cert_t *a, const cert_t *b)
247 {
248 return a->type == b->type && a->u.x509 == b->u.x509;
249 }
250
251 /**
252 * for each link pointing to the certificate increase the count by one
253 */
254 void share_cert(cert_t cert)
255 {
256 switch (cert.type)
257 {
258 case CERT_PGP:
259 share_pgpcert(cert.u.pgp);
260 break;
261 case CERT_X509_SIGNATURE:
262 share_x509cert(cert.u.x509);
263 break;
264 default:
265 break;
266 }
267 }
268
269 /* release of a certificate decreases the count by one
270 " the certificate is freed when the counter reaches zero
271 */
272 void
273 release_cert(cert_t cert)
274 {
275 switch (cert.type)
276 {
277 case CERT_PGP:
278 release_pgpcert(cert.u.pgp);
279 break;
280 case CERT_X509_SIGNATURE:
281 release_x509cert(cert.u.x509);
282 break;
283 default:
284 break;
285 }
286 }
287
288 /*
289 * list all X.509 and OpenPGP end certificates
290 */
291 void
292 list_certs(bool utc)
293 {
294 list_x509_end_certs(utc);
295 list_pgp_end_certs(utc);
296 }
297