Annotation of embedaddon/strongswan/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2008-2016 Tobias Brunner
3: * Copyright (C) 2008-2009 Martin Willi
4: * Copyright (C) 2000-2008 Andreas Steffen
5: * HSR 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: oid == OID_RSASSA_PSS)
62: {
63: /* TODO: we should parse parameters for PSS and pass them
64: * (and the type), or the complete subjectPublicKeyInfo,
65: * along so we can treat these as restrictions when
66: * generating signatures with the associated private key */
67: type = KEY_RSA;
68: }
69: else if (oid == OID_EC_PUBLICKEY)
70: {
71: /* Need the whole subjectPublicKeyInfo for EC public keys */
72: key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
73: KEY_ECDSA, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
74: goto end;
75: }
76: else if (oid == OID_BLISS_PUBLICKEY)
77: {
78: /* Need the whole subjectPublicKeyInfo for BLISS public keys */
79: key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
80: KEY_BLISS, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
81: goto end;
82: }
83: else if (oid == OID_ED25519)
84: {
85: /* Need the whole subjectPublicKeyInfo for Ed25519 public keys */
86: key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
87: KEY_ED25519, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
88: goto end;
89: }
90: else if (oid == OID_ED448)
91: {
92: /* Need the whole subjectPublicKeyInfo for Ed448 public keys */
93: key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
94: KEY_ED448, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
95: goto end;
96: }
97: else
98: {
99: /* key type not supported */
100: goto end;
101: }
102: break;
103: }
104: case PKINFO_SUBJECT_PUBLIC_KEY:
105: if (object.len > 0 && *object.ptr == 0x00)
106: {
107: /* skip initial bit string octet defining 0 unused bits */
108: object = chunk_skip(object, 1);
109: }
110: DBG2(DBG_ASN, "-- > --");
111: key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, type,
112: BUILD_BLOB_ASN1_DER, object, BUILD_END);
113: DBG2(DBG_ASN, "-- < --");
114: break;
115: }
116: }
117:
118: end:
119: parser->destroy(parser);
120: return key;
121: }
122:
123: /**
124: * ASN.1 definition of RSApublicKey
125: */
126: static const asn1Object_t pubkeyObjects[] = {
127: { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
128: { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
129: { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
130: { 0, "exit", ASN1_EOC, ASN1_EXIT }
131: };
132: #define PUB_KEY_RSA_PUBLIC_KEY 0
133: #define PUB_KEY_MODULUS 1
134: #define PUB_KEY_EXPONENT 2
135:
136: /**
137: * Load a RSA public key from an ASN.1 encoded blob.
138: */
139: static public_key_t *parse_rsa_public_key(chunk_t blob)
140: {
141: chunk_t n, e;
142: asn1_parser_t *parser;
143: chunk_t object;
144: int objectID;
145: bool success = FALSE;
146:
147: parser = asn1_parser_create(pubkeyObjects, blob);
148:
149: while (parser->iterate(parser, &objectID, &object))
150: {
151: switch (objectID)
152: {
153: case PUB_KEY_MODULUS:
154: n = object;
155: break;
156: case PUB_KEY_EXPONENT:
157: e = object;
158: break;
159: }
160: }
161: success = parser->success(parser);
162: parser->destroy(parser);
163:
164: if (!success)
165: {
166: return NULL;
167: }
168: return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
169: BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END);
170: }
171:
172: /**
173: * ASN.1 definition of a PKCS#1 RSA private key
174: */
175: static const asn1Object_t privkeyObjects[] = {
176: { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
177: { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
178: { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
179: { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
180: { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
181: { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
182: { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
183: { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
184: { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
185: { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
186: { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
187: ASN1_LOOP }, /* 10 */
188: { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
189: { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
190: { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
191: { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
192: { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 15 */
193: { 0, "exit", ASN1_EOC, ASN1_EXIT }
194: };
195: #define PRIV_KEY_VERSION 1
196: #define PRIV_KEY_MODULUS 2
197: #define PRIV_KEY_PUB_EXP 3
198: #define PRIV_KEY_PRIV_EXP 4
199: #define PRIV_KEY_PRIME1 5
200: #define PRIV_KEY_PRIME2 6
201: #define PRIV_KEY_EXP1 7
202: #define PRIV_KEY_EXP2 8
203: #define PRIV_KEY_COEFF 9
204:
205: /**
206: * Load a RSA private key from a ASN1 encoded blob.
207: */
208: static private_key_t *parse_rsa_private_key(chunk_t blob)
209: {
210: chunk_t n, e, d, p, q, exp1, exp2, coeff;
211: asn1_parser_t *parser;
212: chunk_t object;
213: int objectID ;
214: bool success = FALSE;
215:
216: parser = asn1_parser_create(privkeyObjects, blob);
217: parser->set_flags(parser, FALSE, TRUE);
218:
219: while (parser->iterate(parser, &objectID, &object))
220: {
221: switch (objectID)
222: {
223: case PRIV_KEY_VERSION:
224: if (object.len > 0 && *object.ptr != 0)
225: {
226: goto end;
227: }
228: break;
229: case PRIV_KEY_MODULUS:
230: n = object;
231: break;
232: case PRIV_KEY_PUB_EXP:
233: e = object;
234: break;
235: case PRIV_KEY_PRIV_EXP:
236: d = object;
237: break;
238: case PRIV_KEY_PRIME1:
239: p = object;
240: break;
241: case PRIV_KEY_PRIME2:
242: q = object;
243: break;
244: case PRIV_KEY_EXP1:
245: exp1 = object;
246: break;
247: case PRIV_KEY_EXP2:
248: exp2 = object;
249: break;
250: case PRIV_KEY_COEFF:
251: coeff = object;
252: break;
253: }
254: }
255: success = parser->success(parser);
256:
257: end:
258: parser->destroy(parser);
259: if (!success)
260: {
261: return NULL;
262: }
263: return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
264: BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_RSA_PRIV_EXP, d,
265: BUILD_RSA_PRIME1, p, BUILD_RSA_PRIME2, q, BUILD_RSA_EXP1, exp1,
266: BUILD_RSA_EXP2, exp2, BUILD_RSA_COEFF, coeff, BUILD_END);
267: }
268:
269: /**
270: * Check if the ASN.1 structure looks like an EC private key according to
271: * RFC 5915.
272: *
273: * ECPrivateKey :=: SEQUENCE {
274: * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
275: * privateKey OCTET STRING,
276: * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
277: * publicKey [1] BIT STRING OPTIONAL
278: * }
279: *
280: * While the parameters and publicKey fields are OPTIONAL, RFC 5915 says that
281: * parameters MUST be included (an errata clarifies this, so this is only the
282: * case for plain private keys, not encoded in PKCS#8) and publicKey SHOULD be.
283: */
284: static bool is_ec_private_key(chunk_t blob)
285: {
286: chunk_t data;
287: return asn1_unwrap(&blob, &blob) == ASN1_SEQUENCE &&
288: asn1_unwrap(&blob, &data) == ASN1_INTEGER &&
289: asn1_parse_integer_uint64(data) == 1 &&
290: asn1_unwrap(&blob, &data) == ASN1_OCTET_STRING &&
291: asn1_unwrap(&blob, &data) == ASN1_CONTEXT_C_0 &&
292: asn1_unwrap(&data, &data) == ASN1_OID &&
293: (!blob.len || (asn1_unwrap(&blob, &data) == ASN1_CONTEXT_C_1));
294: }
295:
296: /**
297: * Check if the ASN.1 structure looks like a BLISS private key.
298: */
299: static bool is_bliss_private_key(chunk_t blob)
300: {
301: chunk_t data;
302: return asn1_unwrap(&blob, &blob) == ASN1_SEQUENCE &&
303: asn1_unwrap(&blob, &data) == ASN1_OID &&
304: asn1_unwrap(&blob, &data) == ASN1_BIT_STRING &&
305: asn1_unwrap(&blob, &data) == ASN1_BIT_STRING &&
306: asn1_unwrap(&blob, &data) == ASN1_BIT_STRING;
307: }
308:
309: /**
310: * Load a private key from an ASN.1 encoded blob trying to detect the type
311: * automatically.
312: */
313: static private_key_t *parse_private_key(chunk_t blob)
314: {
315: if (is_ec_private_key(blob))
316: {
317: return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
318: BUILD_BLOB_ASN1_DER, blob, BUILD_END);
319: }
320: else if (is_bliss_private_key(blob))
321: {
322: return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
323: BUILD_BLOB_ASN1_DER, blob, BUILD_END);
324: }
325: return parse_rsa_private_key(blob);
326: }
327:
328: /**
329: * See header.
330: */
331: public_key_t *pkcs1_public_key_load(key_type_t type, va_list args)
332: {
333: chunk_t blob = chunk_empty;
334:
335: while (TRUE)
336: {
337: switch (va_arg(args, builder_part_t))
338: {
339: case BUILD_BLOB_ASN1_DER:
340: blob = va_arg(args, chunk_t);
341: continue;
342: case BUILD_END:
343: break;
344: default:
345: return NULL;
346: }
347: break;
348: }
349: switch (type)
350: {
351: case KEY_ANY:
352: return parse_public_key(blob);
353: case KEY_RSA:
354: return parse_rsa_public_key(blob);
355: default:
356: return NULL;
357: }
358: }
359:
360: /**
361: * See header.
362: */
363: private_key_t *pkcs1_private_key_load(key_type_t type, va_list args)
364: {
365: chunk_t blob = chunk_empty;
366:
367: while (TRUE)
368: {
369: switch (va_arg(args, builder_part_t))
370: {
371: case BUILD_BLOB_ASN1_DER:
372: blob = va_arg(args, chunk_t);
373: continue;
374: case BUILD_END:
375: break;
376: default:
377: return NULL;
378: }
379: break;
380: }
381: switch (type)
382: {
383: case KEY_ANY:
384: return parse_private_key(blob);
385: case KEY_RSA:
386: return parse_rsa_private_key(blob);
387: default:
388: return NULL;
389: }
390: }
391:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>