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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 13 - (hide annotations) (download)
Wed Nov 7 00:44:09 2001 UTC (11 years, 6 months ago) by rabbi
File MIME type: text/plain
File size: 13841 byte(s)
Cleaned up assert to fix NDEBUG problems with MSVC.
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     Create OpenPGP packets
9 rabbi 13 $Id: pgpcreat.c,v 1.3 2001/11/07 00:44:09 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     #include <time.h>
19    
20     int pgp_packet(BUFFER *in, int type)
21     {
22     int ctb;
23     BUFFER *out;
24    
25     out = buf_new();
26     ctb = 128 + (type << 2);
27     if (in->length < 256 && type != PGP_PUBKEY && type != PGP_SECKEY &&
28     type != PGP_SIG && type != PGP_PUBSUBKEY && type != PGP_SECSUBKEY
29     #ifdef MIMIC
30     && type != PGP_ENCRYPTED
31     #endif
32     ) {
33     buf_setc(out, ctb);
34     buf_appendc(out, in->length);
35     }
36     #ifndef MIMIC
37     else if (in->length < 65536)
38     #else
39     else if ((type == PGP_PUBKEY || type == PGP_SECKEY || type == PGP_SIG
40     || type == PGP_SESKEY || type == PGP_PUBSUBKEY ||
41     type == PGP_SECSUBKEY) && in->length < 65536)
42     #endif
43     {
44     buf_appendc(out, ctb | 1);
45     buf_appendi(out, in->length);
46     } else {
47     buf_appendc(out, ctb | 2);
48     buf_appendl(out, in->length);
49     }
50     buf_cat(out, in);
51     buf_move(in, out);
52     buf_free(out);
53     return (0);
54     }
55    
56     int pgp_subpacket(BUFFER *in, int type)
57     {
58     BUFFER *out;
59     int len;
60    
61     out = buf_new();
62     len = in->length + 1;
63     if (len < 192)
64     buf_setc(out, len);
65     else {
66     buf_setc(out, 255);
67     buf_appendl(out, len);
68     }
69     buf_appendc(out, type);
70     buf_cat(out, in);
71     buf_move(in, out);
72     buf_free(out);
73     return (0);
74     }
75    
76     int pgp_packet3(BUFFER *in, int type)
77     {
78     #ifdef MIMIC
79     int ctb;
80     BUFFER *out;
81    
82     out = buf_new();
83     ctb = 128 + (type << 2);
84     buf_setc(out, ctb | 3);
85     buf_cat(out, in);
86     buf_move(in, out);
87     buf_free(out);
88     return (0);
89     #else
90     return pgp_packet(in, type);
91     #endif
92     }
93    
94     #ifdef USE_IDEA
95     static int pgp_ideaencrypt(BUFFER *in, BUFFER *out, BUFFER *key)
96     {
97     byte iv[8];
98     int i, n = 0;
99     IDEA_KEY_SCHEDULE ks;
100    
101     assert(key->length == 17);
102    
103     for (i = 0; i < 8; i++)
104     iv[i] = 0;
105    
106     idea_set_encrypt_key(key->data + 1, &ks);
107    
108     rnd_bytes(out->data, 8);
109     out->data[8] = out->data[6], out->data[9] = out->data[7];
110     n = 0;
111     idea_cfb64_encrypt(out->data, out->data, 10, &ks, iv, &n, IDEA_ENCRYPT);
112     iv[6] = iv[0], iv[7] = iv[1];
113     memcpy(iv, out->data + 2, 6);
114     n = 0;
115     idea_cfb64_encrypt(in->data, out->data + 10, in->length, &ks, iv, &n,
116     IDEA_ENCRYPT);
117     return (0);
118     }
119     #endif
120    
121     static int pgp_3desencrypt(BUFFER *in, BUFFER *out, BUFFER *key)
122     {
123     des_cblock iv;
124     int i, n = 0;
125     des_key_schedule ks1;
126     des_key_schedule ks2;
127     des_key_schedule ks3;
128    
129     assert(key->length == 25);
130    
131     for (i = 0; i < 8; i++)
132     iv[i] = 0;
133    
134     des_set_key((const_des_cblock *) (key->data + 1), ks1);
135     des_set_key((const_des_cblock *) (key->data + 9), ks2);
136     des_set_key((const_des_cblock *) (key->data+ 17), ks3);
137    
138     rnd_bytes(out->data, 8);
139     out->data[8] = out->data[6], out->data[9] = out->data[7];
140     n = 0;
141     des_ede3_cfb64_encrypt(out->data, out->data, 10, ks1, ks2, ks3, &iv, &n,
142     ENCRYPT);
143     iv[6] = iv[0], iv[7] = iv[1];
144     memcpy(iv, out->data + 2, 6);
145     n = 0;
146     des_ede3_cfb64_encrypt(in->data, out->data + 10, in->length, ks1, ks2, ks3,
147     &iv, &n, ENCRYPT);
148     return (0);
149     }
150    
151     static int pgp_castencrypt(BUFFER *in, BUFFER *out, BUFFER *key)
152     {
153     byte iv[8];
154     int i, n = 0;
155     CAST_KEY ks;
156    
157     assert(key->length == 17);
158    
159     for (i = 0; i < 8; i++)
160     iv[i] = 0;
161    
162     CAST_set_key(&ks, 16, key->data + 1);
163    
164     rnd_bytes(out->data, 8);
165     out->data[8] = out->data[6], out->data[9] = out->data[7];
166     n = 0;
167     CAST_cfb64_encrypt(out->data, out->data, 10, &ks, iv, &n, CAST_ENCRYPT);
168     iv[6] = iv[0], iv[7] = iv[1];
169     memcpy(iv, out->data + 2, 6);
170     n = 0;
171     CAST_cfb64_encrypt(in->data, out->data + 10, in->length, &ks, iv, &n,
172     CAST_ENCRYPT);
173     return (0);
174     }
175    
176     int pgp_symmetric(BUFFER *in, BUFFER *key)
177     {
178     BUFFER *out;
179    
180     out = buf_new();
181     buf_prepare(out, in->length + 10);
182     switch (buf_getc(key)) {
183     #ifdef USE_IDEA
184     case PGP_K_IDEA:
185     pgp_ideaencrypt(in, out, key);
186     break;
187     #endif
188     case PGP_K_3DES:
189     pgp_3desencrypt(in, out, key);
190     break;
191     case PGP_K_CAST5:
192     pgp_castencrypt(in, out, key);
193     break;
194     default:
195     errlog(ERRORMSG, "Unknown symmetric algorithm.\n");
196     }
197     pgp_packet(out, PGP_ENCRYPTED);
198    
199     buf_move(in, out);
200     buf_free(out);
201     return (0);
202     }
203    
204     int pgp_literal(BUFFER *b, char *filename, int text)
205     {
206     BUFFER *out;
207     BUFFER *line;
208    
209     if (filename == NULL)
210     filename = "stdin";
211    
212     if (strlen(filename) > 255)
213     return (-1);
214    
215     out = buf_new();
216     line = buf_new();
217    
218     if (text)
219     buf_setc(out, 't');
220     else
221     buf_setc(out, 'b');
222     buf_appendc(out, strlen(filename));
223     buf_appends(out, filename);
224     buf_appendl(out, 0); /* timestamp */
225    
226     if (b->length > 0) {
227     if (text)
228     while (buf_getline(b, line) != -1) {
229     buf_cat(out, line);
230     buf_appends(out, "\r\n");
231     } else
232     buf_cat(out, b);
233     }
234     pgp_packet(out, PGP_LITERAL);
235     buf_move(b, out);
236     buf_free(out);
237     buf_free(line);
238    
239     return (0);
240     }
241    
242     int pgp_compress(BUFFER *in)
243     {
244     int err;
245     BUFFER *out;
246    
247     out = buf_new();
248     buf_setc(out, 1);
249     err = buf_zip(out, in, 13);
250     if (err == 0) {
251     pgp_packet3(out, PGP_COMPRESSED);
252     buf_move(in, out);
253     }
254     buf_free(out);
255     return (err);
256     }
257    
258     int pgp_sessionkey(BUFFER *out, BUFFER *user, BUFFER *keyid, BUFFER *seskey,
259     char *pubring)
260     {
261     BUFFER *encrypt, *key, *id;
262     int algo, sym, err = -1;
263     int i, csum = 0;
264     int tempbuf = 0;
265    
266     encrypt = buf_new();
267     key = buf_new();
268     id = buf_new();
269     if (keyid == NULL) {
270     keyid = buf_new();
271     tempbuf = 1;
272     }
273     sym = seskey->data[0];
274     if ((algo = pgpdb_getkey(PK_ENCRYPT, PGP_ANY, &sym, key, user, NULL, keyid,
275     pubring, NULL)) == -1)
276     goto end;
277    
278     buf_setc(out, 3); /* type */
279     buf_cat(out, keyid);
280     buf_appendc(out, algo); /* algorithm */
281    
282     buf_set(encrypt, seskey);
283    
284     for (i = 1; i < encrypt->length; i++)
285     csum = (csum + encrypt->data[i]) % 65536;
286     buf_appendi(encrypt, csum);
287    
288     switch (algo) {
289     #ifdef USE_RSA
290     case PGP_ES_RSA:
291     err = pgp_rsa(encrypt, key, PK_ENCRYPT);
292     mpi_put(out, encrypt);
293     break;
294     #endif
295     case PGP_E_ELG:
296     err = pgp_elgencrypt(encrypt, key);
297     buf_cat(out, encrypt);
298     break;
299     default:
300     errlog(NOTICE, "Unknown encryption algorithm.\n");
301     err = -1;
302     goto end;
303     }
304     if (err == -1) {
305     errlog(ERRORMSG, "Encryption failed!\n");
306     goto end;
307     }
308     pgp_packet(out, PGP_SESKEY);
309     end:
310     if (tempbuf)
311     buf_free(keyid);
312     buf_free(id);
313     buf_free(encrypt);
314     buf_free(key);
315     return (err);
316     }
317    
318     void pgp_marker(BUFFER *out)
319     {
320     buf_clear(out);
321     buf_append(out, "PGP", 3);
322     pgp_packet(out, PGP_MARKER);
323     }
324    
325     int pgp_symsessionkey(BUFFER *out, BUFFER *seskey, BUFFER *pass)
326     {
327     BUFFER *key;
328     int sym;
329     key = buf_new();
330    
331     sym = seskey->data[0];
332     buf_setc(out, 4); /* version */
333     #ifdef MIMICPGP5
334     pgp_makesk(out, key, sym, 1, PGP_H_MD5, pass);
335     #else
336     pgp_makesk(out, key, sym, 3, PGP_H_SHA1, pass);
337     #endif
338     if (seskey->length > 1)
339     buf_cat(out, seskey);
340     else {
341     buf_setc(seskey, sym);
342     buf_cat(seskey, key);
343     }
344     pgp_packet(out, PGP_SYMSESKEY);
345     buf_free(key);
346     return (0);
347     }
348    
349     int pgp_digest(int hashalgo, BUFFER *in, BUFFER *d)
350     {
351     switch (hashalgo) {
352     case PGP_H_MD5:
353     digest_md5(in, d);
354     return (0);
355     case PGP_H_SHA1:
356     digest_sha1(in, d);
357     return (0);
358     case PGP_H_RIPEMD:
359     digest_rmd160(in, d);
360     return (0);
361     default:
362     return (-1);
363     }
364     }
365    
366     int asnprefix(BUFFER *b, int hashalgo)
367     {
368     switch (hashalgo) {
369     case PGP_H_MD5:
370     buf_append(b, MD5PREFIX, sizeof(MD5PREFIX) - 1);
371     return (0);
372     case PGP_H_SHA1:
373     buf_append(b, SHA1PREFIX, sizeof(SHA1PREFIX) - 1);
374     return (0);
375     default:
376     return (-1);
377     }
378     }
379    
380     int pgp_expandsk(BUFFER *key, int skalgo, int hashalgo, BUFFER *data)
381     {
382     BUFFER *temp;
383     int keylen;
384     int err = 0;
385     temp = buf_new();
386    
387     keylen = pgp_keylen(skalgo);
388     buf_clear(key);
389     while (key->length < keylen) {
390     if (pgp_digest(hashalgo, data, temp) == -1) {
391     err = -1;
392     goto end;
393     }
394     buf_cat(key, temp);
395    
396     buf_setc(temp, 0);
397     buf_cat(temp, data);
398     buf_move(data, temp);
399     }
400    
401     if (key->length > keylen) {
402     buf_set(temp, key);
403     buf_get(temp, key, keylen);
404     }
405     end:
406     buf_free(temp);
407     return(err);
408     }
409    
410     int pgp_makesk(BUFFER *out, BUFFER *key, int sym, int type, int hash,
411     BUFFER *pass)
412     {
413     int err = 0;
414     BUFFER *salted;
415     salted = buf_new();
416    
417     buf_appendc(out, sym);
418     buf_appendc(out, type);
419     buf_appendc(out, hash);
420     switch (type) {
421     case 0:
422     buf_set(salted, pass);
423     break;
424     case 1:
425     buf_appendrnd(salted, 8); /* salt */
426     buf_cat(out, salted);
427     buf_cat(salted, pass);
428     break;
429     case 3:
430     buf_appendrnd(salted, 8); /* salt */
431     buf_cat(out, salted);
432     buf_appendc(out, 96); /* encoded count value 65536 */
433     pgp_iteratedsk(salted, salted, pass, 96);
434     break;
435     default:
436     err = -1;
437     }
438     pgp_expandsk(key, sym, hash, salted);
439     buf_free(salted);
440     return (err);
441     }
442    
443     /* PGP/MIME needs to know the hash algorithm */
444     int pgp_signhashalgo(BUFFER *algo, BUFFER *userid, char *secring, BUFFER *pass)
445     {
446     int pkalgo;
447    
448     pkalgo = pgpdb_getkey(PK_SIGN, PGP_ANY, NULL, NULL, userid, NULL, NULL,
449     secring, pass);
450     if (pkalgo == PGP_S_DSA)
451     buf_sets(algo, "sha1");
452     if (pkalgo == PGP_ES_RSA)
453     buf_sets(algo, "md5");
454     return (pkalgo > 0 ? 0 : -1);
455     }
456    
457     int pgp_sign(BUFFER *msg, BUFFER *msg2, BUFFER *sig, BUFFER *userid,
458     BUFFER *pass, int type, int self, long now, int remail,
459     BUFFER *keypacket, char *secring)
460     /* msg: data to be signed (buffer is modified)
461     msg2: additional data to be signed for certain sig types
462     sig: signature is placed here
463     userid: select signing key
464     pass: pass phrase for signing key
465     type: PGP signature type
466     self: is this a self-signature?
467     now: time of signature creation
468     remail: is this an anonymous message?
469     keypacket: signature key
470     secring: key ring with signature key */
471     {
472     BUFFER *key, *id, *d, *sub, *enc;
473     int algo, err = -1;
474     int version = 3, hashalgo;
475 rabbi 11 int type1;
476 rabbi 1
477     id = buf_new();
478     d = buf_new();
479     sub = buf_new();
480     enc = buf_new();
481     key = buf_new();
482    
483     if (now == 0) {
484     now = time(NULL);
485     if (remail)
486     now -= rnd_number(4 * 24 * 60 * 60);
487     }
488     if (keypacket) {
489     buf_rewind(keypacket);
490     algo = pgp_getkey(PK_SIGN, PGP_ANY, NULL, keypacket, key, id, NULL, pass);
491     } else
492     algo = pgpdb_getkey(PK_SIGN, PGP_ANY, NULL, key, userid, NULL, id, secring,
493     pass);
494     if (algo <= -1) {
495     err = algo;
496     goto end;
497     }
498     if (algo == PGP_S_DSA)
499     version = 4;
500     if (version == 3)
501     hashalgo = PGP_H_MD5;
502     else
503     hashalgo = PGP_H_SHA1;
504    
505     if (!self)
506     version = 3;
507    
508     switch (type) {
509     case PGP_SIG_CERT:
510 rabbi 13 type1 = pgp_getpacket(msg, d) == PGP_PUBKEY;
511     assert (type1);
512 rabbi 1 buf_setc(msg, 0x99);
513     buf_appendi(msg, d->length);
514     buf_cat(msg, d);
515    
516     pgp_getpacket(msg2, d);
517     switch (version) {
518     case 3:
519     buf_cat(msg, d);
520     break;
521     case 4:
522     buf_appendc(msg, 0xb4);
523     buf_appendl(msg, d->length);
524     buf_cat(msg, d);
525     break;
526     }
527     break;
528     case PGP_SIG_BINDSUBKEY:
529 rabbi 13 type1 = pgp_getpacket(msg, d) == PGP_PUBKEY;
530     assert (type1);
531 rabbi 1 buf_clear(msg);
532     buf_appendc(msg, 0x99);
533     buf_appendi(msg, d->length);
534     buf_cat(msg, d);
535    
536 rabbi 13 type1 = pgp_getpacket(msg2, d) == PGP_PUBSUBKEY;
537     assert (type1);
538 rabbi 1 buf_appendc(msg, 0x99);
539     buf_appendi(msg, d->length);
540     buf_cat(msg, d);
541     break;
542     case PGP_SIG_BINARY:
543     break;
544     case PGP_SIG_CANONIC:
545     pgp_sigcanonic(msg);
546     break;
547     default:
548     NOT_IMPLEMENTED;
549     }
550     switch (version) {
551     case 3:
552     buf_set(d, msg);
553     buf_appendc(d, type);
554     buf_appendl(d, now);
555     pgp_digest(hashalgo, d, d);
556     if (algo == PGP_ES_RSA)
557     asnprefix(enc, hashalgo);
558     buf_cat(enc, d);
559     err = pgp_dosign(algo, enc, key);
560    
561     buf_setc(sig, version);
562     buf_appendc(sig, 5);
563     buf_appendc(sig, type);
564     buf_appendl(sig, now);
565     buf_cat(sig, id);
566     buf_appendc(sig, algo);
567     buf_appendc(sig, hashalgo);
568     buf_append(sig, d->data, 2);
569     buf_cat(sig, enc);
570     break;
571    
572     case 4:
573     buf_setc(sig, version);
574     buf_appendc(sig, type);
575     buf_appendc(sig, algo);
576     buf_appendc(sig, hashalgo);
577    
578     buf_clear(d);
579     buf_appendl(d, now);
580     pgp_subpacket(d, PGP_SUB_CREATIME);
581     buf_cat(sub, d);
582    
583     if (self) {
584     buf_setc(d, PGP_K_3DES);
585     pgp_subpacket(d, PGP_SUB_PSYMMETRIC);
586     buf_cat(sub, d);
587     }
588    
589     buf_appendi(sig, sub->length); /* hashed subpacket length */
590     buf_cat(sig, sub);
591    
592     /* compute message digest */
593     buf_set(d, msg);
594     buf_cat(d, sig);
595     buf_appendc(d, version);
596     buf_appendc(d, 0xff);
597     buf_appendl(d, sig->length);
598     pgp_digest(hashalgo, d, d);
599    
600     pgp_subpacket(id, PGP_SUB_ISSUER);
601     buf_appendi(sig, id->length); /* unhashed subpacket length */
602     buf_cat(sig, id);
603    
604     buf_append(sig, d->data, 2);
605    
606     if (algo == PGP_ES_RSA)
607     asnprefix(enc, hashalgo);
608     buf_cat(enc, d);
609     err = pgp_dosign(algo, enc, key);
610     buf_cat(sig, enc);
611     break;
612     }
613     pgp_packet(sig, PGP_SIG);
614    
615     end:
616     buf_free(key);
617     buf_free(id);
618     buf_free(d);
619     buf_free(sub);
620     buf_free(enc);
621     return (err);
622     }
623    
624     int pgp_pubkeycert(BUFFER *userid, char *keyring, BUFFER *pass,
625     BUFFER *out, int remail)
626     {
627     BUFFER *key;
628     KEYRING *r;
629     int err = -1;
630    
631     key = buf_new();
632     r = pgpdb_open(keyring, pass, 0);
633     if (r != NULL)
634     while (pgpdb_getnext(r, key, NULL, userid) != -1) {
635     if (pgp_makepubkey(key, NULL, out, pass, 0) != -1)
636     err = 0;
637     }
638     if (err == 0)
639     pgp_armor(out, remail);
640     else
641     buf_clear(out);
642     buf_free(key);
643     return (err);
644     }
645    
646     #endif /* USE_PGP */

  ViewVC Help
Powered by ViewVC 1.1.5