]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
Moved debug.[ch] to utils folder
[thirdparty/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 <utils/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 || oid == OID_RSAES_OAEP)
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 DBG2(DBG_ASN, "-- > --");
85 key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, type,
86 BUILD_BLOB_ASN1_DER, object, BUILD_END);
87 DBG2(DBG_ASN, "-- < --");
88 break;
89 }
90 }
91
92 end:
93 parser->destroy(parser);
94 return key;
95 }
96
97 /**
98 * ASN.1 definition of RSApublicKey
99 */
100 static const asn1Object_t pubkeyObjects[] = {
101 { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
102 { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
103 { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
104 { 0, "exit", ASN1_EOC, ASN1_EXIT }
105 };
106 #define PUB_KEY_RSA_PUBLIC_KEY 0
107 #define PUB_KEY_MODULUS 1
108 #define PUB_KEY_EXPONENT 2
109
110 /**
111 * Load a RSA public key from an ASN.1 encoded blob.
112 */
113 static public_key_t *parse_rsa_public_key(chunk_t blob)
114 {
115 chunk_t n, e;
116 asn1_parser_t *parser;
117 chunk_t object;
118 int objectID;
119 bool success = FALSE;
120
121 parser = asn1_parser_create(pubkeyObjects, blob);
122
123 while (parser->iterate(parser, &objectID, &object))
124 {
125 switch (objectID)
126 {
127 case PUB_KEY_MODULUS:
128 n = object;
129 break;
130 case PUB_KEY_EXPONENT:
131 e = object;
132 break;
133 }
134 }
135 success = parser->success(parser);
136 parser->destroy(parser);
137
138 if (!success)
139 {
140 return NULL;
141 }
142 return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
143 BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END);
144 }
145
146 /**
147 * ASN.1 definition of a PKCS#1 RSA private key
148 */
149 static const asn1Object_t privkeyObjects[] = {
150 { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
151 { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
152 { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
153 { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
154 { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
155 { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
156 { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
157 { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
158 { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
159 { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
160 { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
161 ASN1_LOOP }, /* 10 */
162 { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
163 { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
164 { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
165 { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
166 { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 15 */
167 { 0, "exit", ASN1_EOC, ASN1_EXIT }
168 };
169 #define PRIV_KEY_VERSION 1
170 #define PRIV_KEY_MODULUS 2
171 #define PRIV_KEY_PUB_EXP 3
172 #define PRIV_KEY_PRIV_EXP 4
173 #define PRIV_KEY_PRIME1 5
174 #define PRIV_KEY_PRIME2 6
175 #define PRIV_KEY_EXP1 7
176 #define PRIV_KEY_EXP2 8
177 #define PRIV_KEY_COEFF 9
178
179 /**
180 * Load a RSA private key from a ASN1 encoded blob.
181 */
182 static private_key_t *parse_rsa_private_key(chunk_t blob)
183 {
184 chunk_t n, e, d, p, q, exp1, exp2, coeff;
185 asn1_parser_t *parser;
186 chunk_t object;
187 int objectID ;
188 bool success = FALSE;
189
190 parser = asn1_parser_create(privkeyObjects, blob);
191 parser->set_flags(parser, FALSE, TRUE);
192
193 while (parser->iterate(parser, &objectID, &object))
194 {
195 switch (objectID)
196 {
197 case PRIV_KEY_VERSION:
198 if (object.len > 0 && *object.ptr != 0)
199 {
200 DBG1(DBG_ASN, "PKCS#1 private key format is not version 1");
201 goto end;
202 }
203 break;
204 case PRIV_KEY_MODULUS:
205 n = object;
206 break;
207 case PRIV_KEY_PUB_EXP:
208 e = object;
209 break;
210 case PRIV_KEY_PRIV_EXP:
211 d = object;
212 break;
213 case PRIV_KEY_PRIME1:
214 p = object;
215 break;
216 case PRIV_KEY_PRIME2:
217 q = object;
218 break;
219 case PRIV_KEY_EXP1:
220 exp1 = object;
221 break;
222 case PRIV_KEY_EXP2:
223 exp2 = object;
224 break;
225 case PRIV_KEY_COEFF:
226 coeff = object;
227 break;
228 }
229 }
230 success = parser->success(parser);
231
232 end:
233 parser->destroy(parser);
234 if (!success)
235 {
236 return NULL;
237 }
238 return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
239 BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_RSA_PRIV_EXP, d,
240 BUILD_RSA_PRIME1, p, BUILD_RSA_PRIME2, q, BUILD_RSA_EXP1, exp1,
241 BUILD_RSA_EXP2, exp2, BUILD_RSA_COEFF, coeff, BUILD_END);
242 }
243
244 /**
245 * See header.
246 */
247 public_key_t *pkcs1_public_key_load(key_type_t type, va_list args)
248 {
249 chunk_t blob = chunk_empty;
250
251 while (TRUE)
252 {
253 switch (va_arg(args, builder_part_t))
254 {
255 case BUILD_BLOB_ASN1_DER:
256 blob = va_arg(args, chunk_t);
257 continue;
258 case BUILD_END:
259 break;
260 default:
261 return NULL;
262 }
263 break;
264 }
265 switch (type)
266 {
267 case KEY_ANY:
268 return parse_public_key(blob);
269 case KEY_RSA:
270 return parse_rsa_public_key(blob);
271 default:
272 return NULL;
273 }
274 }
275
276 /**
277 * See header.
278 */
279 private_key_t *pkcs1_private_key_load(key_type_t type, va_list args)
280 {
281 chunk_t blob = chunk_empty;
282
283 while (TRUE)
284 {
285 switch (va_arg(args, builder_part_t))
286 {
287 case BUILD_BLOB_ASN1_DER:
288 blob = va_arg(args, chunk_t);
289 continue;
290 case BUILD_END:
291 break;
292 default:
293 return NULL;
294 }
295 break;
296 }
297 return parse_rsa_private_key(blob);
298 }
299