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

  ViewVC Help
Powered by ViewVC 1.1.5