Annotation of embedaddon/strongswan/src/libstrongswan/plugins/pgp/pgp_builder.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2009 Martin Willi
3: * Copyright (C) 2002-2009 Andreas Steffen
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 "pgp_builder.h"
18: #include "pgp_utils.h"
19:
20: #include <utils/utils.h>
21: #include <utils/debug.h>
22: #include <credentials/keys/private_key.h>
23:
24: /**
25: * Load a generic public key from a PGP packet
26: */
27: static public_key_t *parse_public_key(chunk_t blob)
28: {
29: uint32_t alg;
30: public_key_t *key;
31:
32: if (!pgp_read_scalar(&blob, 1, &alg))
33: {
34: return NULL;
35: }
36: switch (alg)
37: {
38: case PGP_PUBKEY_ALG_RSA:
39: case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
40: key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
41: BUILD_BLOB_PGP, blob, BUILD_END);
42: break;
43: default:
44: DBG1(DBG_LIB, "PGP public key algorithm %N not supported",
45: pgp_pubkey_alg_names, alg);
46: return NULL;
47: }
48: return key;
49: }
50:
51: /**
52: * Load a RSA public key from a PGP packet
53: */
54: static public_key_t *parse_rsa_public_key(chunk_t blob)
55: {
56: chunk_t mpi[2];
57: int i;
58:
59: for (i = 0; i < 2; i++)
60: {
61: if (!pgp_read_mpi(&blob, &mpi[i]))
62: {
63: return NULL;
64: }
65: }
66: return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
67: BUILD_RSA_MODULUS, mpi[0], BUILD_RSA_PUB_EXP, mpi[1],
68: BUILD_END);
69: }
70:
71: /**
72: * Load a RSA private key from a PGP packet
73: */
74: static private_key_t *parse_rsa_private_key(chunk_t blob)
75: {
76: chunk_t mpi[6];
77: uint32_t s2k;
78: int i;
79:
80: for (i = 0; i < 2; i++)
81: {
82: if (!pgp_read_mpi(&blob, &mpi[i]))
83: {
84: return NULL;
85: }
86: }
87: if (!pgp_read_scalar(&blob, 1, &s2k))
88: {
89: return NULL;
90: }
91: if (s2k == 255 || s2k == 254)
92: {
93: DBG1(DBG_LIB, "string-to-key specifiers not supported");
94: return NULL;
95: }
96: if (s2k != PGP_SYM_ALG_PLAIN)
97: {
98: DBG1(DBG_LIB, "%N private key encryption not supported",
99: pgp_sym_alg_names, s2k);
100: return NULL;
101: }
102:
103: for (i = 2; i < 6; i++)
104: {
105: if (!pgp_read_mpi(&blob, &mpi[i]))
106: {
107: return NULL;
108: }
109: }
110:
111: /* PGP has uses p < q, but we use p > q */
112: return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
113: BUILD_RSA_MODULUS, mpi[0], BUILD_RSA_PUB_EXP, mpi[1],
114: BUILD_RSA_PRIV_EXP, mpi[2], BUILD_RSA_PRIME2, mpi[3],
115: BUILD_RSA_PRIME1, mpi[4], BUILD_RSA_COEFF, mpi[5],
116: BUILD_END);
117: }
118:
119: METHOD(private_key_t, sign_not_allowed, bool,
120: private_key_t *this, signature_scheme_t scheme, void *params,
121: chunk_t data, chunk_t *signature)
122: {
123: DBG1(DBG_LIB, "signing failed - decryption only key");
124: return FALSE;
125: }
126:
127: METHOD(private_key_t, decrypt_not_allowed, bool,
128: private_key_t *this, encryption_scheme_t scheme,
129: chunk_t crypto, chunk_t *plain)
130: {
131: DBG1(DBG_LIB, "decryption failed - signature only key");
132: return FALSE;
133: }
134:
135: /**
136: * Load a generic private key from a PGP packet
137: */
138: static private_key_t *parse_private_key(chunk_t blob)
139: {
140: chunk_t packet;
141: pgp_packet_tag_t tag;
142: uint32_t version, created, days, alg;
143: private_key_t *key;
144:
145: if (!pgp_read_packet(&blob, &packet, &tag))
146: {
147: return NULL;
148: }
149: if (!pgp_read_scalar(&packet, 1, &version))
150: {
151: return NULL;
152: }
153: switch (version)
154: {
155: case 3:
156: if (!pgp_read_scalar(&packet, 2, &days))
157: {
158: return NULL;
159: }
160: break;
161: case 4:
162: break;
163: default:
164: DBG1(DBG_LIB, "PGP packet version V%d not supported", version);
165: return NULL;
166: }
167: if (!pgp_read_scalar(&packet, 4, &created))
168: {
169: return NULL;
170: }
171: if (!pgp_read_scalar(&packet, 1, &alg))
172: {
173: return NULL;
174: }
175: switch (alg)
176: {
177: case PGP_PUBKEY_ALG_RSA:
178: return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
179: BUILD_BLOB_PGP, packet, BUILD_END);
180: case PGP_PUBKEY_ALG_RSA_ENC_ONLY:
181: key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
182: BUILD_BLOB_PGP, packet, BUILD_END);
183: if (key)
184: {
185: key->sign = _sign_not_allowed;
186: }
187: return key;
188: case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
189: key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
190: BUILD_BLOB_PGP, packet, BUILD_END);
191: if (key)
192: {
193: key->decrypt = _decrypt_not_allowed;
194: }
195: return key;
196: case PGP_PUBKEY_ALG_ECDSA:
197: return lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
198: BUILD_BLOB_PGP, packet, BUILD_END);
199: case PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY:
200: case PGP_PUBKEY_ALG_DSA:
201: case PGP_PUBKEY_ALG_ECC:
202: case PGP_PUBKEY_ALG_ELGAMAL:
203: case PGP_PUBKEY_ALG_DIFFIE_HELLMAN:
204: default:
205: return NULL;
206: }
207: }
208:
209: /**
210: * See header.
211: */
212: public_key_t *pgp_public_key_load(key_type_t type, va_list args)
213: {
214: chunk_t blob = chunk_empty;
215:
216: while (TRUE)
217: {
218: switch (va_arg(args, builder_part_t))
219: {
220: case BUILD_BLOB_PGP:
221: blob = va_arg(args, chunk_t);
222: continue;
223: case BUILD_END:
224: break;
225: default:
226: return NULL;
227: }
228: break;
229: }
230: switch (type)
231: {
232: case KEY_ANY:
233: return parse_public_key(blob);
234: case KEY_RSA:
235: return parse_rsa_public_key(blob);
236: default:
237: return NULL;
238: }
239: }
240:
241: /**
242: * See header.
243: */
244: private_key_t *pgp_private_key_load(key_type_t type, va_list args)
245: {
246: chunk_t blob = chunk_empty;
247:
248: while (TRUE)
249: {
250: switch (va_arg(args, builder_part_t))
251: {
252: case BUILD_BLOB_PGP:
253: blob = va_arg(args, chunk_t);
254: continue;
255: case BUILD_END:
256: break;
257: default:
258: return NULL;
259: }
260: break;
261: }
262: switch (type)
263: {
264: case KEY_ANY:
265: return parse_private_key(blob);
266: case KEY_RSA:
267: return parse_rsa_private_key(blob);
268: default:
269: return NULL;
270: }
271: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>