/[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 221 - (hide annotations) (download)
Fri Sep 6 22:45:06 2002 UTC (10 years, 9 months ago) by rabbi
File MIME type: text/plain
File size: 29295 byte(s)
Standardized commenting conventions.
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 rabbi 221 $Id: pgpdata.c,v 1.15 2002/09/06 22:45:06 rabbi 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 weaselp 120 #include <string.h>
19 rabbi 1
20     int pgp_keylen(int symalgo)
21     {
22     switch (symalgo) {
23 rabbi 98 #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 rabbi 1 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 rabbi 98 return (0);
38 rabbi 1 }
39     }
40    
41 rabbi 98 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 rabbi 1 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 weaselp 134 int i, l;
77 rabbi 221 while (!mpi->data[0] && mpi->length) /* remove leading zeros from mpi */
78 weaselp 134 memmove(mpi->data, mpi->data+1, --mpi->length);
79     l = mpi->length * 8;
80 rabbi 1 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 rabbi 98 #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 rabbi 1 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 weaselp 134 int ivlen = iv->length;
266 rabbi 1
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 weaselp 134 if (key && key->length) {
272 rabbi 1 skcrypt(b, ska, key, iv, ENCRYPT);
273 weaselp 134 buf_clear(iv);
274     buf_append(iv, b->data+b->length-ivlen, ivlen);
275     }
276 rabbi 1 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 rabbi 98 buf_get(p, iv, pgp_blocklen(skalgo));
307 rabbi 1
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 rabbi 98 buf_setrnd(iv, pgp_blocklen(PGP_K_CAST5));
327 rabbi 1 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 rabbi 135 int pgp_getkey(int mode, int algo, int *psym, int *pmdc, BUFFER *keypacket, BUFFER *key,
424 rabbi 1 BUFFER *keyid, BUFFER *userid, BUFFER *pass)
425     {
426     int tempbuf = 0;
427     int keytype = -1, type, j;
428 weaselp 120 int thisalgo = 0, version, skalgo;
429 rabbi 135 int needsym = 0, symfound = 0, mdcfound = 0;
430 ulfm 51 BUFFER *p1, *iv, *sk, *i, *thiskeyid;
431 rabbi 98 int ivlen;
432 rabbi 1 int csstart;
433    
434     p1 = buf_new();
435     i = buf_new();
436     iv = buf_new();
437     sk = buf_new();
438 ulfm 51 thiskeyid = buf_new();
439 rabbi 1 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 ulfm 63 if (len)
467 rabbi 221 buf_get(p1, i, len-1); /* len-1 - exclude type */
468 ulfm 63 else
469     buf_clear(i);
470 rabbi 135 if (type == PGP_SUB_PSYMMETRIC) {
471 rabbi 1 while ((a = buf_getc(i)) != -1)
472 rabbi 135 if ((a == PGP_K_3DES || a == PGP_K_CAST5 || a == PGP_K_BF
473 rabbi 1 #ifdef USE_IDEA
474     || a == PGP_K_IDEA
475     #endif
476 rabbi 135 #ifdef USE_AES
477     || a == PGP_K_AES128 || a == PGP_K_AES192 || a == PGP_K_AES256
478     #endif
479 rabbi 1 ) && (a == needsym || needsym == 0)) {
480     symfound = a;
481 rabbi 221 break; /* while ((a = buf_getc(i)) != -1) */
482     } /* if ((a == PGP_K_3DES)... */
483     } /* if (type == PGP_SUB_PSYMMETRIC) */
484 rabbi 135 else if (type == PGP_SUB_FEATURES) {
485     if ((a = buf_getc(i)) != -1)
486     if (a & 0x01)
487     mdcfound = 1;
488 rabbi 221 } /* 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 rabbi 1 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 rabbi 135 mdcfound = 0;
520 rabbi 1 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 ulfm 51 pgp_keyid(p1, thiskeyid);
540 rabbi 1 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 rabbi 98 ivlen = pgp_blocklen(skalgo);
554 rabbi 1 for (j = 0; j < pgp_numsecmpi(thisalgo); j++) {
555 rabbi 98 unsigned char lastb[16];
556 rabbi 1 if (mpi_get(p1, i) == -1) {
557     keytype = -1;
558     goto end;
559     }
560 rabbi 98 assert(ivlen <= 16);
561     memcpy(lastb, i->data+i->length-ivlen, ivlen);
562 rabbi 1 skcrypt(i, skalgo, sk, iv, DECRYPT);
563 rabbi 98 buf_clear(iv);
564     buf_append(iv, lastb, ivlen);
565 rabbi 1 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 rabbi 221 } /* switch (type) */
593     } /* while ((type = pgp_getpacket(keypacket, p1)) > 0) */
594 rabbi 1 end:
595 ulfm 51 if (keyid) buf_set(keyid, thiskeyid);
596 rabbi 1 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 ulfm 51 buf_free(thiskeyid);
605 rabbi 1 #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 rabbi 135 if (pmdc)
614     *pmdc = mdcfound;
615 rabbi 1
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 weaselp 185 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 rabbi 1 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 weaselp 185 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 rabbi 1 #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 disastry 212 k = RSA_generate_key(bits == 0 ? 1024 : bits, 17, NULL, NULL);
840 rabbi 1 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 weaselp 205 buf_appendi(skey, KEYLIFETIME/(24*60*60));
851 rabbi 1 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 rabbi 98 buf_setrnd(iv, pgp_blocklen(skalgo));
860 rabbi 1 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 weaselp 185 keydb->filetype = ARMORED;
893 rabbi 1 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 weaselp 86 RSA_free(k);
909 rabbi 1 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 weaselp 185 keydb->filetype = ARMORED;
1116 rabbi 1 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 weaselp 120 BIGNUM *a = NULL, *b = NULL, *c = NULL,
1215     *p = NULL, *g = NULL, *x = NULL;
1216 rabbi 1 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 weaselp 120 BIGNUM *m, *k, *a, *b, *c, *p, *g, *y = NULL;
1269 rabbi 1 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