/[pkg-mixmaster]/trunk/Mix/Src/pgpdata.c
ViewVC logotype

Contents of /trunk/Mix/Src/pgpdata.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download)
Wed Oct 31 08:19:51 2001 UTC (11 years, 6 months ago) by rabbi
File MIME type: text/plain
File size: 26036 byte(s)
Initial revision
1 /* Mixmaster version 3 -- (C) 1999 Anonymizer Inc.
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 OpenPGP data
9 $Id: pgpdata.c,v 1.1 2001/10/31 08:19:53 rabbi Exp $ */
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 <time.h>
19
20 int pgp_keylen(int symalgo)
21 {
22 switch (symalgo) {
23 case PGP_K_IDEA:
24 case PGP_K_CAST5:
25 case PGP_K_BF:
26 return (16);
27 case PGP_K_3DES:
28 return (24);
29 default:
30 return (-1);
31 }
32 }
33
34 int mpi_get(BUFFER *b, BUFFER *mpi)
35 {
36 int l;
37
38 l = buf_geti(b);
39 buf_clear(mpi);
40
41 if (l <= 0 || b->ptr + (l + 7) / 8 > b->length)
42 return (-1);
43 buf_get(b, mpi, (l + 7) / 8);
44 return (l);
45 }
46
47 int l;
48 int i;
49
50 int mpi_bitcount(BUFFER *mpi)
51 {
52 int l = mpi->length * 8;
53 for (i = 7; i >= 0; i--)
54 if (((mpi->data[0] >> i) & 1) == 1) {
55 l -= 7 - i;
56 break;
57 }
58 return l;
59 }
60
61 int mpi_put(BUFFER *b, BUFFER *mpi)
62 {
63 buf_appendi(b, mpi_bitcount(mpi));
64 buf_cat(b, mpi);
65 return (0);
66 }
67
68 int skcrypt(BUFFER *data, int skalgo, BUFFER *key, BUFFER *iv, int enc)
69 {
70 switch (skalgo) {
71 case 0:
72 return (0);
73 #ifdef USE_IDEA
74 case PGP_K_IDEA:
75 return (buf_ideacrypt(data, key, iv, enc));
76 #endif
77 case PGP_K_3DES:
78 return (buf_3descrypt(data, key, iv, enc));
79 case PGP_K_BF:
80 return (buf_bfcrypt(data, key, iv, enc));
81 case PGP_K_CAST5:
82 return (buf_castcrypt(data, key, iv, enc));
83 default:
84 return (-1);
85 }
86 }
87
88 int pgp_csum(BUFFER *key, int start)
89 {
90 int i, csum = 0;
91 for (i = start; i < key->length; i++)
92 csum = (csum + key->data[i]) % 65536;
93 return (csum);
94 }
95
96 #ifdef USE_RSA
97 int pgp_rsa(BUFFER *in, BUFFER *k, int mode)
98 {
99 BUFFER *mpi, *out;
100 int err = -1;
101 RSA *key;
102
103 assert(mode == PK_ENCRYPT || mode == PK_VERIFY || mode == PK_DECRYPT
104 || mode == PK_SIGN);
105 key = RSA_new();
106 out = buf_new();
107 mpi = buf_new();
108
109 mpi_get(k, mpi);
110 key->n = BN_bin2bn(mpi->data, mpi->length, NULL);
111
112 if (mpi_get(k, mpi) < 0)
113 goto end;
114 key->e = BN_bin2bn(mpi->data, mpi->length, NULL);
115
116 if (mode == PK_DECRYPT || mode == PK_SIGN) {
117 if (mpi_get(k, mpi) < 0)
118 goto end;
119 key->d = BN_bin2bn(mpi->data, mpi->length, NULL);
120
121 #if 1
122 /* compute auxiluary parameters */
123 mpi_get(k, mpi); /* PGP'p is SSLeay's q */
124 key->q = BN_bin2bn(mpi->data, mpi->length, NULL);
125
126 mpi_get(k, mpi);
127 key->p = BN_bin2bn(mpi->data, mpi->length, NULL);
128
129 if (mpi_get(k, mpi) < 0)
130 goto end;
131 key->iqmp = BN_bin2bn(mpi->data, mpi->length, NULL);
132
133 {
134 BIGNUM *i;
135 BN_CTX *ctx;
136
137 ctx = BN_CTX_new();
138 i = BN_new();
139 key->dmp1 = BN_new();
140 key->dmq1 = BN_new();
141
142 BN_sub(i, key->p, BN_value_one());
143 BN_mod(key->dmp1, key->d, i, ctx);
144
145 BN_sub(i, key->q, BN_value_one());
146 BN_mod(key->dmq1, key->d, i, ctx);
147
148 BN_free(i);
149 }
150 #endif
151 }
152 buf_prepare(out, RSA_size(key));
153
154 switch (mode) {
155 case PK_ENCRYPT:
156 out->length = RSA_public_encrypt(in->length, in->data, out->data, key,
157 RSA_PKCS1_PADDING);
158 break;
159 case PK_VERIFY:
160 out->length = RSA_public_decrypt(in->length, in->data, out->data, key,
161 RSA_PKCS1_PADDING);
162 break;
163 case PK_SIGN:
164 out->length = RSA_private_encrypt(in->length, in->data, out->data, key,
165 RSA_PKCS1_PADDING);
166 break;
167 case PK_DECRYPT:
168 out->length = RSA_private_decrypt(in->length, in->data, out->data, key,
169 RSA_PKCS1_PADDING);
170 break;
171 }
172 if (out->length == -1)
173 err = -1, out->length = 0;
174 else
175 err = 0;
176
177 buf_move(in, out);
178 end:
179 RSA_free(key);
180 buf_free(out);
181 buf_free(mpi);
182 return (err);
183 }
184 #endif
185
186 /* Contrary to RFC 2440, old PGP versions use this for clearsign only.
187 * If the text is included in the OpenPGP message, the application will
188 * typically provide the text in the proper format (whatever that is);
189 * we use "canonic" format so everybody will be able to read our messages.
190 * In clearsigned messages, trailing whitespace is always ignored.
191 * Detached signatures are the problematic case. For PGP/MIME, we always
192 * escape trailing whitespace as quoted-printable.
193 */
194 void pgp_sigcanonic(BUFFER *msg)
195 {
196 BUFFER *line, *out;
197
198 out = buf_new();
199 line = buf_new();
200
201 while (buf_getline(msg, line) != -1) {
202 while (line->length > 0 && (line->data[line->length - 1] == ' '
203 #if 0
204 || line->data[line->length - 1] == '\t'
205 #endif
206 ))
207 line->length--;
208 line->data[line->length] = '\0';
209 buf_cat(out, line);
210 buf_appends(out, "\r\n");
211 }
212 buf_move(msg, out);
213 buf_free(out);
214 buf_free(line);
215 }
216
217 static void mpi_bnput(BUFFER *o, BIGNUM *i)
218 {
219 BUFFER *b;
220
221 b = buf_new();
222 buf_prepare(b, BN_num_bytes(i));
223 b->length = BN_bn2bin(i, b->data);
224 mpi_put(o, b);
225 buf_free(b);
226 }
227
228 static void mpi_bnputenc(BUFFER *o, BIGNUM *i, int ska, BUFFER *key,
229 BUFFER *iv)
230 {
231 BUFFER *b;
232
233 b = buf_new();
234 buf_prepare(b, BN_num_bytes(i));
235 b->length = BN_bn2bin(i, b->data);
236 buf_appendi(o, mpi_bitcount(b));
237 if (key && key->length)
238 skcrypt(b, ska, key, iv, ENCRYPT);
239 buf_cat(o, b);
240 buf_free(b);
241 }
242
243 static int getski(BUFFER *p, BUFFER *pass, BUFFER *key, BUFFER *iv)
244 {
245 int skalgo;
246 BUFFER *salt, *temp;
247
248 if (!pass)
249 return(-1);
250
251 salt = buf_new();
252 temp = buf_new();
253
254 skalgo = buf_getc(p);
255 switch (skalgo) {
256 case 0:
257 /* none */
258 goto end;
259 case 255:
260 /* S2K specifier */
261 skalgo = pgp_getsk(p, pass, key);
262 break;
263 default:
264 /* simple */
265 digest_md5(pass, key);
266 break;
267 }
268
269 buf_get(p, iv, 8);
270
271 end:
272 buf_free(salt);
273 buf_free(temp);
274 return (skalgo);
275 }
276
277 static void makeski(BUFFER *secret, BUFFER *pass, int remail)
278 {
279 BUFFER *out, *key, *iv;
280 out = buf_new();
281 key = buf_new();
282 iv = buf_new();
283 if (pass == NULL || pass->length == 0 || remail == 2) {
284 buf_appendc(out, 0);
285 buf_cat(out, secret);
286 } else {
287 buf_appendc(out, 255);
288 pgp_makesk(out, key, PGP_K_CAST5, 3, PGP_H_SHA1, pass);
289 buf_setrnd(iv, 8);
290 buf_cat(out, iv);
291 skcrypt(secret, PGP_K_CAST5, key, iv, 1);
292 buf_cat(out, secret);
293 }
294 buf_move(secret, out);
295 buf_free(out);
296 buf_free(key);
297 buf_free(iv);
298 }
299
300 int pgp_nummpi(int algo)
301 {
302 switch (algo) {
303 case PGP_ES_RSA:
304 return (2);
305 case PGP_S_DSA:
306 return (4);
307 case PGP_E_ELG:
308 return (3);
309 default:
310 return (0);
311 }
312 }
313
314 int pgp_numsecmpi(int algo)
315 {
316 switch (algo) {
317 case PGP_ES_RSA:
318 return (4);
319 case PGP_S_DSA:
320 return (1);
321 case PGP_E_ELG:
322 return (1);
323 default:
324 return (0);
325 }
326 }
327
328 /* store key's ID in keyid */
329 int pgp_keyid(BUFFER *key, BUFFER *keyid)
330 {
331 BUFFER *i, *k;
332 int version, algo, j, ptr;
333
334 i = buf_new();
335 k = buf_new();
336
337 ptr = key->ptr;
338 key->ptr = 0;
339 switch (version = buf_getc(key)) {
340 case 2:
341 case 3:
342 buf_getl(key);
343 buf_geti(key);
344 buf_getc(key);
345 mpi_get(key, i);
346 break;
347 case 4:
348 buf_appendc(k, version);
349 buf_appendl(k, buf_getl(key));
350 algo = buf_getc(key);
351 buf_appendc(k, algo);
352 if (pgp_nummpi(algo) == 0)
353 buf_rest(k, key); /* works for public keys only */
354 else
355 for (j = 0; j < pgp_nummpi(algo); j++) {
356 mpi_get(key, i);
357 mpi_put(k, i);
358 }
359 buf_clear(i);
360 buf_appendc(i, 0x99);
361 buf_appendi(i, k->length);
362 buf_cat(i, k);
363 digest_sha1(i, i);
364 break;
365 }
366 buf_clear(keyid);
367 buf_append(keyid, i->data + i->length - 8, 8);
368 buf_free(i);
369 buf_free(k);
370 key->ptr = ptr;
371 return(0);
372 }
373
374 static int pgp_iskeyid(BUFFER *key, BUFFER *keyid)
375 {
376 BUFFER *thisid;
377 int ret;
378
379 thisid = buf_new();
380 pgp_keyid(key, thisid);
381 ret = buf_eq(keyid, thisid);
382 buf_free(thisid);
383 return(ret);
384 }
385
386 int pgp_getkey(int mode, int algo, int *psym, BUFFER *keypacket, BUFFER *key,
387 BUFFER *keyid, BUFFER *userid, BUFFER *pass)
388 {
389 int tempbuf = 0;
390 int keytype = -1, type, j;
391 int thisalgo, version, skalgo;
392 int needsym = 0, symfound = 0;
393 BUFFER *p1, *iv, *sk, *i;
394 int csstart;
395
396 p1 = buf_new();
397 i = buf_new();
398 iv = buf_new();
399 sk = buf_new();
400 if (psym)
401 needsym = *psym;
402 if (keypacket == key) {
403 key = buf_new();
404 tempbuf = 1;
405 }
406 if (userid)
407 buf_clear(userid);
408
409 while ((type = pgp_getpacket(keypacket, p1)) > 0) {
410 switch (type) {
411 case PGP_SIG:
412 /* it is assumed that only valid keys have been imported */
413 if (buf_getc(p1) == 4) {
414 if (buf_getc(p1) == PGP_SIG_CERT) {
415 buf_getc(p1);
416 buf_getc(p1);
417 j = buf_geti(p1);
418 j += p1->ptr;
419 while (p1->ptr < j) {
420 int len, type, a;
421 len = buf_getc(p1);
422 if (len > 192 && len < 255)
423 len = (len - 192) * 256 + buf_getc(p1) + 192;
424 else if (len == 255)
425 len = buf_getl(p1);
426 type = buf_getc(p1);
427 buf_get(p1, i, len);
428 if (type == PGP_SUB_PSYMMETRIC)
429 while ((a = buf_getc(i)) != -1)
430 if ((a == PGP_K_3DES || a == PGP_K_CAST5
431 #ifdef USE_IDEA
432 || a == PGP_K_IDEA
433 #endif
434 ) && (a == needsym || needsym == 0)) {
435 symfound = a;
436 break;
437 }
438 }
439 }
440 }
441 break;
442 case PGP_USERID:
443 if (userid)
444 buf_move(userid, p1);
445 break;
446 case PGP_PUBSUBKEY:
447 case PGP_SECSUBKEY:
448 if (keytype != -1 && (mode == PK_SIGN || mode == PK_VERIFY))
449 continue;
450 case PGP_PUBKEY:
451 case PGP_SECKEY:
452 if ((type == PGP_PUBKEY || type == PGP_PUBSUBKEY) &&
453 (mode == PK_DECRYPT || mode == PK_SIGN))
454 continue;
455 keytype = type;
456 version = buf_getc(p1);
457 switch (version) {
458 case 2:
459 case 3:
460 buf_getl(p1); /* created */
461 buf_geti(p1); /* valid */
462 thisalgo = buf_getc(p1);
463 if (thisalgo != PGP_ES_RSA) {
464 keytype = -1;
465 goto end;
466 }
467 symfound = PGP_K_IDEA;
468 break;
469 case 4:
470 buf_appendc(key, version);
471 buf_appendl(key, buf_getl(p1));
472 thisalgo = buf_getc(p1);
473 buf_appendc(key, thisalgo);
474 if (symfound == 0)
475 symfound = PGP_K_3DES; /* default algorithm */
476 break;
477 default:
478 keytype = -1;
479 goto end;
480 }
481 if (algo != PGP_ANY && thisalgo != algo) {
482 keytype = -1;
483 continue;
484 }
485 if (keyid && keyid->length && !pgp_iskeyid(p1, keyid))
486 continue;
487 if (keyid);
488 pgp_keyid(p1, keyid);
489 if (key) {
490 buf_clear(key);
491 for (j = 0; j < pgp_nummpi(thisalgo); j++) {
492 if (mpi_get(p1, i) == -1)
493 goto end;
494 mpi_put(key, i);
495 }
496 if (keytype == PGP_SECKEY || keytype == PGP_SECSUBKEY) {
497 csstart = key->length;
498 skalgo = getski(p1, pass, sk, iv);
499 switch (version) {
500 case 2:
501 case 3:
502 for (j = 0; j < pgp_numsecmpi(thisalgo); j++) {
503 if (mpi_get(p1, i) == -1) {
504 keytype = -1;
505 goto end;
506 }
507 skcrypt(i, skalgo, sk, iv, DECRYPT);
508 mpi_put(key, i);
509 }
510 break;
511 case 4:
512 buf_clear(i);
513 buf_rest(i, p1);
514 skcrypt(i, skalgo, sk, iv, DECRYPT);
515 buf_move(p1, i);
516 for (j = 0; j < pgp_numsecmpi(thisalgo); j++) {
517 if (mpi_get(p1, i) == -1) {
518 keytype = PGP_PASS;
519 goto end;
520 }
521 mpi_put(key, i);
522 }
523 break;
524 }
525 if (pgp_csum(key, csstart) != buf_geti(p1)) {
526 keytype = PGP_PASS;
527 goto end;
528 }
529 }
530 }
531 break;
532 default:
533 /* ignore trust packets etc */
534 break;
535 }
536 }
537 end:
538 if (tempbuf) {
539 buf_move(keypacket, key);
540 buf_free(key);
541 }
542 buf_free(p1);
543 buf_free(i);
544 buf_free(iv);
545 buf_free(sk);
546 #ifndef USE_RSA
547 if (thisalgo == PGP_ES_RSA)
548 keytype = -1;
549 #endif
550 if (needsym > 0 && symfound != needsym)
551 keytype = -1;
552 else if (psym && *psym == 0)
553 *psym = symfound;
554
555 return (keytype <= 0 ? keytype : thisalgo);
556 }
557
558 int pgp_makepkpacket(int type, BUFFER *p, BUFFER *outtxt, BUFFER *out,
559 BUFFER *key, BUFFER *pass, time_t *created)
560 {
561 BUFFER *i, *id;
562 char txt[LINELEN], algoid;
563 int version, algo, valid = 0, err = 0;
564 int len, j;
565 struct tm *tc;
566
567 i = buf_new();
568 id = buf_new();
569
570 version = buf_getc(p);
571 buf_clear(key);
572 switch (version) {
573 case 2:
574 case 3:
575 *created = buf_getl(p);
576 valid = buf_geti(p);
577 algo = buf_getc(p);
578 if (algo != PGP_ES_RSA)
579 return(-1);
580 break;
581 case 4:
582 *created = buf_getl(p);
583 algo = buf_getc(p);
584 break;
585 default:
586 return(-1);
587 }
588
589 switch (version) {
590 case 2:
591 case 3:
592 buf_appendc(key, version);
593 buf_appendl(key, *created);
594 buf_appendi(key, valid);
595 buf_appendc(key, algo);
596 break;
597 case 4:
598 buf_appendc(key, version);
599 buf_appendl(key, *created);
600 buf_appendc(key, algo);
601 break;
602 }
603
604 pgp_keyid(p, id);
605 len = mpi_get(p, i);
606 mpi_put(key, i);
607 for (j = 1; j < pgp_nummpi(algo); j++) {
608 if (mpi_get(p, i) == -1) {
609 err = -1;
610 goto end;
611 }
612 mpi_put(key, i);
613 }
614 pgp_packet(key, type);
615 buf_cat(out, key);
616
617 if (outtxt != NULL) {
618 switch(algo) {
619 case PGP_ES_RSA:
620 algoid = 'R';
621 break;
622 case PGP_S_DSA:
623 algoid = 'D';
624 break;
625 case PGP_E_ELG:
626 algoid = 'g';
627 break;
628 default:
629 algoid = '?';
630 }
631 buf_appendf(outtxt, "%s %4d%c/%02X%02X%02X%02X ", type == PGP_PUBSUBKEY ?
632 "sub" : "pub", len, algoid,
633 id->data[4], id->data[5], id->data[6], id->data[7]);
634 tc = localtime(created);
635 strftime(txt, LINELEN, "%Y/%m/%d ", tc);
636 buf_appends(outtxt, txt);
637 }
638 end:
639 buf_free(i);
640 buf_free(id);
641 return(err == 0 ? algo : err);
642 }
643
644 int pgp_makepubkey(BUFFER *keypacket, BUFFER *outtxt, BUFFER *out,
645 BUFFER *pass, int keyalgo)
646 {
647 BUFFER *p, *pubkey, *seckey, *subkey, *sig, *tmp;
648 int err = -1, type, thisalgo;
649 time_t created;
650
651 p = buf_new();
652 seckey = buf_new();
653 pubkey = buf_new();
654 subkey = buf_new();
655 sig = buf_new();
656 tmp = buf_new();
657
658 buf_set(seckey, keypacket);
659 type = pgp_getpacket(keypacket, p);
660 if (type != PGP_SECKEY)
661 goto end;
662
663 thisalgo = pgp_makepkpacket(PGP_PUBKEY, p, outtxt, tmp, pubkey, pass,
664 &created);
665 if (thisalgo == -1 || (keyalgo != 0 && keyalgo != thisalgo))
666 goto end;
667 buf_cat(out, tmp);
668
669 while ((type = pgp_getpacket(keypacket, p)) > 0) {
670 if (type == PGP_SECSUBKEY) {
671 if (pgp_makepkpacket(PGP_PUBSUBKEY, p, outtxt, out, subkey, pass,
672 &created) == -1)
673 goto end;
674 if (pgp_sign(pubkey, subkey, sig, NULL, pass, PGP_SIG_BINDSUBKEY, 0,
675 created, 0, seckey, NULL) != -1)
676 buf_cat(out, sig);
677 if (outtxt)
678 buf_nl(outtxt);
679 } else if (type == PGP_USERID) {
680 if (outtxt != NULL) {
681 buf_cat(outtxt, p);
682 buf_nl(outtxt);
683 }
684 pgp_packet(p, PGP_USERID);
685 err = pgp_sign(pubkey, p, sig, NULL, pass, PGP_SIG_CERT, 1, created, 0,
686 seckey, NULL);
687 buf_cat(out, p);
688 if (err == 0)
689 buf_cat(out, sig);
690 } else if (type == PGP_PUBKEY || type == PGP_SECKEY)
691 break;
692 }
693 end:
694 buf_free(pubkey);
695 buf_free(seckey);
696 buf_free(subkey);
697 buf_free(sig);
698 buf_free(p);
699 buf_free(tmp);
700 return (err);
701 }
702
703 #ifdef USE_RSA
704 int pgp_rsakeygen(int bits, BUFFER *userid, BUFFER *pass, char *pubring,
705 char *secring, int remail)
706 /* remail==2: encrypt the secring */
707 {
708 RSA *k;
709 KEYRING *keydb;
710 BUFFER *pkey, *skey;
711 BUFFER *dk, *sig, *iv, *p;
712 long now;
713 int skalgo = 0;
714 int err = 0;
715
716 pkey = buf_new();
717 skey = buf_new();
718 iv = buf_new();
719 dk = buf_new();
720 p = buf_new();
721 sig = buf_new();
722
723 errlog(NOTICE, "Generating OpenPGP RSA key.\n");
724 k = RSA_generate_key(bits == 0 ? 1024 : bits, 3, NULL, NULL);
725 if (k == NULL) {
726 err = -1;
727 goto end;
728 }
729 now = time(NULL);
730 if (remail) /* fake time in nym keys */
731 now -= rnd_number(4 * 24 * 60 * 60);
732
733 buf_appendc(skey, 3);
734 buf_appendl(skey, now);
735 buf_appendi(skey, 0);
736 buf_appendc(skey, PGP_ES_RSA);
737 mpi_bnput(skey, k->n);
738 mpi_bnput(skey, k->e);
739
740 #ifdef USE_IDEA
741 if (pass != NULL && pass->length > 0 && remail != 2) {
742 skalgo = PGP_K_IDEA;
743 digest_md5(pass, dk);
744 buf_setrnd(iv, 8);
745 buf_appendc(skey, skalgo);
746 buf_cat(skey, iv);
747 }
748 else
749 #endif
750 buf_appendc(skey, 0);
751
752 mpi_bnputenc(skey, k->d, skalgo, dk, iv);
753 mpi_bnputenc(skey, k->q, skalgo, dk, iv);
754 mpi_bnputenc(skey, k->p, skalgo, dk, iv);
755 mpi_bnputenc(skey, k->iqmp, skalgo, dk, iv);
756
757 buf_clear(p);
758 mpi_bnput(p, k->d);
759 mpi_bnput(p, k->q);
760 mpi_bnput(p, k->p);
761 mpi_bnput(p, k->iqmp);
762 buf_appendi(skey, pgp_csum(p, 0));
763
764 pgp_packet(skey, PGP_SECKEY);
765 buf_set(p, userid);
766 pgp_packet(p, PGP_USERID);
767 buf_cat(skey, p);
768
769 if (secring == NULL)
770 secring = PGPREMSECRING;
771 keydb = pgpdb_open(secring, remail == 2 ? pass : NULL, 1);
772 if (keydb == NULL) {
773 err = -1;
774 goto end;
775 }
776 if (keydb->filetype == -1)
777 keydb->filetype = 0;
778 pgpdb_append(keydb, skey);
779 pgpdb_close(keydb);
780
781 if (pubring != NULL) {
782 if (pgp_makepubkey(skey, NULL, pkey, pass, 0) == -1)
783 goto end;
784 keydb = pgpdb_open(pubring, NULL, 1);
785 if (keydb == NULL)
786 goto end;
787 if (keydb->filetype == -1)
788 keydb->filetype = ARMORED;
789 pgpdb_append(keydb, pkey);
790 pgpdb_close(keydb);
791 }
792 end:
793 buf_free(pkey);
794 buf_free(skey);
795 buf_free(iv);
796 buf_free(dk);
797 buf_free(p);
798 buf_free(sig);
799 return (err);
800 }
801 #endif
802
803 #define begin_param "-----BEGIN PUBLIC PARAMETER BLOCK-----"
804 #define end_param "-----END PUBLIC PARAMETER BLOCK-----"
805
806 static void *params(int dsa, int bits)
807 {
808 DSA *k = NULL;
809 DH *d = NULL;
810 FILE *f;
811 BUFFER *p, *n;
812 char line[LINELEN];
813 byte b[1024];
814 int m, l;
815
816 if (bits == 0)
817 bits = 1024;
818 if (dsa && bits > 1024)
819 bits = 1024;
820
821 p = buf_new();
822 n = buf_new();
823 f = mix_openfile(dsa ? DSAPARAMS : DHPARAMS, "r");
824 if (f != NULL) {
825 for (;;) {
826 if (fgets(line, sizeof(line), f) == NULL)
827 break;
828 if (strleft(line, begin_param)) {
829 if (fgets(line, sizeof(line), f) == NULL)
830 break;
831 m = 0;
832 sscanf(line, "%d", &m);
833 if (bits == m) {
834 buf_clear(p);
835 while (fgets(line, sizeof(line), f) != NULL) {
836 if (strleft(line, end_param)) {
837 decode(p, p);
838 if (dsa) {
839 k = DSA_new();
840 l = buf_geti(p);
841 buf_get(p, n, l);
842 k->p = BN_bin2bn(n->data, n->length, NULL);
843 l = buf_geti(p);
844 buf_get(p, n, l);
845 k->q = BN_bin2bn(n->data, n->length, NULL);
846 l = buf_geti(p);
847 buf_get(p, n, l);
848 k->g = BN_bin2bn(n->data, n->length, NULL);
849 } else {
850 d = DH_new();
851 l = buf_geti(p);
852 buf_get(p, n, l);
853 d->p = BN_bin2bn(n->data, n->length, NULL);
854 l = buf_geti(p);
855 buf_get(p, n, l);
856 d->g = BN_bin2bn(n->data, n->length, NULL);
857 }
858 break;
859 }
860 buf_appends(p, line);
861 }
862 }
863 }
864 }
865 fclose(f);
866 }
867
868 buf_free(p);
869 buf_free(n);
870
871 if (dsa) {
872 if (k == NULL) {
873 errlog(NOTICE, "Generating DSA parameters.\n");
874 k = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
875 p = buf_new();
876 l = BN_bn2bin(k->p, b);
877 buf_appendi(p, l);
878 buf_append(p, b, l);
879 l = BN_bn2bin(k->q, b);
880 buf_appendi(p, l);
881 buf_append(p, b, l);
882 l = BN_bn2bin(k->g, b);
883 buf_appendi(p, l);
884 buf_append(p, b, l);
885 encode(p, 64);
886 f = mix_openfile(DSAPARAMS, "a");
887 fprintf(f, "%s\n%d\n", begin_param, bits);
888 buf_write(p, f);
889 fprintf(f, "%s\n", end_param);
890 fclose(f);
891 buf_free(p);
892 }
893 return (k);
894 } else {
895 if (d == NULL) {
896 errlog(NOTICE, "Generating DH parameters. (This may take a long time!)\n");
897 d = DH_generate_parameters(bits, DH_GENERATOR_5, NULL, NULL);
898 p = buf_new();
899 l = BN_bn2bin(d->p, b);
900 buf_appendi(p, l);
901 buf_append(p, b, l);
902 l = BN_bn2bin(d->g, b);
903 buf_appendi(p, l);
904 buf_append(p, b, l);
905 encode(p, 64);
906 f = mix_openfile(DHPARAMS, "a");
907 fprintf(f, "%s\n%d\n", begin_param, bits);
908 buf_write(p, f);
909 fprintf(f, "%s\n", end_param);
910 fclose(f);
911 buf_free(p);
912 }
913 return (d);
914 }
915 }
916
917 int pgp_dhkeygen(int bits, BUFFER *userid, BUFFER *pass, char *pubring,
918 char *secring, int remail)
919 /* remail==2: encrypt the secring */
920 {
921 DSA *s;
922 DH *e;
923 KEYRING *keydb;
924 BUFFER *pkey, *skey, *subkey, *secret;
925 BUFFER *dk, *sig, *iv, *p;
926 long now;
927 int err = 0;
928
929 pkey = buf_new();
930 skey = buf_new();
931 subkey = buf_new();
932 iv = buf_new();
933 dk = buf_new();
934 p = buf_new();
935 sig = buf_new();
936 secret = buf_new();
937
938 s = params(1, bits);
939 errlog(NOTICE, "Generating OpenPGP DSA key.\n");
940 if (s == NULL || DSA_generate_key(s) != 1) {
941 err = -1;
942 goto end;
943 }
944 e = params(0, bits);
945 errlog(NOTICE, "Generating OpenPGP ElGamal key.\n");
946 if (e == NULL || DH_generate_key(e) != 1) {
947 err = -1;
948 goto end;
949 }
950
951 now = time(NULL);
952 if (remail) /* fake time in nym keys */
953 now -= rnd_number(4 * 24 * 60 * 60);
954
955 /* DSA key */
956 buf_setc(skey, 4);
957 buf_appendl(skey, now);
958 buf_appendc(skey, PGP_S_DSA);
959 mpi_bnput(skey, s->p);
960 mpi_bnput(skey, s->q);
961 mpi_bnput(skey, s->g);
962 mpi_bnput(skey, s->pub_key);
963
964 mpi_bnput(secret, s->priv_key);
965 buf_appendi(secret, pgp_csum(secret, 0));
966 makeski(secret, pass, remail);
967 buf_cat(skey, secret);
968 pgp_packet(skey, PGP_SECKEY);
969
970 /* ElGamal key */
971 buf_setc(subkey, 4);
972 buf_appendl(subkey, now);
973 buf_appendc(subkey, PGP_E_ELG);
974 mpi_bnput(subkey, e->p);
975 mpi_bnput(subkey, e->g);
976 mpi_bnput(subkey, e->pub_key);
977
978 buf_clear(secret);
979 mpi_bnput(secret, e->priv_key);
980 buf_appendi(secret, pgp_csum(secret, 0));
981 makeski(secret, pass, remail);
982 buf_cat(subkey, secret);
983
984 buf_set(p, userid);
985 pgp_packet(p, PGP_USERID);
986 buf_cat(skey, p);
987
988 pgp_packet(subkey, PGP_SECSUBKEY);
989 buf_cat(skey, subkey);
990
991 if (secring == NULL)
992 secring = PGPREMSECRING;
993 keydb = pgpdb_open(secring, remail == 2 ? pass : NULL, 1);
994 if (keydb == NULL) {
995 err = -1;
996 goto end;
997 }
998 if (keydb->filetype == -1)
999 keydb->filetype = 0;
1000 pgpdb_append(keydb, skey);
1001 pgpdb_close(keydb);
1002
1003 if (pubring != NULL) {
1004 pgp_makepubkey(skey, NULL, pkey, pass, 0);
1005 keydb = pgpdb_open(pubring, NULL, 1);
1006 if (keydb == NULL)
1007 goto end;
1008 if (keydb->filetype == -1)
1009 keydb->filetype = ARMORED;
1010 pgpdb_append(keydb, pkey);
1011 pgpdb_close(keydb);
1012 }
1013 end:
1014 buf_free(pkey);
1015 buf_free(skey);
1016 buf_free(subkey);
1017 buf_free(iv);
1018 buf_free(dk);
1019 buf_free(p);
1020 buf_free(sig);
1021 buf_free(secret);
1022 return (err);
1023 }
1024
1025 int pgp_dsasign(BUFFER *data, BUFFER *key, BUFFER *out)
1026 {
1027 BUFFER *mpi, *b;
1028 DSA *d;
1029 DSA_SIG *sig = NULL;
1030
1031 d = DSA_new();
1032 b = buf_new();
1033 mpi = buf_new();
1034 mpi_get(key, mpi);
1035 d->p = BN_bin2bn(mpi->data, mpi->length, NULL);
1036 mpi_get(key, mpi);
1037 d->q = BN_bin2bn(mpi->data, mpi->length, NULL);
1038 mpi_get(key, mpi);
1039 d->g = BN_bin2bn(mpi->data, mpi->length, NULL);
1040 mpi_get(key, mpi);
1041 d->pub_key = BN_bin2bn(mpi->data, mpi->length, NULL);
1042 if (mpi_get(key, mpi) == -1) {
1043 goto end;
1044 }
1045 d->priv_key = BN_bin2bn(mpi->data, mpi->length, NULL);
1046
1047 sig = DSA_do_sign(data->data, data->length, d);
1048 if (sig) {
1049 buf_prepare(b, BN_num_bytes(sig->r));
1050 b->length = BN_bn2bin(sig->r, b->data);
1051 mpi_put(out, b);
1052 b->length = BN_bn2bin(sig->s, b->data);
1053 mpi_put(out, b);
1054 }
1055 end:
1056 buf_free(mpi);
1057 buf_free(b);
1058 DSA_SIG_free(sig);
1059 DSA_free(d);
1060 return(sig ? 0 : -1);
1061 }
1062
1063 int pgp_dosign(int algo, BUFFER *data, BUFFER *key)
1064 {
1065 int err;
1066 BUFFER *out, *r, *s;
1067
1068 out = buf_new();
1069 r = buf_new();
1070 s = buf_new();
1071 switch (algo) {
1072 #ifdef USE_RSA
1073 case PGP_ES_RSA:
1074 err = pgp_rsa(data, key, PK_SIGN);
1075 if (err == 0)
1076 mpi_put(out, data);
1077 break;
1078 #endif
1079 case PGP_S_DSA:
1080 err = pgp_dsasign(data, key, out);
1081 break;
1082 default:
1083 errlog(NOTICE, "Unknown encryption algorithm!\n");
1084 return (-1);
1085 }
1086 if (err == -1)
1087 errlog(ERRORMSG, "Signing operation failed!\n");
1088
1089 buf_move(data, out);
1090 buf_free(out);
1091 buf_free(r);
1092 buf_free(s);
1093 return (err);
1094 }
1095
1096 int pgp_elgdecrypt(BUFFER *in, BUFFER *key)
1097 {
1098 BIGNUM *a, *b, *c, *p, *g, *x;
1099 BN_CTX *ctx;
1100 BUFFER *i;
1101 int err = -1;
1102
1103 i = buf_new();
1104 ctx = BN_CTX_new();
1105 if (ctx == NULL) goto end;
1106 mpi_get(key, i);
1107 p = BN_bin2bn(i->data, i->length, NULL);
1108 mpi_get(key, i);
1109 g = BN_bin2bn(i->data, i->length, NULL);
1110 mpi_get(key, i); /* y */
1111 mpi_get(key, i);
1112 x = BN_bin2bn(i->data, i->length, NULL);
1113 mpi_get(in, i);
1114 a = BN_bin2bn(i->data, i->length, NULL);
1115 if (mpi_get(in, i) == -1)
1116 goto e1;
1117 b = BN_bin2bn(i->data, i->length, NULL);
1118 c = BN_new();
1119
1120 if (BN_mod_exp(c, a, x, p, ctx) == 0) goto end;
1121 if (BN_mod_inverse(a, c, p, ctx) == 0) goto end;
1122 if (BN_mod_mul(c, a, b, p, ctx) == 0) goto end;
1123
1124 buf_prepare(i, BN_num_bytes(c));
1125 i->length = BN_bn2bin(c, i->data);
1126
1127 buf_prepare(in, BN_num_bytes(c));
1128 in->length = RSA_padding_check_PKCS1_type_2(in->data, in->length, i->data,
1129 i->length, i->length + 1);
1130 if (in->length <= 0)
1131 in->length = 0;
1132 else
1133 err = 0;
1134
1135 end:
1136 BN_free(b);
1137 BN_free(c);
1138 e1:
1139 buf_free(i);
1140 BN_free(a);
1141 BN_free(p);
1142 BN_free(g);
1143 BN_clear_free(x);
1144 BN_CTX_free(ctx);
1145
1146 return (err);
1147 }
1148
1149 int pgp_elgencrypt(BUFFER *in, BUFFER *key)
1150 {
1151 BIGNUM *m, *k, *a, *b, *c, *p, *g, *y;
1152 BN_CTX *ctx;
1153 BUFFER *i;
1154 int err = -1;
1155
1156 i = buf_new();
1157 ctx = BN_CTX_new();
1158 if (ctx == NULL) goto end;
1159 mpi_get(key, i);
1160 p = BN_bin2bn(i->data, i->length, NULL);
1161 mpi_get(key, i);
1162 g = BN_bin2bn(i->data, i->length, NULL);
1163 if (mpi_get(key, i) == -1)
1164 goto e1;
1165 y = BN_bin2bn(i->data, i->length, NULL);
1166
1167 buf_prepare(i, BN_num_bytes(p));
1168 if (RSA_padding_add_PKCS1_type_2(i->data, i->length, in->data, in->length)
1169 != 1)
1170 goto end;
1171 m = BN_bin2bn(i->data, i->length, NULL);
1172
1173 k = BN_new();
1174 BN_rand(k, BN_num_bits(p), 0, 0);
1175
1176 a = BN_new();
1177 b = BN_new();
1178 c = BN_new();
1179
1180 if (BN_mod_exp(a, g, k, p, ctx) == 0) goto end;
1181 if (BN_mod_exp(c, y, k, p, ctx) == 0) goto end;
1182 if (BN_mod_mul(b, m, c, p, ctx) == 0) goto end;
1183
1184 buf_clear(in);
1185 i->length = BN_bn2bin(a, i->data);
1186 mpi_put(in, i);
1187 i->length = BN_bn2bin(b, i->data);
1188 mpi_put(in, i);
1189
1190 err = 0;
1191
1192 BN_free(a);
1193 BN_free(b);
1194 BN_free(c);
1195 BN_free(m);
1196 e1:
1197 buf_free(i);
1198 BN_free(p);
1199 BN_free(g);
1200 BN_free(y);
1201 BN_CTX_free(ctx);
1202 end:
1203
1204 return (err);
1205 }
1206
1207 #endif /* USE_PGP */

  ViewVC Help
Powered by ViewVC 1.1.5