/[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 51 - (show annotations) (download)
Sat Dec 15 00:34:21 2001 UTC (11 years, 6 months ago) by ulfm
File MIME type: text/plain
File size: 26126 byte(s)
Bug fix: use proper key id for ElGamal encryption.
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.2 2001/12/15 00:34:21 ulfm 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, *thiskeyid;
394 int csstart;
395
396 p1 = buf_new();
397 i = buf_new();
398 iv = buf_new();
399 sk = buf_new();
400 thiskeyid = buf_new();
401 if (psym)
402 needsym = *psym;
403 if (keypacket == key) {
404 key = buf_new();
405 tempbuf = 1;
406 }
407 if (userid)
408 buf_clear(userid);
409
410 while ((type = pgp_getpacket(keypacket, p1)) > 0) {
411 switch (type) {
412 case PGP_SIG:
413 /* it is assumed that only valid keys have been imported */
414 if (buf_getc(p1) == 4) {
415 if (buf_getc(p1) == PGP_SIG_CERT) {
416 buf_getc(p1);
417 buf_getc(p1);
418 j = buf_geti(p1);
419 j += p1->ptr;
420 while (p1->ptr < j) {
421 int len, type, a;
422 len = buf_getc(p1);
423 if (len > 192 && len < 255)
424 len = (len - 192) * 256 + buf_getc(p1) + 192;
425 else if (len == 255)
426 len = buf_getl(p1);
427 type = buf_getc(p1);
428 buf_get(p1, i, len);
429 if (type == PGP_SUB_PSYMMETRIC)
430 while ((a = buf_getc(i)) != -1)
431 if ((a == PGP_K_3DES || a == PGP_K_CAST5
432 #ifdef USE_IDEA
433 || a == PGP_K_IDEA
434 #endif
435 ) && (a == needsym || needsym == 0)) {
436 symfound = a;
437 break;
438 }
439 }
440 }
441 }
442 break;
443 case PGP_USERID:
444 if (userid)
445 buf_move(userid, p1);
446 break;
447 case PGP_PUBSUBKEY:
448 case PGP_SECSUBKEY:
449 if (keytype != -1 && (mode == PK_SIGN || mode == PK_VERIFY))
450 continue;
451 case PGP_PUBKEY:
452 case PGP_SECKEY:
453 if ((type == PGP_PUBKEY || type == PGP_PUBSUBKEY) &&
454 (mode == PK_DECRYPT || mode == PK_SIGN))
455 continue;
456 keytype = type;
457 version = buf_getc(p1);
458 switch (version) {
459 case 2:
460 case 3:
461 buf_getl(p1); /* created */
462 buf_geti(p1); /* valid */
463 thisalgo = buf_getc(p1);
464 if (thisalgo != PGP_ES_RSA) {
465 keytype = -1;
466 goto end;
467 }
468 symfound = PGP_K_IDEA;
469 break;
470 case 4:
471 buf_appendc(key, version);
472 buf_appendl(key, buf_getl(p1));
473 thisalgo = buf_getc(p1);
474 buf_appendc(key, thisalgo);
475 if (symfound == 0)
476 symfound = PGP_K_3DES; /* default algorithm */
477 break;
478 default:
479 keytype = -1;
480 goto end;
481 }
482 if (algo != PGP_ANY && thisalgo != algo) {
483 keytype = -1;
484 continue;
485 }
486 if (keyid && keyid->length && !pgp_iskeyid(p1, keyid))
487 continue;
488 pgp_keyid(p1, thiskeyid);
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 (keyid) buf_set(keyid, thiskeyid);
539 if (tempbuf) {
540 buf_move(keypacket, key);
541 buf_free(key);
542 }
543 buf_free(p1);
544 buf_free(i);
545 buf_free(iv);
546 buf_free(sk);
547 buf_free(thiskeyid);
548 #ifndef USE_RSA
549 if (thisalgo == PGP_ES_RSA)
550 keytype = -1;
551 #endif
552 if (needsym > 0 && symfound != needsym)
553 keytype = -1;
554 else if (psym && *psym == 0)
555 *psym = symfound;
556
557 return (keytype <= 0 ? keytype : thisalgo);
558 }
559
560 int pgp_makepkpacket(int type, BUFFER *p, BUFFER *outtxt, BUFFER *out,
561 BUFFER *key, BUFFER *pass, time_t *created)
562 {
563 BUFFER *i, *id;
564 char txt[LINELEN], algoid;
565 int version, algo, valid = 0, err = 0;
566 int len, j;
567 struct tm *tc;
568
569 i = buf_new();
570 id = buf_new();
571
572 version = buf_getc(p);
573 buf_clear(key);
574 switch (version) {
575 case 2:
576 case 3:
577 *created = buf_getl(p);
578 valid = buf_geti(p);
579 algo = buf_getc(p);
580 if (algo != PGP_ES_RSA)
581 return(-1);
582 break;
583 case 4:
584 *created = buf_getl(p);
585 algo = buf_getc(p);
586 break;
587 default:
588 return(-1);
589 }
590
591 switch (version) {
592 case 2:
593 case 3:
594 buf_appendc(key, version);
595 buf_appendl(key, *created);
596 buf_appendi(key, valid);
597 buf_appendc(key, algo);
598 break;
599 case 4:
600 buf_appendc(key, version);
601 buf_appendl(key, *created);
602 buf_appendc(key, algo);
603 break;
604 }
605
606 pgp_keyid(p, id);
607 len = mpi_get(p, i);
608 mpi_put(key, i);
609 for (j = 1; j < pgp_nummpi(algo); j++) {
610 if (mpi_get(p, i) == -1) {
611 err = -1;
612 goto end;
613 }
614 mpi_put(key, i);
615 }
616 pgp_packet(key, type);
617 buf_cat(out, key);
618
619 if (outtxt != NULL) {
620 switch(algo) {
621 case PGP_ES_RSA:
622 algoid = 'R';
623 break;
624 case PGP_S_DSA:
625 algoid = 'D';
626 break;
627 case PGP_E_ELG:
628 algoid = 'g';
629 break;
630 default:
631 algoid = '?';
632 }
633 buf_appendf(outtxt, "%s %4d%c/%02X%02X%02X%02X ", type == PGP_PUBSUBKEY ?
634 "sub" : "pub", len, algoid,
635 id->data[4], id->data[5], id->data[6], id->data[7]);
636 tc = localtime(created);
637 strftime(txt, LINELEN, "%Y/%m/%d ", tc);
638 buf_appends(outtxt, txt);
639 }
640 end:
641 buf_free(i);
642 buf_free(id);
643 return(err == 0 ? algo : err);
644 }
645
646 int pgp_makepubkey(BUFFER *keypacket, BUFFER *outtxt, BUFFER *out,
647 BUFFER *pass, int keyalgo)
648 {
649 BUFFER *p, *pubkey, *seckey, *subkey, *sig, *tmp;
650 int err = -1, type, thisalgo;
651 time_t created;
652
653 p = buf_new();
654 seckey = buf_new();
655 pubkey = buf_new();
656 subkey = buf_new();
657 sig = buf_new();
658 tmp = buf_new();
659
660 buf_set(seckey, keypacket);
661 type = pgp_getpacket(keypacket, p);
662 if (type != PGP_SECKEY)
663 goto end;
664
665 thisalgo = pgp_makepkpacket(PGP_PUBKEY, p, outtxt, tmp, pubkey, pass,
666 &created);
667 if (thisalgo == -1 || (keyalgo != 0 && keyalgo != thisalgo))
668 goto end;
669 buf_cat(out, tmp);
670
671 while ((type = pgp_getpacket(keypacket, p)) > 0) {
672 if (type == PGP_SECSUBKEY) {
673 if (pgp_makepkpacket(PGP_PUBSUBKEY, p, outtxt, out, subkey, pass,
674 &created) == -1)
675 goto end;
676 if (pgp_sign(pubkey, subkey, sig, NULL, pass, PGP_SIG_BINDSUBKEY, 0,
677 created, 0, seckey, NULL) != -1)
678 buf_cat(out, sig);
679 if (outtxt)
680 buf_nl(outtxt);
681 } else if (type == PGP_USERID) {
682 if (outtxt != NULL) {
683 buf_cat(outtxt, p);
684 buf_nl(outtxt);
685 }
686 pgp_packet(p, PGP_USERID);
687 err = pgp_sign(pubkey, p, sig, NULL, pass, PGP_SIG_CERT, 1, created, 0,
688 seckey, NULL);
689 buf_cat(out, p);
690 if (err == 0)
691 buf_cat(out, sig);
692 } else if (type == PGP_PUBKEY || type == PGP_SECKEY)
693 break;
694 }
695 end:
696 buf_free(pubkey);
697 buf_free(seckey);
698 buf_free(subkey);
699 buf_free(sig);
700 buf_free(p);
701 buf_free(tmp);
702 return (err);
703 }
704
705 #ifdef USE_RSA
706 int pgp_rsakeygen(int bits, BUFFER *userid, BUFFER *pass, char *pubring,
707 char *secring, int remail)
708 /* remail==2: encrypt the secring */
709 {
710 RSA *k;
711 KEYRING *keydb;
712 BUFFER *pkey, *skey;
713 BUFFER *dk, *sig, *iv, *p;
714 long now;
715 int skalgo = 0;
716 int err = 0;
717
718 pkey = buf_new();
719 skey = buf_new();
720 iv = buf_new();
721 dk = buf_new();
722 p = buf_new();
723 sig = buf_new();
724
725 errlog(NOTICE, "Generating OpenPGP RSA key.\n");
726 k = RSA_generate_key(bits == 0 ? 1024 : bits, 3, NULL, NULL);
727 if (k == NULL) {
728 err = -1;
729 goto end;
730 }
731 now = time(NULL);
732 if (remail) /* fake time in nym keys */
733 now -= rnd_number(4 * 24 * 60 * 60);
734
735 buf_appendc(skey, 3);
736 buf_appendl(skey, now);
737 buf_appendi(skey, 0);
738 buf_appendc(skey, PGP_ES_RSA);
739 mpi_bnput(skey, k->n);
740 mpi_bnput(skey, k->e);
741
742 #ifdef USE_IDEA
743 if (pass != NULL && pass->length > 0 && remail != 2) {
744 skalgo = PGP_K_IDEA;
745 digest_md5(pass, dk);
746 buf_setrnd(iv, 8);
747 buf_appendc(skey, skalgo);
748 buf_cat(skey, iv);
749 }
750 else
751 #endif
752 buf_appendc(skey, 0);
753
754 mpi_bnputenc(skey, k->d, skalgo, dk, iv);
755 mpi_bnputenc(skey, k->q, skalgo, dk, iv);
756 mpi_bnputenc(skey, k->p, skalgo, dk, iv);
757 mpi_bnputenc(skey, k->iqmp, skalgo, dk, iv);
758
759 buf_clear(p);
760 mpi_bnput(p, k->d);
761 mpi_bnput(p, k->q);
762 mpi_bnput(p, k->p);
763 mpi_bnput(p, k->iqmp);
764 buf_appendi(skey, pgp_csum(p, 0));
765
766 pgp_packet(skey, PGP_SECKEY);
767 buf_set(p, userid);
768 pgp_packet(p, PGP_USERID);
769 buf_cat(skey, p);
770
771 if (secring == NULL)
772 secring = PGPREMSECRING;
773 keydb = pgpdb_open(secring, remail == 2 ? pass : NULL, 1);
774 if (keydb == NULL) {
775 err = -1;
776 goto end;
777 }
778 if (keydb->filetype == -1)
779 keydb->filetype = 0;
780 pgpdb_append(keydb, skey);
781 pgpdb_close(keydb);
782
783 if (pubring != NULL) {
784 if (pgp_makepubkey(skey, NULL, pkey, pass, 0) == -1)
785 goto end;
786 keydb = pgpdb_open(pubring, NULL, 1);
787 if (keydb == NULL)
788 goto end;
789 if (keydb->filetype == -1)
790 keydb->filetype = ARMORED;
791 pgpdb_append(keydb, pkey);
792 pgpdb_close(keydb);
793 }
794 end:
795 buf_free(pkey);
796 buf_free(skey);
797 buf_free(iv);
798 buf_free(dk);
799 buf_free(p);
800 buf_free(sig);
801 return (err);
802 }
803 #endif
804
805 #define begin_param "-----BEGIN PUBLIC PARAMETER BLOCK-----"
806 #define end_param "-----END PUBLIC PARAMETER BLOCK-----"
807
808 static void *params(int dsa, int bits)
809 {
810 DSA *k = NULL;
811 DH *d = NULL;
812 FILE *f;
813 BUFFER *p, *n;
814 char line[LINELEN];
815 byte b[1024];
816 int m, l;
817
818 if (bits == 0)
819 bits = 1024;
820 if (dsa && bits > 1024)
821 bits = 1024;
822
823 p = buf_new();
824 n = buf_new();
825 f = mix_openfile(dsa ? DSAPARAMS : DHPARAMS, "r");
826 if (f != NULL) {
827 for (;;) {
828 if (fgets(line, sizeof(line), f) == NULL)
829 break;
830 if (strleft(line, begin_param)) {
831 if (fgets(line, sizeof(line), f) == NULL)
832 break;
833 m = 0;
834 sscanf(line, "%d", &m);
835 if (bits == m) {
836 buf_clear(p);
837 while (fgets(line, sizeof(line), f) != NULL) {
838 if (strleft(line, end_param)) {
839 decode(p, p);
840 if (dsa) {
841 k = DSA_new();
842 l = buf_geti(p);
843 buf_get(p, n, l);
844 k->p = BN_bin2bn(n->data, n->length, NULL);
845 l = buf_geti(p);
846 buf_get(p, n, l);
847 k->q = BN_bin2bn(n->data, n->length, NULL);
848 l = buf_geti(p);
849 buf_get(p, n, l);
850 k->g = BN_bin2bn(n->data, n->length, NULL);
851 } else {
852 d = DH_new();
853 l = buf_geti(p);
854 buf_get(p, n, l);
855 d->p = BN_bin2bn(n->data, n->length, NULL);
856 l = buf_geti(p);
857 buf_get(p, n, l);
858 d->g = BN_bin2bn(n->data, n->length, NULL);
859 }
860 break;
861 }
862 buf_appends(p, line);
863 }
864 }
865 }
866 }
867 fclose(f);
868 }
869
870 buf_free(p);
871 buf_free(n);
872
873 if (dsa) {
874 if (k == NULL) {
875 errlog(NOTICE, "Generating DSA parameters.\n");
876 k = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
877 p = buf_new();
878 l = BN_bn2bin(k->p, b);
879 buf_appendi(p, l);
880 buf_append(p, b, l);
881 l = BN_bn2bin(k->q, b);
882 buf_appendi(p, l);
883 buf_append(p, b, l);
884 l = BN_bn2bin(k->g, b);
885 buf_appendi(p, l);
886 buf_append(p, b, l);
887 encode(p, 64);
888 f = mix_openfile(DSAPARAMS, "a");
889 fprintf(f, "%s\n%d\n", begin_param, bits);
890 buf_write(p, f);
891 fprintf(f, "%s\n", end_param);
892 fclose(f);
893 buf_free(p);
894 }
895 return (k);
896 } else {
897 if (d == NULL) {
898 errlog(NOTICE, "Generating DH parameters. (This may take a long time!)\n");
899 d = DH_generate_parameters(bits, DH_GENERATOR_5, NULL, NULL);
900 p = buf_new();
901 l = BN_bn2bin(d->p, b);
902 buf_appendi(p, l);
903 buf_append(p, b, l);
904 l = BN_bn2bin(d->g, b);
905 buf_appendi(p, l);
906 buf_append(p, b, l);
907 encode(p, 64);
908 f = mix_openfile(DHPARAMS, "a");
909 fprintf(f, "%s\n%d\n", begin_param, bits);
910 buf_write(p, f);
911 fprintf(f, "%s\n", end_param);
912 fclose(f);
913 buf_free(p);
914 }
915 return (d);
916 }
917 }
918
919 int pgp_dhkeygen(int bits, BUFFER *userid, BUFFER *pass, char *pubring,
920 char *secring, int remail)
921 /* remail==2: encrypt the secring */
922 {
923 DSA *s;
924 DH *e;
925 KEYRING *keydb;
926 BUFFER *pkey, *skey, *subkey, *secret;
927 BUFFER *dk, *sig, *iv, *p;
928 long now;
929 int err = 0;
930
931 pkey = buf_new();
932 skey = buf_new();
933 subkey = buf_new();
934 iv = buf_new();
935 dk = buf_new();
936 p = buf_new();
937 sig = buf_new();
938 secret = buf_new();
939
940 s = params(1, bits);
941 errlog(NOTICE, "Generating OpenPGP DSA key.\n");
942 if (s == NULL || DSA_generate_key(s) != 1) {
943 err = -1;
944 goto end;
945 }
946 e = params(0, bits);
947 errlog(NOTICE, "Generating OpenPGP ElGamal key.\n");
948 if (e == NULL || DH_generate_key(e) != 1) {
949 err = -1;
950 goto end;
951 }
952
953 now = time(NULL);
954 if (remail) /* fake time in nym keys */
955 now -= rnd_number(4 * 24 * 60 * 60);
956
957 /* DSA key */
958 buf_setc(skey, 4);
959 buf_appendl(skey, now);
960 buf_appendc(skey, PGP_S_DSA);
961 mpi_bnput(skey, s->p);
962 mpi_bnput(skey, s->q);
963 mpi_bnput(skey, s->g);
964 mpi_bnput(skey, s->pub_key);
965
966 mpi_bnput(secret, s->priv_key);
967 buf_appendi(secret, pgp_csum(secret, 0));
968 makeski(secret, pass, remail);
969 buf_cat(skey, secret);
970 pgp_packet(skey, PGP_SECKEY);
971
972 /* ElGamal key */
973 buf_setc(subkey, 4);
974 buf_appendl(subkey, now);
975 buf_appendc(subkey, PGP_E_ELG);
976 mpi_bnput(subkey, e->p);
977 mpi_bnput(subkey, e->g);
978 mpi_bnput(subkey, e->pub_key);
979
980 buf_clear(secret);
981 mpi_bnput(secret, e->priv_key);
982 buf_appendi(secret, pgp_csum(secret, 0));
983 makeski(secret, pass, remail);
984 buf_cat(subkey, secret);
985
986 buf_set(p, userid);
987 pgp_packet(p, PGP_USERID);
988 buf_cat(skey, p);
989
990 pgp_packet(subkey, PGP_SECSUBKEY);
991 buf_cat(skey, subkey);
992
993 if (secring == NULL)
994 secring = PGPREMSECRING;
995 keydb = pgpdb_open(secring, remail == 2 ? pass : NULL, 1);
996 if (keydb == NULL) {
997 err = -1;
998 goto end;
999 }
1000 if (keydb->filetype == -1)
1001 keydb->filetype = 0;
1002 pgpdb_append(keydb, skey);
1003 pgpdb_close(keydb);
1004
1005 if (pubring != NULL) {
1006 pgp_makepubkey(skey, NULL, pkey, pass, 0);
1007 keydb = pgpdb_open(pubring, NULL, 1);
1008 if (keydb == NULL)
1009 goto end;
1010 if (keydb->filetype == -1)
1011 keydb->filetype = ARMORED;
1012 pgpdb_append(keydb, pkey);
1013 pgpdb_close(keydb);
1014 }
1015 end:
1016 buf_free(pkey);
1017 buf_free(skey);
1018 buf_free(subkey);
1019 buf_free(iv);
1020 buf_free(dk);
1021 buf_free(p);
1022 buf_free(sig);
1023 buf_free(secret);
1024 return (err);
1025 }
1026
1027 int pgp_dsasign(BUFFER *data, BUFFER *key, BUFFER *out)
1028 {
1029 BUFFER *mpi, *b;
1030 DSA *d;
1031 DSA_SIG *sig = NULL;
1032
1033 d = DSA_new();
1034 b = buf_new();
1035 mpi = buf_new();
1036 mpi_get(key, mpi);
1037 d->p = BN_bin2bn(mpi->data, mpi->length, NULL);
1038 mpi_get(key, mpi);
1039 d->q = BN_bin2bn(mpi->data, mpi->length, NULL);
1040 mpi_get(key, mpi);
1041 d->g = BN_bin2bn(mpi->data, mpi->length, NULL);
1042 mpi_get(key, mpi);
1043 d->pub_key = BN_bin2bn(mpi->data, mpi->length, NULL);
1044 if (mpi_get(key, mpi) == -1) {
1045 goto end;
1046 }
1047 d->priv_key = BN_bin2bn(mpi->data, mpi->length, NULL);
1048
1049 sig = DSA_do_sign(data->data, data->length, d);
1050 if (sig) {
1051 buf_prepare(b, BN_num_bytes(sig->r));
1052 b->length = BN_bn2bin(sig->r, b->data);
1053 mpi_put(out, b);
1054 b->length = BN_bn2bin(sig->s, b->data);
1055 mpi_put(out, b);
1056 }
1057 end:
1058 buf_free(mpi);
1059 buf_free(b);
1060 DSA_SIG_free(sig);
1061 DSA_free(d);
1062 return(sig ? 0 : -1);
1063 }
1064
1065 int pgp_dosign(int algo, BUFFER *data, BUFFER *key)
1066 {
1067 int err;
1068 BUFFER *out, *r, *s;
1069
1070 out = buf_new();
1071 r = buf_new();
1072 s = buf_new();
1073 switch (algo) {
1074 #ifdef USE_RSA
1075 case PGP_ES_RSA:
1076 err = pgp_rsa(data, key, PK_SIGN);
1077 if (err == 0)
1078 mpi_put(out, data);
1079 break;
1080 #endif
1081 case PGP_S_DSA:
1082 err = pgp_dsasign(data, key, out);
1083 break;
1084 default:
1085 errlog(NOTICE, "Unknown encryption algorithm!\n");
1086 return (-1);
1087 }
1088 if (err == -1)
1089 errlog(ERRORMSG, "Signing operation failed!\n");
1090
1091 buf_move(data, out);
1092 buf_free(out);
1093 buf_free(r);
1094 buf_free(s);
1095 return (err);
1096 }
1097
1098 int pgp_elgdecrypt(BUFFER *in, BUFFER *key)
1099 {
1100 BIGNUM *a, *b, *c, *p, *g, *x;
1101 BN_CTX *ctx;
1102 BUFFER *i;
1103 int err = -1;
1104
1105 i = buf_new();
1106 ctx = BN_CTX_new();
1107 if (ctx == NULL) goto end;
1108 mpi_get(key, i);
1109 p = BN_bin2bn(i->data, i->length, NULL);
1110 mpi_get(key, i);
1111 g = BN_bin2bn(i->data, i->length, NULL);
1112 mpi_get(key, i); /* y */
1113 mpi_get(key, i);
1114 x = BN_bin2bn(i->data, i->length, NULL);
1115 mpi_get(in, i);
1116 a = BN_bin2bn(i->data, i->length, NULL);
1117 if (mpi_get(in, i) == -1)
1118 goto e1;
1119 b = BN_bin2bn(i->data, i->length, NULL);
1120 c = BN_new();
1121
1122 if (BN_mod_exp(c, a, x, p, ctx) == 0) goto end;
1123 if (BN_mod_inverse(a, c, p, ctx) == 0) goto end;
1124 if (BN_mod_mul(c, a, b, p, ctx) == 0) goto end;
1125
1126 buf_prepare(i, BN_num_bytes(c));
1127 i->length = BN_bn2bin(c, i->data);
1128
1129 buf_prepare(in, BN_num_bytes(c));
1130 in->length = RSA_padding_check_PKCS1_type_2(in->data, in->length, i->data,
1131 i->length, i->length + 1);
1132 if (in->length <= 0)
1133 in->length = 0;
1134 else
1135 err = 0;
1136
1137 end:
1138 BN_free(b);
1139 BN_free(c);
1140 e1:
1141 buf_free(i);
1142 BN_free(a);
1143 BN_free(p);
1144 BN_free(g);
1145 BN_clear_free(x);
1146 BN_CTX_free(ctx);
1147
1148 return (err);
1149 }
1150
1151 int pgp_elgencrypt(BUFFER *in, BUFFER *key)
1152 {
1153 BIGNUM *m, *k, *a, *b, *c, *p, *g, *y;
1154 BN_CTX *ctx;
1155 BUFFER *i;
1156 int err = -1;
1157
1158 i = buf_new();
1159 ctx = BN_CTX_new();
1160 if (ctx == NULL) goto end;
1161 mpi_get(key, i);
1162 p = BN_bin2bn(i->data, i->length, NULL);
1163 mpi_get(key, i);
1164 g = BN_bin2bn(i->data, i->length, NULL);
1165 if (mpi_get(key, i) == -1)
1166 goto e1;
1167 y = BN_bin2bn(i->data, i->length, NULL);
1168
1169 buf_prepare(i, BN_num_bytes(p));
1170 if (RSA_padding_add_PKCS1_type_2(i->data, i->length, in->data, in->length)
1171 != 1)
1172 goto end;
1173 m = BN_bin2bn(i->data, i->length, NULL);
1174
1175 k = BN_new();
1176 BN_rand(k, BN_num_bits(p), 0, 0);
1177
1178 a = BN_new();
1179 b = BN_new();
1180 c = BN_new();
1181
1182 if (BN_mod_exp(a, g, k, p, ctx) == 0) goto end;
1183 if (BN_mod_exp(c, y, k, p, ctx) == 0) goto end;
1184 if (BN_mod_mul(b, m, c, p, ctx) == 0) goto end;
1185
1186 buf_clear(in);
1187 i->length = BN_bn2bin(a, i->data);
1188 mpi_put(in, i);
1189 i->length = BN_bn2bin(b, i->data);
1190 mpi_put(in, i);
1191
1192 err = 0;
1193
1194 BN_free(a);
1195 BN_free(b);
1196 BN_free(c);
1197 BN_free(m);
1198 e1:
1199 buf_free(i);
1200 BN_free(p);
1201 BN_free(g);
1202 BN_free(y);
1203 BN_CTX_free(ctx);
1204 end:
1205
1206 return (err);
1207 }
1208
1209 #endif /* USE_PGP */

  ViewVC Help
Powered by ViewVC 1.1.5