1 /* rfc2440.c - OpenPGP message format
2 * Copyright (C) 2002, 2007 Timo Schulz
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <defines.h>
19 #include <random.h>
20 #include <time.h>
21 #include <assert.h>
22 #ifdef HAVE_LIBZ
23 #include <zlib.h>
24 #endif
25 #include <stdio.h>
26
27 #include "keys.h"
28 #include "errors.h"
29 #include "rfc2440.h"
30 #include "defines.h"
31
32 #ifndef _mcrypt_calloc
33 #define _mcrypt_calloc calloc
34 #endif
35
36 /*-- mcrypt.c --*/
37 extern char *algorithm;
38 extern int keysize;
39 extern char* keymode;
40 extern char* mode;
41 extern int openpgp_z;
42 extern int real_random_flag;
43 /*--------------*/
44
45 extern int total_bytes; /* openpgp.c */
46
47 /* typedef short cuts for common primitive data types. */
48 typedef unsigned int uint32;
49 typedef unsigned char uchar;
50
51 #define S2K_DEFAULT_COUNT 96
52
53 #ifndef DIM /* helper to figure out the amount of elements. */
54 #define DIM(x) (sizeof (x) / sizeof (x)[0])
55 #endif
56
57 typedef struct packet_s {
58 unsigned blockmode:1;
59 unsigned old:1;
60 } PACKET;
61
62
63 /* FIXME: the 'mmap' interface could be a problem for larger
64 files. In general it would be better to provide a
65 more flexible solutions with smaller buffers. */
66
67
68 static USTRING
make_ustring(const uchar * buffer,size_t length)69 make_ustring(const uchar *buffer, size_t length)
70 {
71 USTRING a;
72
73 a = _mcrypt_calloc(1, sizeof *a + length);
74 a->len = length;
75 a->d = (void*)a + sizeof *a;
76 memset(a->d, 1, length);
77 if (buffer != NULL)
78 memcpy(a->d, buffer, length);
79 return a;
80 }
81
82 static USTRING
realloc_ustring(const USTRING src,size_t length)83 realloc_ustring(const USTRING src, size_t length)
84 {
85 USTRING a;
86 size_t len;
87
88 len = length;
89 if (src != NULL)
90 len += src->len;
91 a = _mcrypt_calloc(1, sizeof *a + len);
92 a->len = len;
93 a->d = (void*)a + sizeof *a;
94 memset(a->d, 1, len);
95 if (src != NULL) {
96 memcpy(a->d, src->d, src->len);
97 free(src);
98 }
99 return a;
100 }
101
102 static uchar*
file_to_buf(const char * file,off_t offset,size_t * ret_len)103 file_to_buf(const char *file, off_t offset, size_t *ret_len )
104 {
105 struct stat statbuf;
106 uchar *buf;
107 FILE *fp;
108 size_t len;
109
110 /* Return NULL if the file cannot be stat or has a length of zero. */
111 if (stat(file, &statbuf) == -1 ||
112 statbuf.st_size == 0)
113 return NULL;
114
115 len = statbuf.st_size;
116 fp = fopen(file, "rb");
117 if (fp == NULL)
118 return NULL;
119 buf = _mcrypt_calloc(1, len);
120 fseeko(fp, offset, SEEK_SET);
121 fread(buf, 1, len, fp);
122 fclose(fp);
123 *ret_len = len - offset;
124 return buf;
125 }
126
127 static void
_mcrypt_sync(MCRYPT hd,uchar * rndpref,int blocklen)128 _mcrypt_sync(MCRYPT hd, uchar *rndpref, int blocklen)
129 {
130 uchar sync[19];
131
132 if (blocklen != 8 && blocklen != 16)
133 return;
134 sync[0] = 0;
135 memcpy(sync + 1, rndpref + 2, blocklen);
136 mcrypt_enc_set_state(hd, sync, blocklen + 1);
137 }
138
139
140 static int
_mcrypt_encrypt(MCRYPT hd,uchar * out,size_t outlen,uchar * in,size_t inlen)141 _mcrypt_encrypt(MCRYPT hd, uchar *out, size_t outlen,
142 uchar *in, size_t inlen)
143 {
144 if (!in)
145 return mcrypt_generic(hd, out, outlen);
146 if (outlen < inlen)
147 return -1;
148 memcpy(out, in, inlen);
149 mcrypt_generic(hd, out, inlen);
150 return 0;
151 }
152
153 static int
_mcrypt_decrypt(MCRYPT hd,uchar * out,size_t outlen,uchar * in,size_t inlen)154 _mcrypt_decrypt(MCRYPT hd, uchar *out, size_t outlen,
155 uchar *in, size_t inlen)
156 {
157 if (!in)
158 return mdecrypt_generic(hd, out, outlen);
159 if (outlen < inlen)
160 return -1;
161 memcpy(out, in, inlen);
162 mdecrypt_generic(hd, out, inlen);
163 return 0;
164 }
165
166
167 static char*
_mhash_keymode2str(keygenid ki,hashid hi)168 _mhash_keymode2str(keygenid ki, hashid hi)
169 {
170 static char ret[512];
171
172 ret[0] = 0;
173 if (ki == KEYGEN_S2K_SIMPLE)
174 strcat(ret, "s2k-simple-");
175 else if (ki == KEYGEN_S2K_SALTED)
176 strcat(ret, "s2k-salted-");
177 else if (ki == KEYGEN_S2K_ISALTED)
178 strcat(ret, "s2k-isalted-");
179
180 if (hi == MHASH_SHA1)
181 strcat(ret, "sha1");
182 else if (hi == MHASH_MD5)
183 strcat(ret, "md5");
184 else if (hi == MHASH_RIPEMD160)
185 strcat(ret, "ripemd");
186 else if (hi == MHASH_SHA256)
187 strcat(ret, "sha256");
188 return ret;
189 }
190
191 /* Convert the OpenPGP type ID to the local mhash ID. */
192 static int
_mhash_keygen(uchar algid)193 _mhash_keygen(uchar algid)
194 {
195 switch (algid) {
196 case OPENPGP_S2K_SIMPLE: return KEYGEN_S2K_SIMPLE;
197 case OPENPGP_S2K_SALTED: return KEYGEN_S2K_SALTED;
198 case OPENPGP_S2K_ISALTED: return KEYGEN_S2K_ISALTED;
199 }
200 return KEYGEN_S2K_ISALTED; /* return default keygen mode. */
201 }
202
203 int
_mhash_keygen_to_rfc2440(int algo)204 _mhash_keygen_to_rfc2440(int algo)
205 {
206 switch (algo) {
207 case KEYGEN_S2K_SIMPLE: return OPENPGP_S2K_SIMPLE;
208 case KEYGEN_S2K_SALTED: return OPENPGP_S2K_SALTED;
209 case KEYGEN_S2K_ISALTED: return OPENPGP_S2K_ISALTED;
210 }
211 return OPENPGP_S2K_ISALTED;
212 }
213
214 static int
_mhash_algo(uchar algid)215 _mhash_algo(uchar algid)
216 {
217 switch ( algid ) {
218 case OPENPGP_MD_MD5: return MHASH_MD5;
219 case OPENPGP_MD_SHA1: return MHASH_SHA1;
220 case OPENPGP_MD_RMD160: return MHASH_RIPEMD160;
221 }
222 return MHASH_SHA1;
223 }
224
225 static int
_mhash_algo_to_rfc2440(int algo)226 _mhash_algo_to_rfc2440(int algo)
227 {
228 switch (algo) {
229 case MHASH_MD5: return OPENPGP_MD_MD5;
230 case MHASH_SHA1: return OPENPGP_MD_SHA1;
231 case MHASH_RIPEMD160: return OPENPGP_MD_RMD160;
232 }
233 return OPENPGP_MD_SHA1;
234 }
235
236
237 static char*
_mcrypt_algid_to_algo(uchar algid)238 _mcrypt_algid_to_algo(uchar algid)
239 {
240 switch (algid) {
241 case OPENPGP_ENC_3DES:
242 keysize = 24;
243 return "tripledes";
244
245 case OPENPGP_ENC_CAST5:
246 keysize = 16;
247 return "cast-128";
248
249 case OPENPGP_ENC_BLOWFISH:
250 keysize = 16;
251 return "blowfish";
252
253 case OPENPGP_ENC_AES128:
254 keysize = 16;
255 return "rijndael-128";
256
257 case OPENPGP_ENC_AES192:
258 keysize = 24;
259 return "rijndael-128";
260
261 case OPENPGP_ENC_AES256:
262 keysize = 32;
263 return "rijndael-128";
264
265 case OPENPGP_ENC_TWOFISH:
266 keysize = 32;
267 return "twofish";
268 }
269
270 /* default cipher is CAST5. */
271 keysize = 16;
272 return "cast-128";
273 }
274
275 /* convert mcrypt specific ID to an OpenPGP ID. */
276 static uchar
_mcrypt_algo_to_algid(char * algo)277 _mcrypt_algo_to_algid(char *algo)
278 {
279 if (!strcmp(algo, "tripledes"))
280 return OPENPGP_ENC_3DES;
281 else if (!strcmp(algo, "cast-128"))
282 return OPENPGP_ENC_CAST5;
283 else if (!strcmp(algo, "blowfish"))
284 return OPENPGP_ENC_BLOWFISH;
285 else if (!strcmp(algo, "rijndael-128") && keysize == 16)
286 return OPENPGP_ENC_AES128;
287 else if ( !strcmp(algo, "rijndael-128") && keysize == 24)
288 return OPENPGP_ENC_AES192;
289 else if ( !strcmp(algo, "rijndael-128") && keysize == 32)
290 return OPENPGP_ENC_AES256;
291 else if ( !strcmp(algo, "twofish"))
292 return OPENPGP_ENC_TWOFISH;
293
294 return OPENPGP_ENC_AES128;
295 }
296
297 static char*
pgp_get_algo(char * algo)298 pgp_get_algo(char *algo)
299 {
300 /* Return default cipher algorithm. */
301 if (!algo)
302 return "cast-128";
303
304 /* make sure we only use OpenPGP compatible algorithms */
305 if (!strcmp(algo, "tripledes") ||
306 !strcmp(algo, "cast-128") ||
307 !strcmp(algo, "blowfish") ||
308 !strcmp(algo, "rijndael-128") ||
309 !strcmp(algo, "twofish"))
310 return algo;
311
312 fprintf(stderr,
313 _("Algorithm %s is not available in OpenPGP encryption.\n"),
314 algo);
315 fprintf(stderr, _("%s will be used instead.\n"), DEFAULT_PGP_ALGO);
316 return DEFAULT_PGP_ALGO;
317 }
318
319
320 static uint32
get_pkt_tag(const uchar * buf,PACKET * pkt)321 get_pkt_tag(const uchar *buf, PACKET *pkt)
322 {
323 uint32 tag = -1;
324
325 assert(buf);
326 if (!(buf[0] & 0x80))
327 return -1; /* invalid */
328 if (buf[0] & 0x40) { /* new style */
329 tag = buf[0] & 0x3f;
330 if (pkt)
331 pkt->old = 0;
332 }
333 else { /* old style */
334 tag = (buf[0] & 0x3c) >> 2;
335 if (pkt)
336 pkt->old = 1;
337 }
338 return tag;
339 }
340
341
342 static uint32
length_len(const uint32 len,PACKET * pkt)343 length_len(const uint32 len, PACKET *pkt)
344 {
345 uint32 ret = 0;
346
347 if (pkt && pkt->blockmode)
348 return 1;
349 else if (pkt && pkt->old) {
350 if (len < 0xff)
351 ret = 1;
352 else if (len < 0xffff)
353 ret = 2;
354 else if (len < 0xffffffff)
355 ret = 4;
356 }
357 else {
358 if (len < 192)
359 ret = 1;
360 else if (len < 8384)
361 ret = 2;
362 else
363 ret = 5;
364 }
365 return ret;
366 }
367
368
369 static void
length_encode(uint32 len,uchar * lenbuf,uchar * lensize)370 length_encode(uint32 len, uchar *lenbuf, uchar *lensize)
371 {
372 assert(len > 0);
373
374 if (len < 192) {
375 lenbuf[0] = len;
376 *lensize = 1;
377 }
378 else if (len < 8384) {
379 len -= 192;
380 lenbuf[0] = len / 256 + 192;
381 lenbuf[1] = len % 256;
382 *lensize = 2;
383 }
384 else {
385 lenbuf[0] = 255;
386 lenbuf[1] = len >> 24;
387 lenbuf[2] = len >> 16;
388 lenbuf[3] = len >> 8;
389 lenbuf[4] = len;
390 *lensize = 5;
391 }
392 }
393
394
395 static uint32
length_decode(const uchar * buf,int pos,PACKET * pkt)396 length_decode(const uchar *buf, int pos, PACKET *pkt)
397 {
398 uint32 len = 0;
399
400 assert (buf != NULL);
401 assert (pos >= 0);
402
403 if (buf[pos] < 192)
404 len = buf[pos];
405 else if (buf[pos] >= 192 && buf[pos] <= 223) {
406 len = (buf[pos] - 192) << 8;
407 len += (buf[pos+1] + 192);
408 }
409 else if (buf[pos] == 255) {
410 len += (buf[pos+1] << 24);
411 len += (buf[pos+2] << 16);
412 len += (buf[pos+3] << 8);
413 len += buf[pos+4];
414 }
415 else {
416 len = 1 << (buf[pos]);
417 if (pkt)
418 pkt->blockmode = 1;
419 }
420 return len;
421 }
422
423 static void
header_decode(const uchar * buf,uint32 * tag,uint32 * len,uint32 * headlen,PACKET * pkt)424 header_decode(const uchar *buf, uint32 *tag, uint32 *len,
425 uint32 *headlen, PACKET *pkt)
426 {
427 assert (buf != NULL);
428
429 *tag = get_pkt_tag(buf, pkt);
430 if (buf[0] & 0x40) {
431 *len = length_decode( buf, 1, pkt );
432 *headlen = 1 + length_len( *len, pkt );
433 }
434 else {
435 if ((buf[0] & 0x03) == 0) {
436 *len = buf[1];
437 *headlen = 2;
438 }
439 else if ((buf[0] & 0x03) == 1) {
440 *len = (buf[1] << 8) | buf[2];
441 *headlen = 3;
442 }
443 else if ((buf[0] & 0x03) == 2) {
444 *len = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
445 *headlen = 5;
446 }
447 else if ((buf[0] & 0x03) == 3) {
448 *len = 0;
449 *headlen = 1;
450 }
451 }
452 }
453
454 int
plaintext_decode(const USTRING pt,USTRING * result)455 plaintext_decode(const USTRING pt, USTRING *result)
456 {
457 uint32 headlen = 0, tag = 0, offset = 0;
458 PACKET pkt;
459 USTRING t;
460
461 memset( &pkt, 0, sizeof(pkt));
462
463 assert(pt->len > 0);
464 header_decode(pt->d, &tag, &headlen, &offset, &pkt);
465 if (tag != PKT_PLAINTEXT)
466 return PGP_ERR_PKT;
467
468 if (pt->len < 8) /* wrong len */
469 return PGP_ERR_PKT;
470 if (!pkt.blockmode && (pt->len-1-length_len(headlen, &pkt)) != headlen)
471 return PGP_ERR_PKT; /* malformed */
472 if (pt->d[offset] != 0x62 && pt->d[offset] != 0x74)
473 return PGP_ERR_PKT;
474 offset++;
475
476 /* we ignore the file name but need to skip past it if its present */
477 if (pt->d[offset] > 0)
478 offset += pt->d[offset];
479 offset++; /* file name length */
480 offset += 4; /* timestamp */
481
482 t = make_ustring( pt->d+offset, pt->len-offset);
483 *result = t;
484
485 return PGP_SUCCESS;
486 }
487
488
489 USTRING
plaintext_encode(const USTRING dat)490 plaintext_encode(const USTRING dat)
491 {
492 USTRING result = NULL, newdat = NULL;
493 uint32 pos = 0;
494 uchar lenbuf[5], lensize = 0;
495 time_t t;
496
497 assert(dat->len > 0);
498 result = make_ustring( NULL, 2 * dat->len); /* xxx */
499 newdat = (USTRING)dat;
500 result->d[pos++] = (0x80 | 0x40 | PKT_PLAINTEXT);
501
502 /* 1 byte data type, 4 bytes timestamp, 1 byte non-file-name */
503 length_encode(dat->len + 6, lenbuf, &lensize);
504 memcpy(result->d + pos, lenbuf, lensize);
505 pos += lensize;
506
507 t = time(NULL); /* time of creation. */
508 result->d[pos++] = 0x62; /* binary */
509 result->d[pos++] = 0; /* no file name */
510 result->d[pos++] = t >> 24;
511 result->d[pos++] = t >> 16;
512 result->d[pos++] = t >> 8;
513 result->d[pos++] = t;
514
515 memcpy(result->d + pos, newdat->d, newdat->len);
516 result->len = pos + newdat->len;
517 return result;
518 }
519
520 void
dek_free(DEK * d)521 dek_free(DEK *d)
522 {
523 if (!d)
524 return;
525 mcrypt_generic_deinit(d->hd);
526 mcrypt_module_close(d->hd);
527 free(d);
528 }
529
530
531 static int
pgp_get_keysize(const char * algo)532 pgp_get_keysize(const char *algo)
533 {
534 int keylen = keysize;
535
536 /* OpenPGP uses fixed key sizes which means we need to
537 change the size for variable ciphers. */
538 if (!strcmp(algo, "twofish" ))
539 keylen = 32;
540 if (!strcmp(algo, "blowfish"))
541 keylen = 16;
542 if (!strcmp(algo, "cast-128"))
543 keylen = 16;
544 keysize = keylen; /* set the global key size to this */
545 return keylen;
546 }
547
548
549 void
dek_load(DEK * d,char * pass)550 dek_load(DEK *d, char *pass)
551 {
552 KEYGEN keygen_data;
553 char* mode = DEFAULT_PGP_MODE;
554 int ret;
555
556 d->keylen = pgp_get_keysize(d->algo);
557 keygen_data.hash_algorithm[0] = d->s2k.algo;
558 keygen_data.count = d->s2k.count;
559 keygen_data.salt = d->s2k.salt;
560 keygen_data.salt_size = 8;
561
562 d->blocklen = mcrypt_module_get_algo_block_size(d->algo, NULL);
563 ret = mhash_keygen_ext(d->s2k.mode, keygen_data, d->key,
564 DIM (d->key), pass, strlen(pass));
565 if (ret < 0)
566 err_quit(_("mhash_keygen_ext() failed.\n"));
567 d->hd = mcrypt_module_open(d->algo, NULL, mode, NULL);
568 if (d->hd == MCRYPT_FAILED)
569 err_quit(_("Could not open module\n"));
570 }
571
572
573 DEK*
dek_create(char * algo,char * pass)574 dek_create(char* algo, char *pass)
575 {
576 DEK *d;
577 KEYGEN keygen_data;
578 char* mode = DEFAULT_PGP_MODE;
579 keygenid mh_keymode;
580 hashid mh_alg;
581 int ret;
582
583 d = _mcrypt_calloc(1, sizeof *d);
584 d->algo = algo;
585 d->keylen = pgp_get_keysize(algo);
586 d->blocklen = mcrypt_module_get_algo_block_size(algo, NULL);
587
588 algorithm = d->algo;
589 keysize = d->keylen;
590
591 /* There are two ways for symmetric encryption.
592 1. To derrive the session key directly from the passphrase
593 2. Use a random session key and it encrypt it with a derrived
594 key from the passphrase.
595 For the sake of simplicity, we always use method 1. */
596 if (_mcrypt_pgp_conv_keymode(keymode, &mh_keymode, &mh_alg) < 0) {
597 char tmp[255];
598
599 snprintf(tmp, DIM (tmp)-1, _("OpenPGP: Unsupported key mode %s\n"),
600 keymode);
601 err_quit(tmp);
602 }
603
604 d->s2k.mode = mh_keymode;
605 d->s2k.algo = mh_alg;
606 d->s2k.count = S2K_DEFAULT_COUNT;
607
608 keygen_data.hash_algorithm[0] = mh_alg;
609 keygen_data.count = S2K_DEFAULT_COUNT;
610 keygen_data.salt = d->s2k.salt;
611 keygen_data.salt_size = 8;
612
613 mcrypt_randomize(d->s2k.salt, 8, 0);
614 ret = mhash_keygen_ext(mh_keymode, keygen_data, d->key,
615 DIM (d->key), pass, strlen(pass));
616 if (ret < 0)
617 err_quit(_("mhash_keygen_ext() failed.\n"));
618 d->hd = mcrypt_module_open(algo, NULL, mode, NULL);
619 if (d->hd == MCRYPT_FAILED)
620 err_quit(_("Could not open module\n"));
621 return d;
622 }
623
624
625 int
symkey_enc_decode(const USTRING dat,DEK ** ret_dek)626 symkey_enc_decode(const USTRING dat, DEK **ret_dek)
627 {
628 DEK *d;
629 int tag = 0, headlen = 0, offset = 0;
630
631 assert(dat->len > 0);
632
633 header_decode(dat->d, &tag, &headlen, &offset, NULL);
634 if (tag != PKT_SYMKEY_ENC)
635 return PGP_ERR_PKT;
636 if (headlen < 3)
637 return PGP_ERR_PKT;
638 if (dat->d[offset++] != 4)
639 return PGP_ERR_PKT; /* invalid version */
640
641 d = _mcrypt_calloc(1, sizeof *d);
642 d->algo = _mcrypt_algid_to_algo(dat->d[offset++]);
643 d->s2k.mode = _mhash_keygen(dat->d[offset++]);
644 d->s2k.algo = _mhash_algo(dat->d[offset++]);
645 if (d->s2k.mode != KEYGEN_S2K_SIMPLE) {
646 memcpy(d->s2k.salt, dat->d + offset, 8);
647 offset += 8;
648 }
649 if (d->s2k.mode == KEYGEN_S2K_ISALTED)
650 d->s2k.count = dat->d[offset++];
651 *ret_dek = d;
652
653 /* in order to print the proper algorithm later. */
654 algorithm = d->algo;
655 keymode = _mhash_keymode2str(d->s2k.mode, d->s2k.algo);
656 mode = DEFAULT_PGP_MODE; /* no other options */
657
658 return 0;
659 }
660
661
662 USTRING
symkey_enc_encode(const DEK * dek)663 symkey_enc_encode(const DEK *dek)
664 {
665 USTRING result;
666 int pos = 0;
667 uchar buf[16];
668
669 assert(dek->keylen > 0);
670
671 buf[pos++] = (0x80 | 0x40 | PKT_SYMKEY_ENC);
672 buf[pos++] = 4; /* length */
673 buf[pos++] = 4; /* version */
674 buf[pos++] = _mcrypt_algo_to_algid(dek->algo);
675 buf[pos++] = _mhash_keygen_to_rfc2440(dek->s2k.mode);
676 buf[pos++] = _mhash_algo_to_rfc2440(dek->s2k.algo);
677 if (dek->s2k.mode != KEYGEN_S2K_SIMPLE) {
678 memcpy(buf+pos, dek->s2k.salt, 8);
679 pos += 8;
680 buf[1] += 8;
681 }
682 if (dek->s2k.mode == KEYGEN_S2K_ISALTED) {
683 buf[pos++] = dek->s2k.count;
684 buf[1] += 1;
685 }
686 result = make_ustring(buf, pos);
687 result->len = pos;
688 return result;
689 }
690
691
692 USTRING
read_partial(const uchar * buf,size_t blen,size_t pktlen)693 read_partial(const uchar *buf, size_t blen, size_t pktlen)
694 {
695 USTRING dat;
696 uchar data[2048];
697 int pos = 0, partial = 1;
698 PACKET pkt;
699
700 memset( &pkt, 0, sizeof(pkt));
701
702 dat = make_ustring(NULL, blen);
703 while (pktlen > 0) {
704 /*fprintf( stderr, "ptklen=%d pos=%d blen=%d partial=%d llen=%d\n",
705 pktlen, pos, blen, partial, length_len( pktlen, &pkt) );*/
706 while (pktlen > 2048 && pos < blen) {
707 memcpy(data, buf, 2048);
708 memcpy(dat->d + pos, data, 2048);
709 pos += 2048;
710 buf += 2048; pktlen -= 2048;
711 }
712 if (pktlen > 0 && pos < blen) {
713 memcpy(data, buf, pktlen);
714 memcpy(dat->d + pos, data, pktlen);
715 pos += pktlen;
716 buf += pktlen; pktlen -= pktlen;
717 }
718 if (!partial)
719 break;
720 else {
721 memset(&pkt, 0, sizeof (pkt));
722 pktlen = length_decode(buf, 0, &pkt);
723 buf += length_len(pktlen, &pkt);
724 partial = pkt.blockmode;
725 }
726 }
727 dat->len = pos;
728 return dat;
729 }
730
731 int
encrypted_decode(const DEK * dek,const USTRING dat,USTRING * result)732 encrypted_decode(const DEK *dek, const USTRING dat, USTRING *result)
733 {
734 int rc, nprefix;
735 uint32 tag = 0, headlen = 0, offset = 0;
736 uchar rndprefix[18], encprefix[18];
737 PACKET pkt;
738 USTRING t = NULL, p = NULL;
739
740 memset(&pkt, 0, sizeof(pkt));
741
742 assert(dat->len > 0);
743 header_decode(dat->d, &tag, &headlen, &offset, &pkt);
744
745 if (tag != PKT_ENCRYPTED)
746 return PGP_ERR_PKT;
747 if (dat->len < dek->blocklen + 3)
748 return PGP_ERR_PKT; /* wrong len */
749 if (!pkt.blockmode && (dat->len-1-length_len(headlen, &pkt)) != headlen)
750 return PGP_ERR_PKT; /* moderately malformed */
751
752 rc = mcrypt_generic_init(dek->hd, (uchar *)&dek->key, dek->keylen, NULL);
753 if (rc < 0)
754 err_quit(_("mcrypt_generic_init() failed\n"));
755
756 nprefix = dek->blocklen;
757 memcpy(encprefix, dat->d + offset, nprefix + 2);
758 _mcrypt_decrypt(dek->hd, rndprefix, nprefix + 2,
759 dat->d + offset, nprefix + 2);
760 offset += (nprefix + 2);
761
762 /* Note that we don't decrypt the whole thing at once;
763 if 7 != 9 or 8 != 10 then we immediately stop */
764 if (rndprefix[nprefix] != rndprefix[nprefix-2] ||
765 rndprefix[nprefix+1] != rndprefix[nprefix-1]) {
766 err_warn(_("decryption: wrong key.\n"));
767 return PGP_ERR_GENERAL;
768 }
769 _mcrypt_sync(dek->hd, encprefix, dek->blocklen);
770
771 if (!pkt.blockmode) {
772 t = make_ustring( dat->d+offset, dat->len - offset); /* xxx */
773
774 _mcrypt_decrypt(dek->hd, t->d, t->len, NULL, 0);
775 }
776 else {
777 p = read_partial(dat->d + (offset - (nprefix+2)),
778 dat->len - (offset - (nprefix+2)), headlen);
779 if (!p || !p->len) {
780 *result = NULL;
781 return PGP_ERR_GENERAL;
782 }
783 t = make_ustring(p->d + (nprefix+2), p->len - (nprefix+2));
784 _mcrypt_decrypt(dek->hd, t->d, t->len, NULL, 0);
785 free(p); p=NULL;
786 }
787 *result = t;
788 return 0;
789 }
790
791
792 USTRING
encrypted_encode(const USTRING pt,const DEK * dek)793 encrypted_encode(const USTRING pt, const DEK *dek)
794 {
795 USTRING ct, result;
796 uchar rndpref[18], lenbuf[5], lensize;
797 int pos, rc;
798
799 assert(pt->len > 0);
800
801 rc = mcrypt_generic_init(dek->hd, (uchar *)&dek->key, dek->keylen, NULL);
802 if (rc < 0)
803 err_quit( _("mcrypt_generic_init() failed\n") );
804
805 mcrypt_randomize(rndpref, dek->blocklen, real_random_flag);
806 rndpref[dek->blocklen] = rndpref[dek->blocklen - 2];
807 rndpref[dek->blocklen + 1] = rndpref[dek->blocklen - 1];
808 _mcrypt_encrypt(dek->hd, rndpref, dek->blocklen + 2, NULL, 0);
809 _mcrypt_sync(dek->hd, rndpref, dek->blocklen);
810
811 ct = make_ustring( rndpref, 2 * pt->len); /* xxx */
812 pos = dek->blocklen + 2;
813
814 _mcrypt_encrypt(dek->hd, ct->d + pos, pt->len, pt->d, pt->len);
815 ct->len = (pos += pt->len);
816 pos = 0;
817
818 result = make_ustring( NULL, ct->len + 8); /* xxx */
819 result->d[pos++] = (0x80 | 0x40 | PKT_ENCRYPTED);
820 length_encode(ct->len, lenbuf, &lensize);
821 memcpy(result->d + pos, lenbuf, lensize);
822 pos += lensize;
823
824 memcpy(result->d + pos, ct->d, ct->len);
825 result->len = ct->len + pos;
826 free(ct);
827
828 return result;
829 }
830
831
832 static int
do_compress(int algo,int flush,uchar * inbuf,size_t insize,USTRING * ret_out)833 do_compress(int algo, int flush, uchar *inbuf, size_t insize,
834 USTRING *ret_out)
835 {
836 #ifdef HAVE_LIBZ
837 uchar buf[4096];
838 int pos = 0, len = 0;
839 int zrc = 0;
840 z_stream *zs = NULL;
841 USTRING out = NULL;
842
843 zs = _mcrypt_calloc( 1, sizeof *zs );
844 zrc = (algo == 1)? deflateInit2(zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
845 -13, openpgp_z, Z_DEFAULT_STRATEGY):
846 deflateInit(zs, Z_DEFAULT_COMPRESSION);
847 if (zrc)
848 goto leave;
849
850 zs->next_in = inbuf;
851 zs->avail_in = insize;
852
853 do {
854 zs->next_out = buf;
855 zs->avail_out = sizeof(buf);
856 zrc = deflate( zs, flush );
857 if ( zrc == Z_STREAM_END ) {
858 deflateEnd( zs );
859 if ( zs->avail_out ) {
860 len = sizeof(buf) - zs->avail_out;
861 out = realloc_ustring( out, len );
862 memcpy( out->d + pos, buf, len );
863 pos += len;
864 break;
865 }
866 }
867 if ( zrc == Z_OK ) {
868 len = sizeof(buf) - zs->avail_out;
869 out = realloc_ustring( out, len );
870 memcpy( out->d + pos, buf, len );
871 pos += len;
872 }
873
874 if ( zrc ) {
875 if ( zs->msg )
876 fprintf( stderr, _("zlib error `%s'.\n"), zs->msg );
877 fprintf( stderr, _("compress: deflate returned %d.\n"), zrc );
878 }
879 } while ( zs->avail_out == 0 );
880
881 leave:
882 *ret_out = out;
883 free( zs );
884 if ( zrc == Z_OK || zrc == Z_STREAM_END )
885 zrc = 0;
886 return zrc;
887 #else
888 return 0;
889 #endif
890 } /* do_compress */
891
892 USTRING
compressed_encode(const USTRING dat,int algo)893 compressed_encode( const USTRING dat, int algo )
894 {
895 #ifdef HAVE_LIBZ
896 USTRING result = NULL, z = NULL;
897 int rc = 0;
898
899 assert( dat->len );
900 rc = do_compress( algo, Z_NO_FLUSH, dat->d, dat->len, &z );
901 if ( !rc )
902 rc = do_compress( algo, Z_FINISH, dat->d, dat->len, &z );
903 if ( rc )
904 goto leave;
905
906 result = make_ustring( NULL, z->len + 8); /* xxx */
907 result->len = z->len + 3;
908 result->d[0] = (0x80 | 0x40 | PKT_COMPRESSED);
909 result->d[1] = 0;
910 result->d[2] = algo;
911 memcpy( result->d + 3, z->d, z->len );
912
913 leave:
914 free( z );
915 return result;
916 #else
917 return NULL;
918 #endif
919 } /* compressed_encode */
920
921 static int
do_uncompress(int algo,uchar * inbuf,size_t insize,USTRING * ret_out)922 do_uncompress( int algo, uchar *inbuf, size_t insize, USTRING *ret_out )
923 {
924 #ifdef HAVE_LIBZ
925 USTRING out = NULL;
926 z_stream *zs = NULL;
927 uchar buf[4096];
928 int pos = 0, len = 0;
929 int zrc = 0;
930
931 zs = _mcrypt_calloc( 1, sizeof *zs );
932 zrc = ( algo == 1 )? inflateInit2( zs, -13 ) : inflateInit( zs );
933 if ( zrc )
934 goto leave;
935
936 zs->next_in = inbuf;
937 zs->avail_in = insize;
938
939 do {
940 zs->next_out = buf;
941 zs->avail_out = sizeof(buf);
942
943 zrc = inflate( zs, Z_SYNC_FLUSH );
944 if ( zrc == Z_STREAM_END ) {
945 inflateEnd( zs );
946 if ( zs->avail_out ) {
947 len = sizeof(buf) - zs->avail_out;
948 out = realloc_ustring( out, len );
949 memcpy( out->d + pos, buf, len );
950 out->len = (pos += len);
951 /*fprintf( stderr, "DBG: end len=%d pos=%d\n", len, pos );*/
952 }
953 break;
954 }
955 if ( zrc == Z_OK ) {
956 len = sizeof(buf) - zs->avail_out;
957 out = realloc_ustring( out, len );
958 memcpy( out->d + pos, buf, len );
959 out->len = (pos += len);
960 /*fprintf( stderr, "DBG: ok len=%d pos=%d\n", len, pos );*/
961 }
962 if ( zrc ) {
963 if ( zs->msg )
964 fprintf( stderr, _("zlib error `%s'.\n"), zs->msg );
965 fprintf( stderr, _("uncompress: inflate returned %d.\n"), zrc );
966 break;
967 }
968 } while ( 1 );
969
970 leave:
971 *ret_out = out;
972 free( zs );
973 if ( zrc == Z_OK || zrc == Z_STREAM_END )
974 zrc = 0;
975 return zrc;
976 #else
977 return 0;
978 #endif
979 } /* do_uncompress */
980
981 int
compressed_decode(const USTRING zip,USTRING * result)982 compressed_decode( const USTRING zip, USTRING *result )
983 {
984 #ifdef HAVE_LIBZ
985 uint32 tag = 0, headlen = 0, offset = 0;
986 USTRING t = NULL;
987 int rc = 0;
988
989 assert( zip->len );
990 header_decode( zip->d, &tag, &headlen, &offset, NULL );
991
992 if ( tag != PKT_COMPRESSED )
993 return PGP_ERR_PKT;
994 if ( zip->d[offset] != 1 && zip->d[offset] != 2 )
995 return PGP_ERR_PKT;
996
997 err_info( _("Will decompress input file.\n") );
998 rc = do_uncompress( zip->d[offset], zip->d + offset + 1,
999 zip->len - offset - 1, &t );
1000 *result = t;
1001
1002 return rc;
1003 #else
1004 return 0;
1005 #endif
1006 } /* compressed_decode */
1007
1008
1009 int
pgp_encrypt_file(const char * infile,const char * outfile,char * pass)1010 pgp_encrypt_file(const char *infile, const char *outfile, char *pass)
1011 {
1012 USTRING t = NULL, pt = NULL, sym = NULL, enc = NULL, zip = NULL;
1013 DEK *dek = NULL;
1014 FILE *fp = NULL;
1015 uchar *buf = NULL, tmp[16*1024];
1016 size_t len = 0, nread = 0;
1017 int tag=0;
1018
1019 if (!infile || *infile == '-') {
1020 while (!feof(stdin)) {
1021 nread = fread(tmp, 1, DIM (tmp), stdin);
1022 if (nread > 0) {
1023 t = realloc_ustring (t, nread);
1024 memcpy (t->d + len, tmp, nread);
1025 }
1026 len += nread;
1027 }
1028 fp = stdout;
1029 }
1030 else {
1031 fp = fopen(outfile, "wb");
1032 if (fp == NULL)
1033 return PGP_ERR_FILE;
1034 buf = file_to_buf(infile, 0, &len);
1035 if (!buf) {
1036 fclose (fp);
1037 return PGP_ERR_FILE;
1038 }
1039 t = make_ustring(buf, len);
1040 }
1041 tag = get_pkt_tag(t->d, NULL);
1042 free(buf);
1043 dek = dek_create(pgp_get_algo(algorithm), pass);
1044 sym = symkey_enc_encode(dek);
1045 fwrite(sym->d, 1, sym->len, fp);
1046 free(sym);
1047 total_bytes += t->len; /* increase input bytes */
1048
1049 pt = plaintext_encode(t);
1050 free(t);
1051 #ifdef HAVE_LIBZ
1052 if (openpgp_z > 0 && tag == -1 && pt && len > 32) {
1053 err_info( _("Output file will be compressed.\n") );
1054 zip = compressed_encode(pt, 1);
1055 free(pt);
1056 }
1057 else zip = pt;
1058 #else
1059 zip = pt;
1060 #endif
1061 if (zip) {
1062 enc = encrypted_encode(zip, dek);
1063 free(zip);
1064 }
1065 if (enc) {
1066 fwrite(enc->d, 1, enc->len, fp);
1067 free(enc);
1068 }
1069 dek_free(dek);
1070 if (fp != stdout)
1071 fclose(fp);
1072 else
1073 fflush (fp);
1074 return 0;
1075 }
1076
1077 int
pgp_decrypt_file(const char * infile,const char * outfile,char * pass)1078 pgp_decrypt_file(const char *infile, const char *outfile, char *pass)
1079 {
1080 USTRING r = NULL, dat = NULL, pt = NULL, result = NULL;
1081 uchar *buf = NULL, tmp[16*1024];
1082 const uchar *p;
1083 DEK *dek = NULL;
1084 PACKET pkt;
1085 uint32 off = 0, tag = 0, len = 0;
1086 size_t flen = 0, nread;
1087 int rc = 0;
1088 FILE *fp;
1089
1090 memset(&pkt, 0, sizeof(pkt));
1091
1092 if (!infile || *infile == '-') {
1093 while (!feof(stdin)) {
1094 nread = fread(tmp, 1, DIM (tmp), stdin);
1095 if (nread) {
1096 buf = realloc(buf, flen + nread);
1097 memcpy(buf + flen, tmp, nread);
1098 }
1099 flen += nread;
1100 }
1101 }
1102 else {
1103 buf = file_to_buf(infile, 0, &flen);
1104 if (!buf)
1105 return PGP_ERR_FILE;
1106 }
1107 total_bytes = flen;
1108 p = buf;
1109 while (flen > 0) {
1110 memset(&pkt, 0, sizeof (pkt));
1111 header_decode(p, &tag, &len, &off, &pkt);
1112 switch (tag) {
1113 case PKT_SYMKEY_ENC:
1114 r = make_ustring(p, len + off);
1115 rc = symkey_enc_decode(r, &dek);
1116 free (r);
1117 /*fprintf(stderr, "symkey_enc_decode=%d\n", rc);*/
1118 if (rc) {
1119 free (buf);
1120 return rc;
1121 }
1122 dek_load(dek, pass);
1123 break;
1124
1125 case PKT_ENCRYPTED:
1126 r = make_ustring(p, flen);
1127 rc = encrypted_decode(dek, r, &dat);
1128 /*fprintf(stderr, "encrypted=%d\n", rc);*/
1129 free(r);
1130 if (rc) {
1131 free (buf);
1132 return rc;
1133 }
1134 flen = 0; /* automatic EOF */
1135 break;
1136
1137 default:
1138 /*fprintf(stderr, "tag=%d\n", tag);*/
1139 free (buf);
1140 return PGP_ERR_PKT;
1141 }
1142 if (flen > 0) {
1143 p += (len + off);
1144 flen -= (len + off);
1145 }
1146 }
1147 free(buf);
1148 dek_free(dek);
1149 if (!dat)
1150 return PGP_ERR_FILE;
1151
1152 if (get_pkt_tag(dat->d, NULL) == PKT_COMPRESSED) {
1153 rc = compressed_decode(dat, &pt);
1154 /*fprintf(stderr,"compressed=%d\n",rc);*/
1155 free(dat);
1156 if (rc)
1157 return rc;
1158 }
1159 else
1160 pt = dat;
1161
1162 if (get_pkt_tag(pt->d, NULL) != PKT_PLAINTEXT) {
1163 err_warn(_("Unsupported OpenPGP packet!\n"));
1164 free (pt);
1165 }
1166 rc = plaintext_decode(pt, &result);
1167 free (pt);
1168 /*fprintf(stderr,"plaintext=%d\n", rc);*/
1169 if (rc)
1170 return rc;
1171
1172 if (!outfile)
1173 fp = stdout;
1174 else {
1175 fp = fopen(outfile, "wb");
1176 if (fp == NULL) {
1177 free(result);
1178 return PGP_ERR_FILE;
1179 }
1180 }
1181 fwrite(result->d, 1, result->len, fp);
1182 free(result);
1183 if (outfile)
1184 fclose(fp);
1185 else
1186 fflush (fp);
1187 return 0;
1188 }
1189
1190