1 /*
2 * pgp-pubkey.c
3 * Read public or secret key.
4 *
5 * Copyright (c) 2005 Marko Kreen
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * contrib/pgcrypto/pgp-pubkey.c
30 */
31 #include "postgres.h"
32
33 #include "px.h"
34 #include "mbuf.h"
35 #include "pgp.h"
36
37 int
pgp_key_alloc(PGP_PubKey ** pk_p)38 pgp_key_alloc(PGP_PubKey **pk_p)
39 {
40 PGP_PubKey *pk;
41
42 pk = px_alloc(sizeof(*pk));
43 memset(pk, 0, sizeof(*pk));
44 *pk_p = pk;
45 return 0;
46 }
47
48 void
pgp_key_free(PGP_PubKey * pk)49 pgp_key_free(PGP_PubKey *pk)
50 {
51 if (pk == NULL)
52 return;
53
54 switch (pk->algo)
55 {
56 case PGP_PUB_ELG_ENCRYPT:
57 pgp_mpi_free(pk->pub.elg.p);
58 pgp_mpi_free(pk->pub.elg.g);
59 pgp_mpi_free(pk->pub.elg.y);
60 pgp_mpi_free(pk->sec.elg.x);
61 break;
62 case PGP_PUB_RSA_SIGN:
63 case PGP_PUB_RSA_ENCRYPT:
64 case PGP_PUB_RSA_ENCRYPT_SIGN:
65 pgp_mpi_free(pk->pub.rsa.n);
66 pgp_mpi_free(pk->pub.rsa.e);
67 pgp_mpi_free(pk->sec.rsa.d);
68 pgp_mpi_free(pk->sec.rsa.p);
69 pgp_mpi_free(pk->sec.rsa.q);
70 pgp_mpi_free(pk->sec.rsa.u);
71 break;
72 case PGP_PUB_DSA_SIGN:
73 pgp_mpi_free(pk->pub.dsa.p);
74 pgp_mpi_free(pk->pub.dsa.q);
75 pgp_mpi_free(pk->pub.dsa.g);
76 pgp_mpi_free(pk->pub.dsa.y);
77 pgp_mpi_free(pk->sec.dsa.x);
78 break;
79 }
80 px_memset(pk, 0, sizeof(*pk));
81 px_free(pk);
82 }
83
84 static int
calc_key_id(PGP_PubKey * pk)85 calc_key_id(PGP_PubKey *pk)
86 {
87 int res;
88 PX_MD *md;
89 int len;
90 uint8 hdr[3];
91 uint8 hash[20];
92
93 res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
94 if (res < 0)
95 return res;
96
97 len = 1 + 4 + 1;
98 switch (pk->algo)
99 {
100 case PGP_PUB_ELG_ENCRYPT:
101 len += 2 + pk->pub.elg.p->bytes;
102 len += 2 + pk->pub.elg.g->bytes;
103 len += 2 + pk->pub.elg.y->bytes;
104 break;
105 case PGP_PUB_RSA_SIGN:
106 case PGP_PUB_RSA_ENCRYPT:
107 case PGP_PUB_RSA_ENCRYPT_SIGN:
108 len += 2 + pk->pub.rsa.n->bytes;
109 len += 2 + pk->pub.rsa.e->bytes;
110 break;
111 case PGP_PUB_DSA_SIGN:
112 len += 2 + pk->pub.dsa.p->bytes;
113 len += 2 + pk->pub.dsa.q->bytes;
114 len += 2 + pk->pub.dsa.g->bytes;
115 len += 2 + pk->pub.dsa.y->bytes;
116 break;
117 }
118
119 hdr[0] = 0x99;
120 hdr[1] = len >> 8;
121 hdr[2] = len & 0xFF;
122 px_md_update(md, hdr, 3);
123
124 px_md_update(md, &pk->ver, 1);
125 px_md_update(md, pk->time, 4);
126 px_md_update(md, &pk->algo, 1);
127
128 switch (pk->algo)
129 {
130 case PGP_PUB_ELG_ENCRYPT:
131 pgp_mpi_hash(md, pk->pub.elg.p);
132 pgp_mpi_hash(md, pk->pub.elg.g);
133 pgp_mpi_hash(md, pk->pub.elg.y);
134 break;
135 case PGP_PUB_RSA_SIGN:
136 case PGP_PUB_RSA_ENCRYPT:
137 case PGP_PUB_RSA_ENCRYPT_SIGN:
138 pgp_mpi_hash(md, pk->pub.rsa.n);
139 pgp_mpi_hash(md, pk->pub.rsa.e);
140 break;
141 case PGP_PUB_DSA_SIGN:
142 pgp_mpi_hash(md, pk->pub.dsa.p);
143 pgp_mpi_hash(md, pk->pub.dsa.q);
144 pgp_mpi_hash(md, pk->pub.dsa.g);
145 pgp_mpi_hash(md, pk->pub.dsa.y);
146 break;
147 }
148
149 px_md_finish(md, hash);
150 px_md_free(md);
151
152 memcpy(pk->key_id, hash + 12, 8);
153 px_memset(hash, 0, 20);
154
155 return 0;
156 }
157
158 int
_pgp_read_public_key(PullFilter * pkt,PGP_PubKey ** pk_p)159 _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
160 {
161 int res;
162 PGP_PubKey *pk;
163
164 res = pgp_key_alloc(&pk);
165 if (res < 0)
166 return res;
167
168 /* get version */
169 GETBYTE(pkt, pk->ver);
170 if (pk->ver != 4)
171 {
172 res = PXE_PGP_NOT_V4_KEYPKT;
173 goto out;
174 }
175
176 /* read time */
177 res = pullf_read_fixed(pkt, 4, pk->time);
178 if (res < 0)
179 goto out;
180
181 /* pubkey algorithm */
182 GETBYTE(pkt, pk->algo);
183
184 switch (pk->algo)
185 {
186 case PGP_PUB_DSA_SIGN:
187 res = pgp_mpi_read(pkt, &pk->pub.dsa.p);
188 if (res < 0)
189 break;
190 res = pgp_mpi_read(pkt, &pk->pub.dsa.q);
191 if (res < 0)
192 break;
193 res = pgp_mpi_read(pkt, &pk->pub.dsa.g);
194 if (res < 0)
195 break;
196 res = pgp_mpi_read(pkt, &pk->pub.dsa.y);
197 if (res < 0)
198 break;
199
200 res = calc_key_id(pk);
201 break;
202
203 case PGP_PUB_RSA_SIGN:
204 case PGP_PUB_RSA_ENCRYPT:
205 case PGP_PUB_RSA_ENCRYPT_SIGN:
206 res = pgp_mpi_read(pkt, &pk->pub.rsa.n);
207 if (res < 0)
208 break;
209 res = pgp_mpi_read(pkt, &pk->pub.rsa.e);
210 if (res < 0)
211 break;
212
213 res = calc_key_id(pk);
214
215 if (pk->algo != PGP_PUB_RSA_SIGN)
216 pk->can_encrypt = 1;
217 break;
218
219 case PGP_PUB_ELG_ENCRYPT:
220 res = pgp_mpi_read(pkt, &pk->pub.elg.p);
221 if (res < 0)
222 break;
223 res = pgp_mpi_read(pkt, &pk->pub.elg.g);
224 if (res < 0)
225 break;
226 res = pgp_mpi_read(pkt, &pk->pub.elg.y);
227 if (res < 0)
228 break;
229
230 res = calc_key_id(pk);
231
232 pk->can_encrypt = 1;
233 break;
234
235 default:
236 px_debug("unknown public algo: %d", pk->algo);
237 res = PXE_PGP_UNKNOWN_PUBALGO;
238 }
239
240 out:
241 if (res < 0)
242 pgp_key_free(pk);
243 else
244 *pk_p = pk;
245
246 return res;
247 }
248
249 #define HIDE_CLEAR 0
250 #define HIDE_CKSUM 255
251 #define HIDE_SHA1 254
252
253 static int
check_key_sha1(PullFilter * src,PGP_PubKey * pk)254 check_key_sha1(PullFilter *src, PGP_PubKey *pk)
255 {
256 int res;
257 uint8 got_sha1[20];
258 uint8 my_sha1[20];
259 PX_MD *md;
260
261 res = pullf_read_fixed(src, 20, got_sha1);
262 if (res < 0)
263 return res;
264
265 res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
266 if (res < 0)
267 goto err;
268 switch (pk->algo)
269 {
270 case PGP_PUB_ELG_ENCRYPT:
271 pgp_mpi_hash(md, pk->sec.elg.x);
272 break;
273 case PGP_PUB_RSA_SIGN:
274 case PGP_PUB_RSA_ENCRYPT:
275 case PGP_PUB_RSA_ENCRYPT_SIGN:
276 pgp_mpi_hash(md, pk->sec.rsa.d);
277 pgp_mpi_hash(md, pk->sec.rsa.p);
278 pgp_mpi_hash(md, pk->sec.rsa.q);
279 pgp_mpi_hash(md, pk->sec.rsa.u);
280 break;
281 case PGP_PUB_DSA_SIGN:
282 pgp_mpi_hash(md, pk->sec.dsa.x);
283 break;
284 }
285 px_md_finish(md, my_sha1);
286 px_md_free(md);
287
288 if (memcmp(my_sha1, got_sha1, 20) != 0)
289 {
290 px_debug("key sha1 check failed");
291 res = PXE_PGP_KEYPKT_CORRUPT;
292 }
293 err:
294 px_memset(got_sha1, 0, 20);
295 px_memset(my_sha1, 0, 20);
296 return res;
297 }
298
299 static int
check_key_cksum(PullFilter * src,PGP_PubKey * pk)300 check_key_cksum(PullFilter *src, PGP_PubKey *pk)
301 {
302 int res;
303 unsigned got_cksum,
304 my_cksum = 0;
305 uint8 buf[2];
306
307 res = pullf_read_fixed(src, 2, buf);
308 if (res < 0)
309 return res;
310
311 got_cksum = ((unsigned) buf[0] << 8) + buf[1];
312 switch (pk->algo)
313 {
314 case PGP_PUB_ELG_ENCRYPT:
315 my_cksum = pgp_mpi_cksum(0, pk->sec.elg.x);
316 break;
317 case PGP_PUB_RSA_SIGN:
318 case PGP_PUB_RSA_ENCRYPT:
319 case PGP_PUB_RSA_ENCRYPT_SIGN:
320 my_cksum = pgp_mpi_cksum(0, pk->sec.rsa.d);
321 my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.p);
322 my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.q);
323 my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.u);
324 break;
325 case PGP_PUB_DSA_SIGN:
326 my_cksum = pgp_mpi_cksum(0, pk->sec.dsa.x);
327 break;
328 }
329 if (my_cksum != got_cksum)
330 {
331 px_debug("key cksum check failed");
332 return PXE_PGP_KEYPKT_CORRUPT;
333 }
334 return 0;
335 }
336
337 static int
process_secret_key(PullFilter * pkt,PGP_PubKey ** pk_p,const uint8 * key,int key_len)338 process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p,
339 const uint8 *key, int key_len)
340 {
341 int res;
342 int hide_type;
343 int cipher_algo;
344 int bs;
345 uint8 iv[512];
346 PullFilter *pf_decrypt = NULL,
347 *pf_key;
348 PGP_CFB *cfb = NULL;
349 PGP_S2K s2k;
350 PGP_PubKey *pk;
351
352 /* first read public key part */
353 res = _pgp_read_public_key(pkt, &pk);
354 if (res < 0)
355 return res;
356
357 /*
358 * is secret key encrypted?
359 */
360 GETBYTE(pkt, hide_type);
361 if (hide_type == HIDE_SHA1 || hide_type == HIDE_CKSUM)
362 {
363 if (key == NULL)
364 return PXE_PGP_NEED_SECRET_PSW;
365 GETBYTE(pkt, cipher_algo);
366 res = pgp_s2k_read(pkt, &s2k);
367 if (res < 0)
368 return res;
369
370 res = pgp_s2k_process(&s2k, cipher_algo, key, key_len);
371 if (res < 0)
372 return res;
373
374 bs = pgp_get_cipher_block_size(cipher_algo);
375 if (bs == 0)
376 {
377 px_debug("unknown cipher algo=%d", cipher_algo);
378 return PXE_PGP_UNSUPPORTED_CIPHER;
379 }
380 res = pullf_read_fixed(pkt, bs, iv);
381 if (res < 0)
382 return res;
383
384 /*
385 * create decrypt filter
386 */
387 res = pgp_cfb_create(&cfb, cipher_algo, s2k.key, s2k.key_len, 0, iv);
388 if (res < 0)
389 return res;
390 res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
391 if (res < 0)
392 return res;
393 pf_key = pf_decrypt;
394 }
395 else if (hide_type == HIDE_CLEAR)
396 {
397 pf_key = pkt;
398 }
399 else
400 {
401 px_debug("unknown hide type");
402 return PXE_PGP_KEYPKT_CORRUPT;
403 }
404
405 /* read secret key */
406 switch (pk->algo)
407 {
408 case PGP_PUB_RSA_SIGN:
409 case PGP_PUB_RSA_ENCRYPT:
410 case PGP_PUB_RSA_ENCRYPT_SIGN:
411 res = pgp_mpi_read(pf_key, &pk->sec.rsa.d);
412 if (res < 0)
413 break;
414 res = pgp_mpi_read(pf_key, &pk->sec.rsa.p);
415 if (res < 0)
416 break;
417 res = pgp_mpi_read(pf_key, &pk->sec.rsa.q);
418 if (res < 0)
419 break;
420 res = pgp_mpi_read(pf_key, &pk->sec.rsa.u);
421 if (res < 0)
422 break;
423 break;
424 case PGP_PUB_ELG_ENCRYPT:
425 res = pgp_mpi_read(pf_key, &pk->sec.elg.x);
426 break;
427 case PGP_PUB_DSA_SIGN:
428 res = pgp_mpi_read(pf_key, &pk->sec.dsa.x);
429 break;
430 default:
431 px_debug("unknown public algo: %d", pk->algo);
432 res = PXE_PGP_KEYPKT_CORRUPT;
433 }
434 /* read checksum / sha1 */
435 if (res >= 0)
436 {
437 if (hide_type == HIDE_SHA1)
438 res = check_key_sha1(pf_key, pk);
439 else
440 res = check_key_cksum(pf_key, pk);
441 }
442 if (res >= 0)
443 res = pgp_expect_packet_end(pf_key);
444
445 if (pf_decrypt)
446 pullf_free(pf_decrypt);
447 if (cfb)
448 pgp_cfb_free(cfb);
449
450 if (res < 0)
451 pgp_key_free(pk);
452 else
453 *pk_p = pk;
454
455 return res;
456 }
457
458 static int
internal_read_key(PullFilter * src,PGP_PubKey ** pk_p,const uint8 * psw,int psw_len,int pubtype)459 internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
460 const uint8 *psw, int psw_len, int pubtype)
461 {
462 PullFilter *pkt = NULL;
463 int res;
464 uint8 tag;
465 int len;
466 PGP_PubKey *enc_key = NULL;
467 PGP_PubKey *pk = NULL;
468 int got_main_key = 0;
469
470 /*
471 * Search for encryption key.
472 *
473 * Error out on anything fancy.
474 */
475 while (1)
476 {
477 res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
478 if (res <= 0)
479 break;
480 res = pgp_create_pkt_reader(&pkt, src, len, res, NULL);
481 if (res < 0)
482 break;
483
484 switch (tag)
485 {
486 case PGP_PKT_PUBLIC_KEY:
487 case PGP_PKT_SECRET_KEY:
488 if (got_main_key)
489 {
490 res = PXE_PGP_MULTIPLE_KEYS;
491 break;
492 }
493 got_main_key = 1;
494 res = pgp_skip_packet(pkt);
495 break;
496
497 case PGP_PKT_PUBLIC_SUBKEY:
498 if (pubtype != 0)
499 res = PXE_PGP_EXPECT_SECRET_KEY;
500 else
501 res = _pgp_read_public_key(pkt, &pk);
502 break;
503
504 case PGP_PKT_SECRET_SUBKEY:
505 if (pubtype != 1)
506 res = PXE_PGP_EXPECT_PUBLIC_KEY;
507 else
508 res = process_secret_key(pkt, &pk, psw, psw_len);
509 break;
510
511 case PGP_PKT_SIGNATURE:
512 case PGP_PKT_MARKER:
513 case PGP_PKT_TRUST:
514 case PGP_PKT_USER_ID:
515 case PGP_PKT_USER_ATTR:
516 case PGP_PKT_PRIV_61:
517 res = pgp_skip_packet(pkt);
518 break;
519 default:
520 px_debug("unknown/unexpected packet: %d", tag);
521 res = PXE_PGP_UNEXPECTED_PKT;
522 }
523 pullf_free(pkt);
524 pkt = NULL;
525
526 if (pk != NULL)
527 {
528 if (res >= 0 && pk->can_encrypt)
529 {
530 if (enc_key == NULL)
531 {
532 enc_key = pk;
533 pk = NULL;
534 }
535 else
536 res = PXE_PGP_MULTIPLE_SUBKEYS;
537 }
538
539 if (pk)
540 pgp_key_free(pk);
541 pk = NULL;
542 }
543
544 if (res < 0)
545 break;
546 }
547
548 if (pkt)
549 pullf_free(pkt);
550
551 if (res < 0)
552 {
553 if (enc_key)
554 pgp_key_free(enc_key);
555 return res;
556 }
557
558 if (!enc_key)
559 res = PXE_PGP_NO_USABLE_KEY;
560 else
561 *pk_p = enc_key;
562 return res;
563 }
564
565 int
pgp_set_pubkey(PGP_Context * ctx,MBuf * keypkt,const uint8 * key,int key_len,int pubtype)566 pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt,
567 const uint8 *key, int key_len, int pubtype)
568 {
569 int res;
570 PullFilter *src;
571 PGP_PubKey *pk = NULL;
572
573 res = pullf_create_mbuf_reader(&src, keypkt);
574 if (res < 0)
575 return res;
576
577 res = internal_read_key(src, &pk, key, key_len, pubtype);
578 pullf_free(src);
579
580 if (res >= 0)
581 ctx->pub_key = pk;
582
583 return res < 0 ? res : 0;
584 }
585