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

  ViewVC Help
Powered by ViewVC 1.1.5