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