Updated pkcs1 plugin to the new builder API
[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 /**
243 * See header.
244 */
245 public_key_t *pkcs1_public_key_load(key_type_t type, va_list args)
246 {
247 chunk_t blob = chunk_empty;
248
249 while (TRUE)
250 {
251 switch (va_arg(args, builder_part_t))
252 {
253 case BUILD_BLOB_ASN1_DER:
254 blob = va_arg(args, chunk_t);
255 continue;
256 case BUILD_END:
257 break;
258 default:
259 return NULL;
260 }
261 break;
262 }
263 switch (type)
264 {
265 case KEY_ANY:
266 return parse_public_key(blob);
267 case KEY_RSA:
268 return parse_rsa_public_key(blob);
269 default:
270 return NULL;
271 }
272 }
273
274 /**
275 * See header.
276 */
277 private_key_t *pkcs1_private_key_load(key_type_t type, va_list args)
278 {
279 chunk_t blob = chunk_empty;
280
281 while (TRUE)
282 {
283 switch (va_arg(args, builder_part_t))
284 {
285 case BUILD_BLOB_ASN1_DER:
286 blob = va_arg(args, chunk_t);
287 continue;
288 case BUILD_END:
289 break;
290 default:
291 return NULL;
292 }
293 break;
294 }
295 return parse_rsa_private_key(blob);
296 }
297