tpgpcreat.c - mixmaster - mixmaster 3.0 patched for libressl
HTML git clone git://parazyd.org/mixmaster.git
DIR Log
DIR Files
DIR Refs
DIR README
---
tpgpcreat.c (20018B)
---
1 /* Mixmaster version 3.0 -- (C) 1999 - 2006 Anonymizer Inc. and others.
2
3 Mixmaster may be redistributed and modified under certain conditions.
4 This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
5 ANY KIND, either express or implied. See the file COPYRIGHT for
6 details.
7
8 Create OpenPGP packets
9 $Id: pgpcreat.c 934 2006-06-24 13:40:39Z rabbi $ */
10
11
12 #include "mix3.h"
13 #ifdef USE_PGP
14 #include "pgp.h"
15 #include "crypto.h"
16 #include <assert.h>
17 #include <time.h>
18 #include <string.h>
19
20 int pgp_packet(BUFFER *in, int type)
21 {
22 int ctb;
23 BUFFER *out;
24
25 out = buf_new();
26 if (type > 15) {
27 ctb = 0xC0 | type; /* make v4 packet */
28 buf_setc(out, ctb);
29 if (in->length > 8383) {
30 buf_appendc(out, 0xFF);
31 buf_appendl(out, in->length);
32 } else if (in->length > 191) {
33 #if 0
34 buf_appendc(out, ((in->length-192) >> 8) + 192);
35 buf_appendc(out, (in->length-192) & 0xFF);
36 #else /* end of 0 */
37 buf_appendi(out, in->length - 0xC0 + 0xC000);
38 #endif /* else if not 0 */
39 } else {
40 buf_appendc(out, in->length);
41 }
42 } else {
43 ctb = 128 + (type << 2);
44 if (in->length < 256 && type != PGP_PUBKEY && type != PGP_SECKEY &&
45 type != PGP_SIG && type != PGP_PUBSUBKEY && type != PGP_SECSUBKEY
46 #ifdef MIMIC
47 && type != PGP_ENCRYPTED
48 #endif /* MIMIC */
49 ) {
50 buf_setc(out, ctb);
51 buf_appendc(out, in->length);
52 }
53 #ifndef MIMIC
54 else if (in->length < 65536)
55 #else /* end of not MIMIC */
56 else if ((type == PGP_PUBKEY || type == PGP_SECKEY || type == PGP_SIG
57 || type == PGP_SESKEY || type == PGP_PUBSUBKEY ||
58 type == PGP_SECSUBKEY) && in->length < 65536)
59 #endif /* else if MIMIC */
60 {
61 buf_appendc(out, ctb | 1);
62 buf_appendi(out, in->length);
63 } else {
64 buf_appendc(out, ctb | 2);
65 buf_appendl(out, in->length);
66 }
67 }
68 buf_cat(out, in);
69 buf_move(in, out);
70 buf_free(out);
71 return (0);
72 }
73
74 int pgp_subpacket(BUFFER *in, int type)
75 {
76 BUFFER *out;
77 int len;
78
79 out = buf_new();
80 len = in->length + 1;
81 if (len < 192)
82 buf_setc(out, len);
83 else {
84 buf_setc(out, 255);
85 buf_appendl(out, len);
86 }
87 buf_appendc(out, type);
88 buf_cat(out, in);
89 buf_move(in, out);
90 buf_free(out);
91 return (0);
92 }
93
94 int pgp_packet3(BUFFER *in, int type)
95 {
96 #ifdef MIMIC
97 int ctb;
98 BUFFER *out;
99
100 out = buf_new();
101 ctb = 128 + (type << 2);
102 buf_setc(out, ctb | 3);
103 buf_cat(out, in);
104 buf_move(in, out);
105 buf_free(out);
106 return (0);
107 #else /* end of MIMIC */
108 return pgp_packet(in, type);
109 #endif /* else if not MIMIC */
110 }
111
112 #ifdef USE_IDEA
113 static int pgp_ideaencrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc)
114 {
115 byte iv[8];
116 int i, n = 0;
117 IDEA_KEY_SCHEDULE ks;
118 SHA_CTX c;
119
120 assert(key->length == 17);
121
122 for (i = 0; i < 8; i++)
123 iv[i] = 0;
124
125 idea_set_encrypt_key(key->data + 1, &ks);
126
127 if (mdc) {
128 mdc = 1;
129 out->data[0] = 1;
130 }
131 rnd_bytes(out->data + mdc, 8);
132 out->data[8 + mdc] = out->data[6 + mdc], out->data[9 + mdc] = out->data[7 + mdc];
133 if (mdc) {
134 SHA1_Init(&c);
135 SHA1_Update(&c, out->data + 1, 10);
136 SHA1_Update(&c, in->data, in->length);
137 }
138 n = 0;
139 idea_cfb64_encrypt(out->data + mdc, out->data + mdc, 10, &ks, iv, &n, IDEA_ENCRYPT);
140 if (!mdc) {
141 iv[6] = iv[0], iv[7] = iv[1];
142 memcpy(iv, out->data + 2, 6);
143 n = 0;
144 }
145 idea_cfb64_encrypt(in->data, out->data + 10 + mdc, in->length, &ks, iv, &n,
146 IDEA_ENCRYPT);
147 if (mdc) {
148 SHA1_Update(&c, "\xD3\x14", 2); /* 0xD3 = 0xC0 | PGP_MDC */
149 idea_cfb64_encrypt("\xD3\x14", out->data + 11 + in->length, 2, &ks, iv, &n,
150 IDEA_ENCRYPT);
151 SHA1_Final(out->data + 13 + in->length, &c);
152 idea_cfb64_encrypt(out->data + 13 + in->length, out->data + 13 + in->length, 20, &ks, iv, &n,
153 IDEA_ENCRYPT);
154 }
155 return (0);
156 }
157 #endif /* USE_IDEA */
158
159 static int pgp_3desencrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc)
160 {
161 DES_cblock iv;
162 int i, n = 0;
163 DES_key_schedule ks1;
164 DES_key_schedule ks2;
165 DES_key_schedule ks3;
166 SHA_CTX c;
167
168 assert(key->length == 25);
169
170 for (i = 0; i < 8; i++)
171 iv[i] = 0;
172
173 DES_set_key((const_DES_cblock *) (key->data + 1), &ks1);
174 DES_set_key((const_DES_cblock *) (key->data + 9), &ks2);
175 DES_set_key((const_DES_cblock *) (key->data+ 17), &ks3);
176
177 if (mdc) {
178 mdc = 1;
179 out->data[0] = 1;
180 }
181 rnd_bytes(out->data + mdc, 8);
182 out->data[8 + mdc] = out->data[6 + mdc], out->data[9 + mdc] = out->data[7 + mdc];
183 if (mdc) {
184 SHA1_Init(&c);
185 SHA1_Update(&c, out->data + 1, 10);
186 SHA1_Update(&c, in->data, in->length);
187 }
188 n = 0;
189 DES_ede3_cfb64_encrypt(out->data + mdc, out->data + mdc, 10, &ks1, &ks2, &ks3, &iv, &n,
190 ENCRYPT);
191 if (!mdc) {
192 iv[6] = iv[0], iv[7] = iv[1];
193 memcpy(iv, out->data + 2, 6);
194 n = 0;
195 }
196 DES_ede3_cfb64_encrypt(in->data, out->data + 10 + mdc, in->length, &ks1, &ks2, &ks3,
197 &iv, &n, ENCRYPT);
198 if (mdc) {
199 SHA1_Update(&c, "\xD3\x14", 2); /* 0xD3 = 0xC0 | PGP_MDC */
200 DES_ede3_cfb64_encrypt("\xD3\x14", out->data + 11 + in->length, 2, &ks1, &ks2, &ks3,
201 &iv, &n, ENCRYPT);
202 SHA1_Final(out->data + 13 + in->length, &c);
203 DES_ede3_cfb64_encrypt(out->data + 13 + in->length, out->data + 13 + in->length, 20, &ks1, &ks2, &ks3,
204 &iv, &n, ENCRYPT);
205 }
206 return (0);
207 }
208
209 static int pgp_castencrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc)
210 {
211 byte iv[8];
212 int i, n = 0;
213 CAST_KEY ks;
214 SHA_CTX c;
215
216 assert(key->length == 17);
217
218 for (i = 0; i < 8; i++)
219 iv[i] = 0;
220
221 CAST_set_key(&ks, 16, key->data + 1);
222
223 if (mdc) {
224 mdc = 1;
225 out->data[0] = 1;
226 }
227 rnd_bytes(out->data + mdc, 8);
228 out->data[8 + mdc] = out->data[6 + mdc], out->data[9 + mdc] = out->data[7 + mdc];
229 if (mdc) {
230 SHA1_Init(&c);
231 SHA1_Update(&c, out->data + 1, 10);
232 SHA1_Update(&c, in->data, in->length);
233 }
234 n = 0;
235 CAST_cfb64_encrypt(out->data + mdc, out->data + mdc, 10, &ks, iv, &n, CAST_ENCRYPT);
236 if (!mdc) {
237 iv[6] = iv[0], iv[7] = iv[1];
238 memcpy(iv, out->data + 2, 6);
239 n = 0;
240 }
241 CAST_cfb64_encrypt(in->data, out->data + 10 + mdc, in->length, &ks, iv, &n,
242 CAST_ENCRYPT);
243 if (mdc) {
244 SHA1_Update(&c, "\xD3\x14", 2); /* 0xD3 = 0xC0 | PGP_MDC */
245 CAST_cfb64_encrypt("\xD3\x14", out->data + 11 + in->length, 2, &ks, iv, &n,
246 CAST_ENCRYPT);
247 SHA1_Final(out->data + 13 + in->length, &c);
248 CAST_cfb64_encrypt(out->data + 13 + in->length, out->data + 13 + in->length, 20, &ks, iv, &n,
249 CAST_ENCRYPT);
250 }
251 return (0);
252 }
253
254 static int pgp_bfencrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc)
255 {
256 byte iv[8];
257 int i, n = 0;
258 BF_KEY ks;
259 SHA_CTX c;
260
261 assert(key->length == 17);
262
263 for (i = 0; i < 8; i++)
264 iv[i] = 0;
265
266 BF_set_key(&ks, 16, key->data + 1);
267
268 if (mdc) {
269 mdc = 1;
270 out->data[0] = 1;
271 }
272 rnd_bytes(out->data + mdc, 8);
273 out->data[8 + mdc] = out->data[6 + mdc], out->data[9 + mdc] = out->data[7 + mdc];
274 if (mdc) {
275 SHA1_Init(&c);
276 SHA1_Update(&c, out->data + 1, 10);
277 SHA1_Update(&c, in->data, in->length);
278 }
279 n = 0;
280 BF_cfb64_encrypt(out->data + mdc, out->data + mdc, 10, &ks, iv, &n, BF_ENCRYPT);
281 if (!mdc) {
282 iv[6] = iv[0], iv[7] = iv[1];
283 memcpy(iv, out->data + 2, 6);
284 n = 0;
285 }
286 BF_cfb64_encrypt(in->data, out->data + 10 + mdc, in->length, &ks, iv, &n,
287 BF_ENCRYPT);
288 if (mdc) {
289 SHA1_Update(&c, "\xD3\x14", 2); /* 0xD3 = 0xC0 | PGP_MDC */
290 BF_cfb64_encrypt("\xD3\x14", out->data + 11 + in->length, 2, &ks, iv, &n,
291 BF_ENCRYPT);
292 SHA1_Final(out->data + 13 + in->length, &c);
293 BF_cfb64_encrypt(out->data + 13 + in->length, out->data + 13 + in->length, 20, &ks, iv, &n,
294 BF_ENCRYPT);
295 }
296 return (0);
297 }
298
299 #ifdef USE_AES
300 static int pgp_aesencrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc)
301 {
302 byte iv[16];
303 int i, n = 0;
304 AES_KEY ks;
305 SHA_CTX c;
306
307 assert(key->length == 17 || key->length == 25 || key->length == 33);
308
309 for (i = 0; i < 16; i++)
310 iv[i] = 0;
311
312 AES_set_encrypt_key(key->data + 1, (key->length-1)<<3, &ks);
313
314 if (mdc) {
315 mdc = 1;
316 out->data[0] = 1;
317 }
318 rnd_bytes(out->data + mdc, 16);
319 out->data[16 + mdc] = out->data[14 + mdc], out->data[17 + mdc] = out->data[15 + mdc];
320 if (mdc) {
321 SHA1_Init(&c);
322 SHA1_Update(&c, out->data + 1, 18);
323 SHA1_Update(&c, in->data, in->length);
324 }
325 n = 0;
326 AES_cfb128_encrypt(out->data + mdc, out->data + mdc, 18, &ks, iv, &n, AES_ENCRYPT);
327 if (!mdc) {
328 iv[14] = iv[0], iv[15] = iv[1];
329 memcpy(iv, out->data + 2, 14);
330 n = 0;
331 }
332 AES_cfb128_encrypt(in->data, out->data + 18 + mdc, in->length, &ks, iv, &n,
333 AES_ENCRYPT);
334 if (mdc) {
335 SHA1_Update(&c, "\xD3\x14", 2); /* 0xD3 = 0xC0 | PGP_MDC */
336 AES_cfb128_encrypt("\xD3\x14", out->data + 19 + in->length, 2, &ks, iv, &n,
337 AES_ENCRYPT);
338 SHA1_Final(out->data + 21 + in->length, &c);
339 AES_cfb128_encrypt(out->data + 21 + in->length, out->data + 21 + in->length, 20, &ks, iv, &n,
340 AES_ENCRYPT);
341 }
342 return (0);
343 }
344 #endif /* USE_AES */
345
346 int pgp_symmetric(BUFFER *in, BUFFER *key, int mdc)
347 {
348 BUFFER *out;
349 int sym;
350
351 out = buf_new();
352 if (pgp_blocklen(sym = buf_getc(key)) > 8)
353 mdc = 1; /* force MDC for AES */
354 buf_prepare(out, in->length + (mdc?(1+2+22):2) + pgp_blocklen(sym));
355 switch (sym) {
356 #ifdef USE_IDEA
357 case PGP_K_IDEA:
358 pgp_ideaencrypt(in, out, key, mdc);
359 break;
360 #endif /* USE_IDEA */
361 #ifdef USE_AES
362 case PGP_K_AES128:
363 case PGP_K_AES192:
364 case PGP_K_AES256:
365 pgp_aesencrypt(in, out, key, mdc);
366 break;
367 #endif /* USE_AES */
368 case PGP_K_3DES:
369 pgp_3desencrypt(in, out, key, mdc);
370 break;
371 case PGP_K_CAST5:
372 pgp_castencrypt(in, out, key, mdc);
373 break;
374 case PGP_K_BF:
375 pgp_bfencrypt(in, out, key, mdc);
376 break;
377 default:
378 errlog(ERRORMSG, "Unknown symmetric algorithm.\n");
379 }
380 pgp_packet(out, mdc?PGP_ENCRYPTEDMDC:PGP_ENCRYPTED);
381
382 buf_move(in, out);
383 buf_free(out);
384 return (0);
385 }
386
387 int pgp_literal(BUFFER *b, char *filename, int text)
388 {
389 BUFFER *out;
390 BUFFER *line;
391
392 if (filename == NULL)
393 filename = "stdin";
394
395 if (strlen(filename) > 255)
396 return (-1);
397
398 out = buf_new();
399 line = buf_new();
400
401 if (text)
402 buf_setc(out, 't');
403 else
404 buf_setc(out, 'b');
405 buf_appendc(out, strlen(filename));
406 buf_appends(out, filename);
407 buf_appendl(out, 0); /* timestamp */
408
409 if (b->length > 0) {
410 if (text)
411 while (buf_getline(b, line) != -1) {
412 buf_cat(out, line);
413 buf_appends(out, "\r\n");
414 } else
415 buf_cat(out, b);
416 }
417 pgp_packet(out, PGP_LITERAL);
418 buf_move(b, out);
419 buf_free(out);
420 buf_free(line);
421
422 return (0);
423 }
424
425 int pgp_compress(BUFFER *in)
426 {
427 int err;
428 BUFFER *out;
429
430 out = buf_new();
431 buf_setc(out, 1);
432 err = buf_zip(out, in, 13);
433 if (err == 0) {
434 pgp_packet3(out, PGP_COMPRESSED);
435 buf_move(in, out);
436 }
437 buf_free(out);
438 return (err);
439 }
440
441 int pgp_sessionkey(BUFFER *out, BUFFER *user, BUFFER *keyid, BUFFER *seskey,
442 char *pubring)
443 {
444 BUFFER *encrypt, *key, *id;
445 int algo, sym, err = -1;
446 int i, csum = 0;
447 int tempbuf = 0;
448
449 encrypt = buf_new();
450 key = buf_new();
451 id = buf_new();
452 if (keyid == NULL) {
453 keyid = buf_new();
454 tempbuf = 1;
455 }
456 sym = seskey->data[0];
457 if ((algo = pgpdb_getkey(PK_ENCRYPT, PGP_ANY, &sym, NULL, NULL, key, user, NULL, keyid,
458 pubring, NULL)) == -1)
459 goto end;
460
461 buf_setc(out, 3); /* type */
462 buf_cat(out, keyid);
463 buf_appendc(out, algo); /* algorithm */
464
465 buf_set(encrypt, seskey);
466
467 for (i = 1; i < encrypt->length; i++)
468 csum = (csum + encrypt->data[i]) % 65536;
469 buf_appendi(encrypt, csum);
470
471 switch (algo) {
472 case PGP_ES_RSA:
473 err = pgp_rsa(encrypt, key, PK_ENCRYPT);
474 mpi_put(out, encrypt);
475 break;
476 case PGP_E_ELG:
477 err = pgp_elgencrypt(encrypt, key);
478 buf_cat(out, encrypt);
479 break;
480 default:
481 errlog(NOTICE, "Unknown encryption algorithm.\n");
482 err = -1;
483 goto end;
484 }
485 if (err == -1) {
486 errlog(ERRORMSG, "Encryption failed!\n");
487 goto end;
488 }
489 pgp_packet(out, PGP_SESKEY);
490 end:
491 if (tempbuf)
492 buf_free(keyid);
493 buf_free(id);
494 buf_free(encrypt);
495 buf_free(key);
496 return (err);
497 }
498
499 void pgp_marker(BUFFER *out)
500 {
501 buf_clear(out);
502 buf_append(out, "PGP", 3);
503 pgp_packet(out, PGP_MARKER);
504 }
505
506 int pgp_symsessionkey(BUFFER *out, BUFFER *seskey, BUFFER *pass)
507 {
508 BUFFER *key;
509 int sym;
510 key = buf_new();
511
512 sym = seskey->data[0];
513 buf_setc(out, 4); /* version */
514 #ifdef MIMICPGP5
515 pgp_makesk(out, key, sym, 1, PGP_H_MD5, pass);
516 #else /* end of MIMICPGP5 */
517 pgp_makesk(out, key, sym, 3, PGP_H_SHA1, pass);
518 #endif /* else if not MIMICPGP5 */
519 if (seskey->length > 1)
520 buf_cat(out, seskey);
521 else {
522 buf_setc(seskey, sym);
523 buf_cat(seskey, key);
524 }
525 pgp_packet(out, PGP_SYMSESKEY);
526 buf_free(key);
527 return (0);
528 }
529
530 int pgp_digest(int hashalgo, BUFFER *in, BUFFER *d)
531 {
532 switch (hashalgo) {
533 case PGP_H_MD5:
534 digest_md5(in, d);
535 return (0);
536 case PGP_H_SHA1:
537 digest_sha1(in, d);
538 return (0);
539 case PGP_H_RIPEMD:
540 digest_rmd160(in, d);
541 return (0);
542 default:
543 return (-1);
544 }
545 }
546
547 int asnprefix(BUFFER *b, int hashalgo)
548 {
549 switch (hashalgo) {
550 case PGP_H_MD5:
551 buf_append(b, MD5PREFIX, sizeof(MD5PREFIX) - 1);
552 return (0);
553 case PGP_H_SHA1:
554 buf_append(b, SHA1PREFIX, sizeof(SHA1PREFIX) - 1);
555 return (0);
556 default:
557 return (-1);
558 }
559 }
560
561 int pgp_expandsk(BUFFER *key, int skalgo, int hashalgo, BUFFER *data)
562 {
563 BUFFER *temp;
564 int keylen;
565 int err = 0;
566 temp = buf_new();
567
568 keylen = pgp_keylen(skalgo);
569 buf_clear(key);
570 while (key->length < keylen) {
571 if (pgp_digest(hashalgo, data, temp) == -1) {
572 err = -1;
573 goto end;
574 }
575 buf_cat(key, temp);
576
577 buf_setc(temp, 0);
578 buf_cat(temp, data);
579 buf_move(data, temp);
580 }
581
582 if (key->length > keylen) {
583 buf_set(temp, key);
584 buf_get(temp, key, keylen);
585 }
586 end:
587 buf_free(temp);
588 return(err);
589 }
590
591 int pgp_makesk(BUFFER *out, BUFFER *key, int sym, int type, int hash,
592 BUFFER *pass)
593 {
594 int err = 0;
595 BUFFER *salted;
596 salted = buf_new();
597
598 buf_appendc(out, sym);
599 buf_appendc(out, type);
600 buf_appendc(out, hash);
601 switch (type) {
602 case 0:
603 buf_set(salted, pass);
604 break;
605 case 1:
606 buf_appendrnd(salted, 8); /* salt */
607 buf_cat(out, salted);
608 buf_cat(salted, pass);
609 break;
610 case 3:
611 buf_appendrnd(salted, 8); /* salt */
612 buf_cat(out, salted);
613 buf_appendc(out, 96); /* encoded count value 65536 */
614 pgp_iteratedsk(salted, salted, pass, 96);
615 break;
616 default:
617 err = -1;
618 }
619 pgp_expandsk(key, sym, hash, salted);
620 buf_free(salted);
621 return (err);
622 }
623
624 /* PGP/MIME needs to know the hash algorithm */
625 int pgp_signhashalgo(BUFFER *algo, BUFFER *userid, char *secring, BUFFER *pass)
626 {
627 int pkalgo;
628
629 pkalgo = pgpdb_getkey(PK_SIGN, PGP_ANY, NULL, NULL, NULL, NULL, userid, NULL, NULL,
630 secring, pass);
631 if (pkalgo == PGP_S_DSA)
632 buf_sets(algo, "sha1");
633 if (pkalgo == PGP_ES_RSA)
634 buf_sets(algo, "md5");
635 return (pkalgo > 0 ? 0 : -1);
636 }
637
638 int pgp_sign(BUFFER *msg, BUFFER *msg2, BUFFER *sig, BUFFER *userid,
639 BUFFER *pass, int type, int self, long now, int remail,
640 BUFFER *keypacket, char *secring)
641 /* msg: data to be signed (buffer is modified)
642 msg2: additional data to be signed for certain sig types
643 sig: signature is placed here
644 userid: select signing key
645 pass: pass phrase for signing key
646 type: PGP signature type
647 self: is this a self-signature?
648 now: time of signature creation
649 remail: is this an anonymous message?
650 keypacket: signature key
651 secring: key ring with signature key */
652 {
653 BUFFER *key, *id, *d, *sub, *enc;
654 int algo, err = -1;
655 int version = 3, hashalgo;
656 int type1;
657
658 id = buf_new();
659 d = buf_new();
660 sub = buf_new();
661 enc = buf_new();
662 key = buf_new();
663
664 if (now == 0) {
665 now = time(NULL);
666 if (remail)
667 now -= rnd_number(4 * 24 * 60 * 60);
668 }
669 if (keypacket) {
670 buf_rewind(keypacket);
671 algo = pgp_getkey(PK_SIGN, PGP_ANY, NULL, NULL, NULL, keypacket, key, id, NULL, pass);
672 } else
673 algo = pgpdb_getkey(PK_SIGN, PGP_ANY, NULL, NULL, NULL, key, userid, NULL, id, secring,
674 pass);
675 if (algo <= -1) {
676 err = algo;
677 goto end;
678 }
679 if (algo == PGP_S_DSA || algo == PGP_E_ELG)
680 version = 4;
681 if (version == 3)
682 hashalgo = PGP_H_MD5;
683 else
684 hashalgo = PGP_H_SHA1;
685
686 if (!self && type != PGP_SIG_BINDSUBKEY)
687 version = 3;
688
689 switch (type) {
690 case PGP_SIG_CERT:
691 case PGP_SIG_CERT1:
692 case PGP_SIG_CERT2:
693 case PGP_SIG_CERT3:
694 type1 = pgp_getpacket(msg, d) == PGP_PUBKEY;
695 assert (type1);
696 buf_setc(msg, 0x99);
697 buf_appendi(msg, d->length);
698 buf_cat(msg, d);
699
700 pgp_getpacket(msg2, d);
701 switch (version) {
702 case 3:
703 buf_cat(msg, d);
704 break;
705 case 4:
706 buf_appendc(msg, 0xb4);
707 buf_appendl(msg, d->length);
708 buf_cat(msg, d);
709 break;
710 }
711 break;
712 case PGP_SIG_BINDSUBKEY:
713 type1 = pgp_getpacket(msg, d) == PGP_PUBKEY;
714 assert (type1);
715 buf_clear(msg);
716 buf_appendc(msg, 0x99);
717 buf_appendi(msg, d->length);
718 buf_cat(msg, d);
719
720 type1 = pgp_getpacket(msg2, d) == PGP_PUBSUBKEY;
721 assert (type1);
722 buf_appendc(msg, 0x99);
723 buf_appendi(msg, d->length);
724 buf_cat(msg, d);
725 break;
726 case PGP_SIG_BINARY:
727 break;
728 case PGP_SIG_CANONIC:
729 pgp_sigcanonic(msg);
730 break;
731 default:
732 NOT_IMPLEMENTED;
733 }
734 switch (version) {
735 case 3:
736 buf_set(d, msg);
737 buf_appendc(d, type);
738 buf_appendl(d, now);
739 pgp_digest(hashalgo, d, d);
740 if (algo == PGP_ES_RSA)
741 asnprefix(enc, hashalgo);
742 buf_cat(enc, d);
743 err = pgp_dosign(algo, enc, key);
744
745 buf_setc(sig, version);
746 buf_appendc(sig, 5);
747 buf_appendc(sig, type);
748 buf_appendl(sig, now);
749 buf_cat(sig, id);
750 buf_appendc(sig, algo);
751 buf_appendc(sig, hashalgo);
752 buf_append(sig, d->data, 2);
753 buf_cat(sig, enc);
754 break;
755
756 case 4:
757 buf_setc(sig, version);
758 buf_appendc(sig, type);
759 buf_appendc(sig, algo);
760 buf_appendc(sig, hashalgo);
761
762 buf_clear(d);
763 buf_appendl(d, now);
764 pgp_subpacket(d, PGP_SUB_CREATIME);
765 buf_cat(sub, d);
766
767 if (self || type == PGP_SIG_BINDSUBKEY) {
768 /* until we can handle the case where our pgp keys expire, don't create keys that expire */
769 if (0 && KEYLIFETIME) { /* add key expirtaion time */
770 buf_clear(d);
771 buf_appendl(d, KEYLIFETIME);
772 pgp_subpacket(d, PGP_SUB_KEYEXPIRETIME);
773 buf_cat(sub, d);
774 }
775 }
776
777 if (self) {
778 buf_setc(d, PGP_K_CAST5);
779 #ifdef USE_AES
780 buf_appendc(d, PGP_K_AES128);
781 #endif /* USE_AES */
782 buf_appendc(d, PGP_K_3DES);
783 pgp_subpacket(d, PGP_SUB_PSYMMETRIC);
784 buf_cat(sub, d);
785
786 buf_setc(d, 0x01); /* now we support MDC, so we can add MDC flag */
787 pgp_subpacket(d, PGP_SUB_FEATURES);
788 buf_cat(sub, d);
789 }
790
791 buf_appendi(sig, sub->length); /* hashed subpacket length */
792 buf_cat(sig, sub);
793
794 /* compute message digest */
795 buf_set(d, msg);
796 buf_cat(d, sig);
797 buf_appendc(d, version);
798 buf_appendc(d, 0xff);
799 buf_appendl(d, sig->length);
800 pgp_digest(hashalgo, d, d);
801
802 pgp_subpacket(id, PGP_SUB_ISSUER);
803 buf_appendi(sig, id->length); /* unhashed subpacket length */
804 buf_cat(sig, id);
805
806 buf_append(sig, d->data, 2);
807
808 if (algo == PGP_ES_RSA)
809 asnprefix(enc, hashalgo);
810 buf_cat(enc, d);
811 err = pgp_dosign(algo, enc, key);
812 buf_cat(sig, enc);
813 break;
814 }
815 pgp_packet(sig, PGP_SIG);
816
817 end:
818 buf_free(key);
819 buf_free(id);
820 buf_free(d);
821 buf_free(sub);
822 buf_free(enc);
823 return (err);
824 }
825
826 int pgp_pubkeycert(BUFFER *userid, char *keyring, BUFFER *pass,
827 BUFFER *out, int remail)
828 {
829 BUFFER *key;
830 KEYRING *r;
831 int err = -1;
832
833 key = buf_new();
834 r = pgpdb_open(keyring, pass, 0, PGP_TYPE_UNDEFINED);
835 if (r != NULL)
836 while (pgpdb_getnext(r, key, NULL, userid) != -1) {
837 if (pgp_makepubkey(key, NULL, out, pass, 0) != -1)
838 err = 0;
839 }
840 if (err == 0)
841 pgp_armor(out, remail);
842 else
843 buf_clear(out);
844 buf_free(key);
845 return (err);
846 }
847
848 #endif /* USE_PGP */