0213076f93c304e4b3153b97dc83776bc7861989
[strongswan.git] / src / libstrongswan / plugins / pkcs1 / pkcs1_builder.c
1 /*
2 * Copyright (C) 2008-2009 Martin Willi
3 * Copyright (C) 2008 Tobias Brunner
4 * Copyright (C) 2000-2008 Andreas Steffen
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include "pkcs1_builder.h"
19
20 #include <debug.h>
21 #include <asn1/oid.h>
22 #include <asn1/asn1.h>
23 #include <asn1/asn1_parser.h>
24 #include <credentials/keys/private_key.h>
25
26 /**
27 * ASN.1 definition of a subjectPublicKeyInfo structure
28 */
29 static const asn1Object_t pkinfoObjects[] = {
30 { 0, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
31 { 1, "algorithm", ASN1_EOC, ASN1_RAW }, /* 1 */
32 { 1, "subjectPublicKey", ASN1_BIT_STRING, ASN1_BODY }, /* 2 */
33 { 0, "exit", ASN1_EOC, ASN1_EXIT }
34 };
35 #define PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM 1
36 #define PKINFO_SUBJECT_PUBLIC_KEY 2
37
38 /**
39 * Load a generic public key from an ASN.1 encoded blob
40 */
41 static public_key_t *parse_public_key(chunk_t blob)
42 {
43 asn1_parser_t *parser;
44 chunk_t object;
45 int objectID;
46 public_key_t *key = NULL;
47 key_type_t type = KEY_ANY;
48
49 parser = asn1_parser_create(pkinfoObjects, blob);
50
51 while (parser->iterate(parser, &objectID, &object))
52 {
53 switch (objectID)
54 {
55 case PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM:
56 {
57 int oid = asn1_parse_algorithmIdentifier(object,
58 parser->get_level(parser)+1, NULL);
59
60 if (oid == OID_RSA_ENCRYPTION)
61 {
62 type = KEY_RSA;
63 }
64 else if (oid == OID_EC_PUBLICKEY)
65 {
66 /* we need the whole subjectPublicKeyInfo for EC public keys */
67 key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
68 KEY_ECDSA, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
69 goto end;
70 }
71 else
72 {
73 /* key type not supported */
74 goto end;
75 }
76 break;
77 }
78 case PKINFO_SUBJECT_PUBLIC_KEY:
79 if (object.len > 0 && *object.ptr == 0x00)
80 {
81 /* skip initial bit string octet defining 0 unused bits */
82 object = chunk_skip(object, 1);
83 }
84 key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, type,
85 BUILD_BLOB_ASN1_DER, object, BUILD_END);
86 break;
87 }
88 }
89
90 end:
91 parser->destroy(parser);
92 return key;
93 }
94
95 /**
96 * ASN.1 definition of RSApublicKey
97 */
98 static const asn1Object_t pubkeyObjects[] = {
99 { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
100 { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
101 { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
102 { 0, "exit", ASN1_EOC, ASN1_EXIT }
103 };
104 #define PUB_KEY_RSA_PUBLIC_KEY 0
105 #define PUB_KEY_MODULUS 1
106 #define PUB_KEY_EXPONENT 2
107
108 /**
109 * Load a RSA public key from an ASN.1 encoded blob.
110 */
111 static public_key_t *parse_rsa_public_key(chunk_t blob)
112 {
113 chunk_t n, e;
114 asn1_parser_t *parser;
115 chunk_t object;
116 int objectID;
117 bool success = FALSE;
118
119 parser = asn1_parser_create(pubkeyObjects, blob);
120
121 while (parser->iterate(parser, &objectID, &object))
122 {
123 switch (objectID)
124 {
125 case PUB_KEY_MODULUS:
126 n = object;
127 break;
128 case PUB_KEY_EXPONENT:
129 e = object;
130 break;
131 }
132 }
133 success = parser->success(parser);
134 parser->destroy(parser);
135
136 if (!success)
137 {
138 return NULL;
139 }
140 return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
141 BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END);
142 }
143
144 /**
145 * ASN.1 definition of a PKCS#1 RSA private key
146 */
147 static const asn1Object_t privkeyObjects[] = {
148 { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
149 { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
150 { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
151 { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
152 { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
153 { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
154 { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
155 { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
156 { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
157 { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
158 { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
159 ASN1_LOOP }, /* 10 */
160 { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
161 { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
162 { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
163 { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
164 { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 15 */
165 { 0, "exit", ASN1_EOC, ASN1_EXIT }
166 };
167 #define PRIV_KEY_VERSION 1
168 #define PRIV_KEY_MODULUS 2
169 #define PRIV_KEY_PUB_EXP 3
170 #define PRIV_KEY_PRIV_EXP 4
171 #define PRIV_KEY_PRIME1 5
172 #define PRIV_KEY_PRIME2 6
173 #define PRIV_KEY_EXP1 7
174 #define PRIV_KEY_EXP2 8
175 #define PRIV_KEY_COEFF 9
176
177 /**
178 * Load a RSA private key from a ASN1 encoded blob.
179 */
180 static private_key_t *parse_rsa_private_key(chunk_t blob)
181 {
182 chunk_t n, e, d, p, q, exp1, exp2, coeff;
183 asn1_parser_t *parser;
184 chunk_t object;
185 int objectID ;
186 bool success = FALSE;
187
188 parser = asn1_parser_create(privkeyObjects, blob);
189 parser->set_flags(parser, FALSE, TRUE);
190
191 while (parser->iterate(parser, &objectID, &object))
192 {
193 switch (objectID)
194 {
195 case PRIV_KEY_VERSION:
196 if (object.len > 0 && *object.ptr != 0)
197 {
198 DBG1("PKCS#1 private key format is not version 1");
199 goto end;
200 }
201 break;
202 case PRIV_KEY_MODULUS:
203 n = object;
204 break;
205 case PRIV_KEY_PUB_EXP:
206 e = object;
207 break;
208 case PRIV_KEY_PRIV_EXP:
209 d = object;
210 break;
211 case PRIV_KEY_PRIME1:
212 p = object;
213 break;
214 case PRIV_KEY_PRIME2:
215 q = object;
216 break;
217 case PRIV_KEY_EXP1:
218 exp1 = object;
219 break;
220 case PRIV_KEY_EXP2:
221 exp2 = object;
222 break;
223 case PRIV_KEY_COEFF:
224 coeff = object;
225 break;
226 }
227 }
228 success = parser->success(parser);
229
230 end:
231 parser->destroy(parser);
232 if (!success)
233 {
234 return NULL;
235 }
236 return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
237 BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_RSA_PRIV_EXP, d,
238 BUILD_RSA_PRIME1, p, BUILD_RSA_PRIME2, q, BUILD_RSA_EXP1, exp1,
239 BUILD_RSA_EXP2, exp2, BUILD_RSA_COEFF, coeff, BUILD_END);
240 }
241
242 typedef struct private_builder_t private_builder_t;
243
244 /**
245 * Builder implementation for private/public key loading
246 */
247 struct private_builder_t {
248 /** implements the builder interface */
249 builder_t public;
250 /** asn1 der encoded data */
251 chunk_t blob;
252 /** type of key to build */
253 key_type_t type;
254 };
255
256 /**
257 * Implementation of builder_t.build for public keys
258 */
259 static public_key_t *build_public(private_builder_t *this)
260 {
261 public_key_t *key = NULL;
262
263 switch (this->type)
264 {
265 case KEY_ANY:
266 key = parse_public_key(this->blob);
267 break;
268 case KEY_RSA:
269 key = parse_rsa_public_key(this->blob);
270 break;
271 default:
272 break;
273 }
274 free(this);
275 return key;
276 }
277
278 /**
279 * Implementation of builder_t.add for public keys
280 */
281 static void add_public(private_builder_t *this, builder_part_t part, ...)
282 {
283 va_list args;
284
285 switch (part)
286 {
287 case BUILD_BLOB_ASN1_DER:
288 {
289 va_start(args, part);
290 this->blob = va_arg(args, chunk_t);
291 va_end(args);
292 break;
293 }
294 default:
295 builder_cancel(&this->public);
296 break;
297 }
298 }
299
300 /**
301 * Builder construction function for public keys
302 */
303 builder_t *pkcs1_public_key_builder(key_type_t type)
304 {
305 private_builder_t *this;
306
307 if (type != KEY_ANY && type != KEY_RSA)
308 {
309 return NULL;
310 }
311
312 this = malloc_thing(private_builder_t);
313
314 this->blob = chunk_empty;
315 this->type = type;
316 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add_public;
317 this->public.build = (void*(*)(builder_t *this))build_public;
318
319 return &this->public;
320 }
321
322 /**
323 * Implementation of builder_t.build for private keys
324 */
325 static private_key_t *build_private(private_builder_t *this)
326 {
327 private_key_t *key;
328
329 key = parse_rsa_private_key(this->blob);
330 free(this);
331 return key;
332 }
333
334 /**
335 * Implementation of builder_t.add for private keys
336 */
337 static void add_private(private_builder_t *this, builder_part_t part, ...)
338 {
339 va_list args;
340
341 switch (part)
342 {
343 case BUILD_BLOB_ASN1_DER:
344 {
345 va_start(args, part);
346 this->blob = va_arg(args, chunk_t);
347 va_end(args);
348 break;
349 }
350 default:
351 builder_cancel(&this->public);
352 break;
353 }
354 }
355
356 /**
357 * Builder construction function for private keys
358 */
359 builder_t *pkcs1_private_key_builder(key_type_t type)
360 {
361 private_builder_t *this;
362
363 if (type != KEY_RSA)
364 {
365 return NULL;
366 }
367
368 this = malloc_thing(private_builder_t);
369
370 this->blob = chunk_empty;
371 this->type = type;
372 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add_private;
373 this->public.build = (void*(*)(builder_t *this))build_private;
374
375 return &this->public;
376 }
377