/[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 934 - (hide annotations) (download)
Sat Jun 24 13:40:39 2006 UTC (6 years, 10 months ago) by rabbi
File MIME type: text/plain
File size: 36762 byte(s)
Updated copyright dates.
1 rabbi 934 /* Mixmaster version 3.0 -- (C) 1999 - 2006 Anonymizer Inc. and others.
2 rabbi 1
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 weasel 647 $Id$ */
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 rabbi 262 #endif /* USE_AES */
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 rabbi 262 #endif /* USE_AES */
50 rabbi 98 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 rabbi 262 #endif /* USE_IDEA */
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 rabbi 262 #endif /* USE_AES */
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     int pgp_rsa(BUFFER *in, BUFFER *k, int mode)
130     {
131     BUFFER *mpi, *out;
132     int err = -1;
133     RSA *key;
134    
135     assert(mode == PK_ENCRYPT || mode == PK_VERIFY || mode == PK_DECRYPT
136     || mode == PK_SIGN);
137     key = RSA_new();
138     out = buf_new();
139     mpi = buf_new();
140    
141     mpi_get(k, mpi);
142     key->n = BN_bin2bn(mpi->data, mpi->length, NULL);
143    
144     if (mpi_get(k, mpi) < 0)
145     goto end;
146     key->e = BN_bin2bn(mpi->data, mpi->length, NULL);
147    
148     if (mode == PK_DECRYPT || mode == PK_SIGN) {
149     if (mpi_get(k, mpi) < 0)
150     goto end;
151     key->d = BN_bin2bn(mpi->data, mpi->length, NULL);
152    
153     #if 1
154     /* compute auxiluary parameters */
155     mpi_get(k, mpi); /* PGP'p is SSLeay's q */
156     key->q = BN_bin2bn(mpi->data, mpi->length, NULL);
157    
158     mpi_get(k, mpi);
159     key->p = BN_bin2bn(mpi->data, mpi->length, NULL);
160    
161     if (mpi_get(k, mpi) < 0)
162     goto end;
163     key->iqmp = BN_bin2bn(mpi->data, mpi->length, NULL);
164    
165     {
166     BIGNUM *i;
167     BN_CTX *ctx;
168    
169     ctx = BN_CTX_new();
170     i = BN_new();
171     key->dmp1 = BN_new();
172     key->dmq1 = BN_new();
173    
174     BN_sub(i, key->p, BN_value_one());
175     BN_mod(key->dmp1, key->d, i, ctx);
176    
177     BN_sub(i, key->q, BN_value_one());
178     BN_mod(key->dmq1, key->d, i, ctx);
179    
180     BN_free(i);
181     }
182 rabbi 262 #endif /* 1 */
183 rabbi 1 }
184     buf_prepare(out, RSA_size(key));
185    
186     switch (mode) {
187     case PK_ENCRYPT:
188     out->length = RSA_public_encrypt(in->length, in->data, out->data, key,
189     RSA_PKCS1_PADDING);
190     break;
191     case PK_VERIFY:
192     out->length = RSA_public_decrypt(in->length, in->data, out->data, key,
193     RSA_PKCS1_PADDING);
194     break;
195     case PK_SIGN:
196     out->length = RSA_private_encrypt(in->length, in->data, out->data, key,
197     RSA_PKCS1_PADDING);
198     break;
199     case PK_DECRYPT:
200     out->length = RSA_private_decrypt(in->length, in->data, out->data, key,
201     RSA_PKCS1_PADDING);
202     break;
203     }
204     if (out->length == -1)
205     err = -1, out->length = 0;
206     else
207     err = 0;
208    
209     buf_move(in, out);
210     end:
211     RSA_free(key);
212     buf_free(out);
213     buf_free(mpi);
214     return (err);
215     }
216    
217     /* Contrary to RFC 2440, old PGP versions use this for clearsign only.
218     * If the text is included in the OpenPGP message, the application will
219     * typically provide the text in the proper format (whatever that is);
220     * we use "canonic" format so everybody will be able to read our messages.
221     * In clearsigned messages, trailing whitespace is always ignored.
222     * Detached signatures are the problematic case. For PGP/MIME, we always
223     * escape trailing whitespace as quoted-printable.
224     */
225     void pgp_sigcanonic(BUFFER *msg)
226     {
227     BUFFER *line, *out;
228    
229     out = buf_new();
230     line = buf_new();
231    
232     while (buf_getline(msg, line) != -1) {
233     while (line->length > 0 && (line->data[line->length - 1] == ' '
234     #if 0
235     || line->data[line->length - 1] == '\t'
236 rabbi 262 #endif /* 0 */
237 rabbi 1 ))
238     line->length--;
239     line->data[line->length] = '\0';
240     buf_cat(out, line);
241     buf_appends(out, "\r\n");
242     }
243     buf_move(msg, out);
244     buf_free(out);
245     buf_free(line);
246     }
247    
248     static void mpi_bnput(BUFFER *o, BIGNUM *i)
249     {
250     BUFFER *b;
251    
252     b = buf_new();
253     buf_prepare(b, BN_num_bytes(i));
254     b->length = BN_bn2bin(i, b->data);
255     mpi_put(o, b);
256     buf_free(b);
257     }
258    
259     static void mpi_bnputenc(BUFFER *o, BIGNUM *i, int ska, BUFFER *key,
260     BUFFER *iv)
261     {
262     BUFFER *b;
263 weaselp 134 int ivlen = iv->length;
264 rabbi 1
265     b = buf_new();
266     buf_prepare(b, BN_num_bytes(i));
267     b->length = BN_bn2bin(i, b->data);
268     buf_appendi(o, mpi_bitcount(b));
269 weaselp 134 if (key && key->length) {
270 rabbi 1 skcrypt(b, ska, key, iv, ENCRYPT);
271 weaselp 134 buf_clear(iv);
272     buf_append(iv, b->data+b->length-ivlen, ivlen);
273     }
274 rabbi 1 buf_cat(o, b);
275     buf_free(b);
276     }
277    
278     static int getski(BUFFER *p, BUFFER *pass, BUFFER *key, BUFFER *iv)
279     {
280     int skalgo;
281     BUFFER *salt, *temp;
282    
283     if (!pass)
284     return(-1);
285    
286     salt = buf_new();
287     temp = buf_new();
288    
289     skalgo = buf_getc(p);
290     switch (skalgo) {
291     case 0:
292     /* none */
293     goto end;
294     case 255:
295     /* S2K specifier */
296     skalgo = pgp_getsk(p, pass, key);
297     break;
298     default:
299     /* simple */
300     digest_md5(pass, key);
301     break;
302     }
303    
304 rabbi 98 buf_get(p, iv, pgp_blocklen(skalgo));
305 rabbi 1
306     end:
307     buf_free(salt);
308     buf_free(temp);
309     return (skalgo);
310     }
311    
312     static void makeski(BUFFER *secret, BUFFER *pass, int remail)
313     {
314     BUFFER *out, *key, *iv;
315     out = buf_new();
316     key = buf_new();
317     iv = buf_new();
318     if (pass == NULL || pass->length == 0 || remail == 2) {
319     buf_appendc(out, 0);
320     buf_cat(out, secret);
321     } else {
322     buf_appendc(out, 255);
323     pgp_makesk(out, key, PGP_K_CAST5, 3, PGP_H_SHA1, pass);
324 rabbi 98 buf_setrnd(iv, pgp_blocklen(PGP_K_CAST5));
325 rabbi 1 buf_cat(out, iv);
326     skcrypt(secret, PGP_K_CAST5, key, iv, 1);
327     buf_cat(out, secret);
328     }
329     buf_move(secret, out);
330     buf_free(out);
331     buf_free(key);
332     buf_free(iv);
333     }
334    
335     int pgp_nummpi(int algo)
336     {
337     switch (algo) {
338     case PGP_ES_RSA:
339     return (2);
340     case PGP_S_DSA:
341     return (4);
342     case PGP_E_ELG:
343     return (3);
344     default:
345     return (0);
346     }
347     }
348    
349     int pgp_numsecmpi(int algo)
350     {
351     switch (algo) {
352     case PGP_ES_RSA:
353     return (4);
354     case PGP_S_DSA:
355     return (1);
356     case PGP_E_ELG:
357     return (1);
358     default:
359     return (0);
360     }
361     }
362    
363     /* store key's ID in keyid */
364     int pgp_keyid(BUFFER *key, BUFFER *keyid)
365     {
366     BUFFER *i, *k;
367     int version, algo, j, ptr;
368    
369     i = buf_new();
370     k = buf_new();
371    
372     ptr = key->ptr;
373     key->ptr = 0;
374     switch (version = buf_getc(key)) {
375     case 2:
376     case 3:
377     buf_getl(key);
378     buf_geti(key);
379     buf_getc(key);
380     mpi_get(key, i);
381     break;
382     case 4:
383     buf_appendc(k, version);
384     buf_appendl(k, buf_getl(key));
385     algo = buf_getc(key);
386     buf_appendc(k, algo);
387     if (pgp_nummpi(algo) == 0)
388     buf_rest(k, key); /* works for public keys only */
389     else
390     for (j = 0; j < pgp_nummpi(algo); j++) {
391     mpi_get(key, i);
392     mpi_put(k, i);
393     }
394     buf_clear(i);
395     buf_appendc(i, 0x99);
396     buf_appendi(i, k->length);
397     buf_cat(i, k);
398     digest_sha1(i, i);
399     break;
400     }
401     buf_clear(keyid);
402     buf_append(keyid, i->data + i->length - 8, 8);
403     buf_free(i);
404     buf_free(k);
405     key->ptr = ptr;
406     return(0);
407     }
408    
409     static int pgp_iskeyid(BUFFER *key, BUFFER *keyid)
410     {
411     BUFFER *thisid;
412     int ret;
413    
414     thisid = buf_new();
415     pgp_keyid(key, thisid);
416     ret = buf_eq(keyid, thisid);
417     buf_free(thisid);
418     return(ret);
419     }
420    
421 disastry 255 static int pgp_get_sig_subpacket(BUFFER * p1, BUFFER *out)
422 disastry 254 {
423     int suptype, len = buf_getc(p1);
424     if (len > 192 && len < 255)
425     len = (len - 192) * 256 + buf_getc(p1) + 192;
426     else if (len == 255)
427     len = buf_getl(p1);
428     suptype = buf_getc(p1);
429     if (len)
430     buf_get(p1, out, len-1); /* len-1 - exclude type */
431     else
432     buf_clear(out);
433     return suptype;
434     }
435    
436     typedef struct _UIDD {
437     struct _UIDD * next;
438     long created, expires;
439     int revoked, sym, mdc, uid, primary;
440     BUFFER *uidstr;
441     } UIDD;
442    
443     static UIDD * new_uidd_c(UIDD *uidd_c, int uidno)
444     {
445     UIDD * tmp;
446    
447     if (!uidd_c || uidd_c->uid < uidno) {
448     tmp = (UIDD *)malloc(sizeof(UIDD));
449     if (!tmp)
450     return uidd_c;
451     if (uidd_c) {
452     uidd_c->next = tmp;
453     uidd_c = uidd_c->next;
454     } else
455     uidd_c = tmp;
456     if (uidd_c) {
457     memset(uidd_c, 0, sizeof(UIDD));
458     uidd_c->uid = uidno;
459     }
460     }
461     return uidd_c;
462     }
463    
464     int pgp_getkey(int mode, int algo, int *psym, int *pmdc, long *pexpires, BUFFER *keypacket, BUFFER *key,
465 rabbi 1 BUFFER *keyid, BUFFER *userid, BUFFER *pass)
466 disastry 254 /* IN: mode - PK_SIGN, PK_VERIFY, PK_DECRYPT, PK_ENCRYPT
467     * algo - PGP_ANY, PGP_ES_RSA, PGP_E_ELG, PGP_S_DSA
468     * psym - reyested sym PGP_K_ANY, PGP_K_IDEA, PGP_K_3DES, ... or NULL
469     * pass - passprase or NULL
470     * keypacket - key, with key uid sig subkey packets, possibly encrypted
471     * keyid - reyested (sub)keyid or empty buffer or NULL
472 weaselp 261 * OUT: psym - found sym algo (or NULL)
473     * pmdc - found mdc flag (or NULL)
474 disastry 254 * key - found key, only key packet, decrypted
475 weaselp 298 * may be the same buffer as keypacket (or NULL)
476 weaselp 261 * keyid - found (sub)keyid (or NULL)
477     * userid - found userid (or NULL)
478     * pexpires - expiry time, or 0 if don't expire (or NULL)
479 disastry 254 */
480 rabbi 1 {
481 weaselp 298 int tempbuf = 0, dummykey = 0;
482 rabbi 1 int keytype = -1, type, j;
483 weaselp 120 int thisalgo = 0, version, skalgo;
484 rabbi 135 int needsym = 0, symfound = 0, mdcfound = 0;
485 disastry 254 BUFFER *p1, *iv, *sk, *i, *thiskeyid, *mainkeyid;
486 rabbi 98 int ivlen;
487 rabbi 1 int csstart;
488 disastry 254 long now = time(NULL);
489     long created = 0, expires = 0, subexpires = 0;
490     int uidno = 0, primary = 0, subkeyno = 0, subkeyok = 0;
491     UIDD * uidd_1 = NULL, * uidd_c = NULL;
492 rabbi 1
493     p1 = buf_new();
494     i = buf_new();
495     iv = buf_new();
496     sk = buf_new();
497 ulfm 51 thiskeyid = buf_new();
498 disastry 254 mainkeyid = buf_new();
499 rabbi 1 if (psym)
500     needsym = *psym;
501     if (keypacket == key) {
502     key = buf_new();
503     tempbuf = 1;
504     }
505 weaselp 298 if (! key) {
506     key = buf_new();
507     dummykey = 1;
508     };
509 rabbi 1 if (userid)
510     buf_clear(userid);
511    
512     while ((type = pgp_getpacket(keypacket, p1)) > 0) {
513     switch (type) {
514     case PGP_SIG:
515 disastry 254 {
516 rabbi 1 /* it is assumed that only valid keys have been imported */
517 disastry 254 long a;
518     int self = 0, certexpires = 0, suptype;
519 weaselp 298 int sigtype = 0, sigver = buf_getc(p1);
520 disastry 254 created = 0, expires = 0, primary = 0;
521     if (sigver == 4) {
522 weaselp 332 sigtype = buf_getc(p1);
523 disastry 254 if (isPGP_SIG_CERT(sigtype) || sigtype == PGP_SIG_BINDSUBKEY || sigtype == PGP_SIG_CERTREVOKE) {
524     int revoked = (sigtype == PGP_SIG_CERTREVOKE), sym = PGP_K_3DES, mdc = 0;
525     buf_getc(p1); /* pk algo */
526     buf_getc(p1); /* hash algo */
527     j = buf_geti(p1); /* length of hashed signature subpackets */
528 rabbi 1 j += p1->ptr;
529     while (p1->ptr < j) {
530 disastry 254 suptype = pgp_get_sig_subpacket(p1, i);
531     switch (suptype & 0x7F) {
532     case PGP_SUB_PSYMMETRIC:
533 rabbi 1 while ((a = buf_getc(i)) != -1)
534 rabbi 135 if ((a == PGP_K_3DES || a == PGP_K_CAST5 || a == PGP_K_BF
535 rabbi 1 #ifdef USE_IDEA
536     || a == PGP_K_IDEA
537 rabbi 262 #endif /* USE_IDEA */
538 rabbi 135 #ifdef USE_AES
539     || a == PGP_K_AES128 || a == PGP_K_AES192 || a == PGP_K_AES256
540 rabbi 262 #endif /* USE_AES */
541 disastry 254 ) && (a == needsym || needsym == PGP_K_ANY)) {
542     sym = a;
543 rabbi 221 break; /* while ((a = buf_getc(i)) != -1) */
544     } /* if ((a == PGP_K_3DES)... */
545 disastry 254 break;
546     case PGP_SUB_FEATURES:
547 rabbi 135 if ((a = buf_getc(i)) != -1)
548     if (a & 0x01)
549 disastry 254 mdc = 1;
550     break;
551     case PGP_SUB_CREATIME:
552     if ((a = buf_getl(i)) != -1)
553     created = a;
554     break;
555     case PGP_SUB_KEYEXPIRETIME:
556     if ((a = buf_getl(i)) != -1)
557     expires = a;
558     break;
559     case PGP_SUB_CERTEXPIRETIME:
560     if ((a = buf_getl(i)) != -1)
561     certexpires = a;
562     break;
563     case PGP_SUB_ISSUER: /* ISSUER normaly is in unhashed data, but check anyway */
564     if (i->length == 8)
565     self = buf_eq(i, mainkeyid);
566     break;
567     case PGP_SUB_PRIMARY:
568     if ((a = buf_getl(i)) != -1)
569     primary = a;
570     break;
571     default:
572     if (suptype & 0x80) {
573     ; /* "critical" bit set! now what? */
574     }
575     } /* switch (suptype) */
576 rabbi 221 } /* while (p1->ptr < j) */
577 disastry 254 if (p1->ptr == j) {
578     j = buf_geti(p1); /* length of unhashed signature subpackets */
579     j += p1->ptr;
580     while (p1->ptr < j) {
581     suptype = pgp_get_sig_subpacket(p1, i);
582     if (suptype == PGP_SUB_ISSUER) {
583     if (i->length == 8)
584     self = buf_eq(i, mainkeyid);
585     } /* if (suptype == PGP_SUB_ISSUER) */
586     } /* while (p1->ptr < j) #2 */
587     } /* if (p1->ptr == j) */
588     if (p1->ptr != j) /* sig damaged ? */
589     break; /* switch (type) */
590     if (self) {
591     if (certexpires)
592     certexpires = ((created + certexpires < now) || (created + certexpires < 0));
593     if ((isPGP_SIG_CERT(sigtype) && !certexpires) || sigtype == PGP_SIG_CERTREVOKE) {
594     uidd_c = new_uidd_c(uidd_c, uidno);
595     if (!uidd_1)
596     uidd_1 = uidd_c;
597     if (uidd_c && uidd_c->uid == uidno) {
598     if (uidd_c->created <= created) {
599     /* if there is several selfsigs on that uid, find the newest one */
600     uidd_c->created = created;
601     uidd_c->expires = expires;
602     uidd_c->revoked = revoked;
603     uidd_c->primary = primary;
604     uidd_c->sym = sym;
605     uidd_c->mdc = mdc;
606     }
607     }
608     } /* if ((isPGP_SIG_CERT(sigtype) && !certexpires) || sigtype == PGP_SIG_CERTREVOKE) */
609     else if (sigtype == PGP_SIG_BINDSUBKEY) {
610     if (!subkeyok) {
611     subexpires = expires ? created + expires : 0;
612     if (expires && ((created + expires < now) || (created + expires < 0))) {
613     if (mode == PK_ENCRYPT) { /* allow decrypt with expired subkeys, but not encrypt */
614     keytype = -1;
615     }
616     }
617     if (keytype != -1)
618     subkeyok = subkeyno;
619     }
620     } /* if (sigtype == PGP_SIG_BINDSUBKEY) */
621     } /* if (self) */
622     } /* if (isPGP_SIG_CERT(sigtype) || sigtype == PGP_SIG_BINDSUBKEY || sigtype == PGP_SIG_CERTREVOKE) */
623     } /* if (sigver == 4) */
624     else if (sigver == 2 || sigver == 3) {
625 weaselp 332 buf_getc(p1); /* One-octet length of following hashed material. MUST be 5 */
626     sigtype = buf_getc(p1);
627 disastry 254 } /* if (sigver == 2 || sigver == 3) */
628     if (sigtype == PGP_SIG_KEYREVOKE) {
629 weaselp 332 /* revocation can be either v3 or v4. if v4 we could check issuer, but we don't do it... */
630 disastry 254 if (mode == PK_SIGN || mode == PK_ENCRYPT) { /* allow verify and decrypt with revokeded keys, but not sign and encrypt */
631     keytype = -1;
632     }
633     } /* if (sigtype == PGP_SIG_KEYREVOKE) */
634     else if (sigtype == PGP_SIG_SUBKEYREVOKE) {
635     if (!subkeyok || subkeyok == subkeyno)
636     if (mode == PK_ENCRYPT) { /* allow decrypt with revokeded subkeys, but not encrypt */
637     keytype = -1;
638     }
639     } /* if (sigtype == PGP_SIG_SUBKEYREVOKE) */
640 rabbi 221 break; /* switch (type) */
641 disastry 254 } /* case PGP_SIG: */
642 rabbi 1 case PGP_USERID:
643 disastry 254 uidno++;
644     uidd_c = new_uidd_c(uidd_c, uidno);
645     if (!uidd_1)
646     uidd_1 = uidd_c;
647     if (uidd_c && uidd_c->uid == uidno) {
648     uidd_c->uidstr = buf_new();
649     buf_set(uidd_c->uidstr, p1);
650     }
651 rabbi 1 if (userid)
652     buf_move(userid, p1);
653     break;
654     case PGP_PUBSUBKEY:
655     case PGP_SECSUBKEY:
656 disastry 254 subkeyno++;
657     if (keytype != -1 && subkeyno > 1) {
658 weaselp 332 /* usable subkey already found, don't bother to check other */
659 disastry 254 continue;
660     }
661 rabbi 1 if (keytype != -1 && (mode == PK_SIGN || mode == PK_VERIFY))
662     continue;
663     case PGP_PUBKEY:
664     if ((type == PGP_PUBKEY || type == PGP_PUBSUBKEY) &&
665     (mode == PK_DECRYPT || mode == PK_SIGN))
666     continue;
667 disastry 254 case PGP_SECKEY:
668     if (type == PGP_PUBKEY || type == PGP_SECKEY)
669     pgp_keyid(p1, mainkeyid);
670 rabbi 1 keytype = type;
671     version = buf_getc(p1);
672     switch (version) {
673     case 2:
674     case 3:
675 disastry 254 created = buf_getl(p1); /* created */
676     expires = buf_geti(p1) * (24*60*60); /* valid */
677     if (uidno == 0) {
678     uidd_c = new_uidd_c(uidd_c, uidno);
679     if (!uidd_1)
680     uidd_1 = uidd_c;
681     if (uidd_c && uidd_c->uid == uidno) {
682     uidd_c->created = created;
683     uidd_c->expires = expires;
684     uidd_c->sym = PGP_K_IDEA;
685     }
686     }
687 rabbi 1 thisalgo = buf_getc(p1);
688     if (thisalgo != PGP_ES_RSA) {
689     keytype = -1;
690     goto end;
691     }
692     symfound = PGP_K_IDEA;
693 disastry 254 mdcfound = 0;
694 rabbi 1 break;
695     case 4:
696     buf_appendc(key, version);
697     buf_appendl(key, buf_getl(p1));
698     thisalgo = buf_getc(p1);
699     buf_appendc(key, thisalgo);
700     if (symfound == 0)
701     symfound = PGP_K_3DES; /* default algorithm */
702     break;
703     default:
704     keytype = -1;
705     goto end;
706 disastry 254 } /* switch (version) */
707 rabbi 1 if (algo != PGP_ANY && thisalgo != algo) {
708     keytype = -1;
709     continue;
710     }
711     if (keyid && keyid->length && !pgp_iskeyid(p1, keyid))
712     continue;
713 ulfm 51 pgp_keyid(p1, thiskeyid);
714 rabbi 1 if (key) {
715     buf_clear(key);
716     for (j = 0; j < pgp_nummpi(thisalgo); j++) {
717     if (mpi_get(p1, i) == -1)
718     goto end;
719     mpi_put(key, i);
720     }
721     if (keytype == PGP_SECKEY || keytype == PGP_SECSUBKEY) {
722     csstart = key->length;
723     skalgo = getski(p1, pass, sk, iv);
724     switch (version) {
725     case 2:
726     case 3:
727 rabbi 98 ivlen = pgp_blocklen(skalgo);
728 rabbi 1 for (j = 0; j < pgp_numsecmpi(thisalgo); j++) {
729 rabbi 98 unsigned char lastb[16];
730 rabbi 1 if (mpi_get(p1, i) == -1) {
731     keytype = -1;
732     goto end;
733     }
734 rabbi 98 assert(ivlen <= 16);
735     memcpy(lastb, i->data+i->length-ivlen, ivlen);
736 rabbi 1 skcrypt(i, skalgo, sk, iv, DECRYPT);
737 rabbi 98 buf_clear(iv);
738     buf_append(iv, lastb, ivlen);
739 rabbi 1 mpi_put(key, i);
740 disastry 254 } /* for */
741     break; /* switch (version) */
742 rabbi 1 case 4:
743     buf_clear(i);
744     buf_rest(i, p1);
745     skcrypt(i, skalgo, sk, iv, DECRYPT);
746     buf_move(p1, i);
747     for (j = 0; j < pgp_numsecmpi(thisalgo); j++) {
748     if (mpi_get(p1, i) == -1) {
749     keytype = PGP_PASS;
750     goto end;
751     }
752     mpi_put(key, i);
753     }
754     break;
755 disastry 254 } /* switch (version) */
756 rabbi 1 if (pgp_csum(key, csstart) != buf_geti(p1)) {
757     keytype = PGP_PASS;
758     goto end;
759     }
760     }
761 disastry 254 } /* if (key) */
762     break; /* switch (type) */
763 rabbi 1 default:
764     /* ignore trust packets etc */
765     break;
766 rabbi 221 } /* switch (type) */
767     } /* while ((type = pgp_getpacket(keypacket, p1)) > 0) */
768 rabbi 1 end:
769 ulfm 51 if (keyid) buf_set(keyid, thiskeyid);
770 rabbi 1 if (tempbuf) {
771     buf_move(keypacket, key);
772     buf_free(key);
773     }
774 weaselp 298 if (dummykey) {
775     buf_free(key);
776     }
777 rabbi 1 buf_free(p1);
778     buf_free(i);
779     buf_free(iv);
780     buf_free(sk);
781 ulfm 51 buf_free(thiskeyid);
782 disastry 254 buf_free(mainkeyid);
783    
784     if (uidd_1) {
785     primary = 0;
786     created = expires = 0;
787     while (uidd_1) {
788     /* find newest uid which is not revoked or expired */
789     if (primary <= uidd_1->primary && created <= uidd_1->created && !uidd_1->revoked) {
790     created = uidd_1->created;
791     expires = uidd_1->expires;
792     primary = uidd_1->primary;
793     symfound = uidd_1->sym;
794     mdcfound = uidd_1->mdc;
795     if (userid && uidd_1->uidstr)
796     buf_set(userid, uidd_1->uidstr);
797     }
798     uidd_c = uidd_1;
799     uidd_1 = uidd_1->next;
800     if (uidd_c->uidstr)
801     buf_free(uidd_c->uidstr);
802     free(uidd_c);
803     }
804     if (expires && ((created + expires < now) || (created + expires < 0))) {
805     if (mode == PK_SIGN || mode == PK_ENCRYPT) { /* allow verify and decrypt with expired keys, but not sign and encrypt */
806 weaselp 332 keytype = -1;
807 disastry 254 }
808     }
809     } /* if (uidd_1) */
810     expires = expires ? created + expires : 0;
811     if (subexpires > 0 && expires > 0 && subexpires < expires)
812     expires = subexpires;
813     if (pexpires)
814     *pexpires = expires;
815    
816     if (!subkeyok && keytype == PGP_E_ELG && (mode == PK_DECRYPT || mode == PK_ENCRYPT))
817     keytype = -1; /* no usable subkey found, one with valid binding */
818    
819     if (needsym != PGP_K_ANY && needsym != symfound)
820 rabbi 1 keytype = -1;
821 disastry 254 else if (psym && *psym == PGP_K_ANY)
822 rabbi 1 *psym = symfound;
823 rabbi 135 if (pmdc)
824     *pmdc = mdcfound;
825 rabbi 1
826     return (keytype <= 0 ? keytype : thisalgo);
827     }
828    
829     int pgp_makepkpacket(int type, BUFFER *p, BUFFER *outtxt, BUFFER *out,
830     BUFFER *key, BUFFER *pass, time_t *created)
831     {
832     BUFFER *i, *id;
833     char txt[LINELEN], algoid;
834     int version, algo, valid = 0, err = 0;
835     int len, j;
836     struct tm *tc;
837    
838     i = buf_new();
839     id = buf_new();
840    
841     version = buf_getc(p);
842     buf_clear(key);
843     switch (version) {
844     case 2:
845     case 3:
846     *created = buf_getl(p);
847     valid = buf_geti(p);
848     algo = buf_getc(p);
849     if (algo != PGP_ES_RSA)
850     return(-1);
851     break;
852     case 4:
853     *created = buf_getl(p);
854     algo = buf_getc(p);
855     break;
856     default:
857     return(-1);
858     }
859    
860     switch (version) {
861     case 2:
862     case 3:
863     buf_appendc(key, version);
864     buf_appendl(key, *created);
865     buf_appendi(key, valid);
866     buf_appendc(key, algo);
867     break;
868     case 4:
869     buf_appendc(key, version);
870     buf_appendl(key, *created);
871     buf_appendc(key, algo);
872     break;
873     }
874    
875     pgp_keyid(p, id);
876     len = mpi_get(p, i);
877     mpi_put(key, i);
878     for (j = 1; j < pgp_nummpi(algo); j++) {
879     if (mpi_get(p, i) == -1) {
880     err = -1;
881     goto end;
882     }
883     mpi_put(key, i);
884     }
885     pgp_packet(key, type);
886     buf_cat(out, key);
887    
888     if (outtxt != NULL) {
889     switch(algo) {
890     case PGP_ES_RSA:
891     algoid = 'R';
892     break;
893     case PGP_S_DSA:
894     algoid = 'D';
895     break;
896     case PGP_E_ELG:
897     algoid = 'g';
898     break;
899     default:
900     algoid = '?';
901     }
902 weaselp 259 buf_appendf(outtxt, "%s %5d%c/%02X%02X%02X%02X ",
903 weaselp 332 type == PGP_PUBSUBKEY ? "sub" :
904 weaselp 185 type == PGP_PUBKEY ? "pub" :
905 weaselp 332 type == PGP_SECKEY ? "sec" :
906 weaselp 185 type == PGP_SECSUBKEY ? "ssb" :
907     "???", len, algoid,
908 rabbi 1 id->data[4], id->data[5], id->data[6], id->data[7]);
909     tc = localtime(created);
910 weaselp 259 strftime(txt, LINELEN, "%Y-%m-%d ", tc);
911 rabbi 1 buf_appends(outtxt, txt);
912     }
913     end:
914     buf_free(i);
915     buf_free(id);
916     return(err == 0 ? algo : err);
917     }
918    
919     int pgp_makepubkey(BUFFER *keypacket, BUFFER *outtxt, BUFFER *out,
920     BUFFER *pass, int keyalgo)
921     {
922     BUFFER *p, *pubkey, *seckey, *subkey, *sig, *tmp;
923     int err = -1, type, thisalgo;
924     time_t created;
925    
926     p = buf_new();
927     seckey = buf_new();
928     pubkey = buf_new();
929     subkey = buf_new();
930     sig = buf_new();
931     tmp = buf_new();
932    
933     buf_set(seckey, keypacket);
934     type = pgp_getpacket(keypacket, p);
935     if (type != PGP_SECKEY)
936     goto end;
937    
938     thisalgo = pgp_makepkpacket(PGP_PUBKEY, p, outtxt, tmp, pubkey, pass,
939     &created);
940     if (thisalgo == -1 || (keyalgo != 0 && keyalgo != thisalgo))
941     goto end;
942     buf_cat(out, tmp);
943    
944     while ((type = pgp_getpacket(keypacket, p)) > 0) {
945     if (type == PGP_SECSUBKEY) {
946     if (pgp_makepkpacket(PGP_PUBSUBKEY, p, outtxt, out, subkey, pass,
947     &created) == -1)
948     goto end;
949     if (pgp_sign(pubkey, subkey, sig, NULL, pass, PGP_SIG_BINDSUBKEY, 0,
950     created, 0, seckey, NULL) != -1)
951     buf_cat(out, sig);
952     if (outtxt)
953     buf_nl(outtxt);
954     } else if (type == PGP_USERID) {
955     if (outtxt != NULL) {
956     buf_cat(outtxt, p);
957     buf_nl(outtxt);
958     }
959     pgp_packet(p, PGP_USERID);
960     err = pgp_sign(pubkey, p, sig, NULL, pass, PGP_SIG_CERT, 1, created, 0,
961 disastry 254 seckey, NULL); /* maybe PGP_SIG_CERT3 ? */
962 rabbi 1 buf_cat(out, p);
963     if (err == 0)
964     buf_cat(out, sig);
965     } else if (type == PGP_PUBKEY || type == PGP_SECKEY)
966     break;
967     }
968     end:
969     buf_free(pubkey);
970     buf_free(seckey);
971     buf_free(subkey);
972     buf_free(sig);
973     buf_free(p);
974     buf_free(tmp);
975     return (err);
976     }
977    
978 weaselp 295 int pgp_makekeyheader(int type, BUFFER *keypacket, BUFFER *outtxt,
979 weaselp 185 BUFFER *pass, int keyalgo)
980     {
981     BUFFER *p, *pubkey, *seckey, *subkey, *sig, *tmp, *dummy;
982 weaselp 295 int thisalgo, err = -1;
983 weaselp 185 time_t created;
984    
985 weaselp 295 assert(type == PGP_SECKEY || type == PGP_PUBKEY);
986 weaselp 332
987 weaselp 185 p = buf_new();
988     seckey = buf_new();
989     pubkey = buf_new();
990     subkey = buf_new();
991     sig = buf_new();
992     tmp = buf_new();
993     dummy = buf_new();
994    
995     buf_set(seckey, keypacket);
996 weaselp 295 if (type != pgp_getpacket(keypacket, p))
997 weaselp 185 goto end;
998    
999 weaselp 295 thisalgo = pgp_makepkpacket(type, p, outtxt, tmp, pubkey, pass,
1000 weaselp 185 &created);
1001     if (thisalgo == -1 || (keyalgo != 0 && keyalgo != thisalgo))
1002     goto end;
1003    
1004     while ((type = pgp_getpacket(keypacket, p)) > 0) {
1005 weaselp 295 if (type == PGP_SECSUBKEY || type == PGP_PUBSUBKEY) {
1006     if (pgp_makepkpacket(type, p, outtxt, dummy, subkey, pass,
1007 weaselp 185 &created) == -1)
1008     goto end;
1009     buf_nl(outtxt);
1010     } else if (type == PGP_USERID) {
1011     buf_cat(outtxt, p);
1012     buf_nl(outtxt);
1013     pgp_packet(p, PGP_USERID);
1014     } else if (type == PGP_PUBKEY || type == PGP_SECKEY)
1015     break;
1016     }
1017     err = 0;
1018     end:
1019     buf_free(pubkey);
1020     buf_free(seckey);
1021     buf_free(subkey);
1022     buf_free(sig);
1023     buf_free(p);
1024     buf_free(dummy);
1025     buf_free(tmp);
1026     return (err);
1027     }
1028    
1029 rabbi 1 int pgp_rsakeygen(int bits, BUFFER *userid, BUFFER *pass, char *pubring,
1030     char *secring, int remail)
1031     /* remail==2: encrypt the secring */
1032     {
1033     RSA *k;
1034     KEYRING *keydb;
1035     BUFFER *pkey, *skey;
1036     BUFFER *dk, *sig, *iv, *p;
1037     long now;
1038     int skalgo = 0;
1039     int err = 0;
1040    
1041     pkey = buf_new();
1042     skey = buf_new();
1043     iv = buf_new();
1044     dk = buf_new();
1045     p = buf_new();
1046     sig = buf_new();
1047    
1048     errlog(NOTICE, "Generating OpenPGP RSA key.\n");
1049 disastry 212 k = RSA_generate_key(bits == 0 ? 1024 : bits, 17, NULL, NULL);
1050 rabbi 1 if (k == NULL) {
1051     err = -1;
1052     goto end;
1053     }
1054     now = time(NULL);
1055     if (remail) /* fake time in nym keys */
1056     now -= rnd_number(4 * 24 * 60 * 60);
1057    
1058     buf_appendc(skey, 3);
1059     buf_appendl(skey, now);
1060 weaselp 505 /* until we can handle the case, where our key expires, don't create keys with expiration dates */
1061     buf_appendi(skey, 0);
1062     /* buf_appendi(skey, KEYLIFETIME/(24*60*60)); */
1063 rabbi 1 buf_appendc(skey, PGP_ES_RSA);
1064     mpi_bnput(skey, k->n);
1065     mpi_bnput(skey, k->e);
1066    
1067     #ifdef USE_IDEA
1068     if (pass != NULL && pass->length > 0 && remail != 2) {
1069     skalgo = PGP_K_IDEA;
1070     digest_md5(pass, dk);
1071 rabbi 98 buf_setrnd(iv, pgp_blocklen(skalgo));
1072 rabbi 1 buf_appendc(skey, skalgo);
1073     buf_cat(skey, iv);
1074     }
1075     else
1076 rabbi 262 #endif /* USE_IDEA */
1077 rabbi 1 buf_appendc(skey, 0);
1078    
1079     mpi_bnputenc(skey, k->d, skalgo, dk, iv);
1080     mpi_bnputenc(skey, k->q, skalgo, dk, iv);
1081     mpi_bnputenc(skey, k->p, skalgo, dk, iv);
1082     mpi_bnputenc(skey, k->iqmp, skalgo, dk, iv);
1083    
1084     buf_clear(p);
1085     mpi_bnput(p, k->d);
1086     mpi_bnput(p, k->q);
1087     mpi_bnput(p, k->p);
1088     mpi_bnput(p, k->iqmp);
1089     buf_appendi(skey, pgp_csum(p, 0));
1090    
1091     pgp_packet(skey, PGP_SECKEY);
1092     buf_set(p, userid);
1093     pgp_packet(p, PGP_USERID);
1094     buf_cat(skey, p);
1095    
1096     if (secring == NULL)
1097     secring = PGPREMSECRING;
1098 weaselp 285 keydb = pgpdb_open(secring, remail == 2 ? pass : NULL, 1, PGP_TYPE_PRIVATE);
1099 rabbi 1 if (keydb == NULL) {
1100     err = -1;
1101     goto end;
1102     }
1103     if (keydb->filetype == -1)
1104 weaselp 185 keydb->filetype = ARMORED;
1105 rabbi 1 pgpdb_append(keydb, skey);
1106 weaselp 284 pgpdb_close(keydb);
1107 rabbi 1
1108     if (pubring != NULL) {
1109     if (pgp_makepubkey(skey, NULL, pkey, pass, 0) == -1)
1110     goto end;
1111 weaselp 285 keydb = pgpdb_open(pubring, NULL, 1, PGP_TYPE_PUBLIC);
1112 rabbi 1 if (keydb == NULL)
1113     goto end;
1114     if (keydb->filetype == -1)
1115     keydb->filetype = ARMORED;
1116     pgpdb_append(keydb, pkey);
1117 weaselp 284 pgpdb_close(keydb);
1118 rabbi 1 }
1119     end:
1120 weaselp 86 RSA_free(k);
1121 rabbi 1 buf_free(pkey);
1122     buf_free(skey);
1123     buf_free(iv);
1124     buf_free(dk);
1125     buf_free(p);
1126     buf_free(sig);
1127     return (err);
1128     }
1129    
1130     #define begin_param "-----BEGIN PUBLIC PARAMETER BLOCK-----"
1131     #define end_param "-----END PUBLIC PARAMETER BLOCK-----"
1132    
1133     static void *params(int dsa, int bits)
1134     {
1135     DSA *k = NULL;
1136     DH *d = NULL;
1137     FILE *f;
1138     BUFFER *p, *n;
1139     char line[LINELEN];
1140     byte b[1024];
1141     int m, l;
1142    
1143     if (bits == 0)
1144     bits = 1024;
1145     if (dsa && bits > 1024)
1146     bits = 1024;
1147    
1148     p = buf_new();
1149     n = buf_new();
1150     f = mix_openfile(dsa ? DSAPARAMS : DHPARAMS, "r");
1151     if (f != NULL) {
1152     for (;;) {
1153     if (fgets(line, sizeof(line), f) == NULL)
1154     break;
1155     if (strleft(line, begin_param)) {
1156     if (fgets(line, sizeof(line), f) == NULL)
1157     break;
1158     m = 0;
1159     sscanf(line, "%d", &m);
1160     if (bits == m) {
1161     buf_clear(p);
1162     while (fgets(line, sizeof(line), f) != NULL) {
1163     if (strleft(line, end_param)) {
1164     decode(p, p);
1165     if (dsa) {
1166     k = DSA_new();
1167     l = buf_geti(p);
1168     buf_get(p, n, l);
1169     k->p = BN_bin2bn(n->data, n->length, NULL);
1170     l = buf_geti(p);
1171     buf_get(p, n, l);
1172     k->q = BN_bin2bn(n->data, n->length, NULL);
1173     l = buf_geti(p);
1174     buf_get(p, n, l);
1175     k->g = BN_bin2bn(n->data, n->length, NULL);
1176     } else {
1177     d = DH_new();
1178     l = buf_geti(p);
1179     buf_get(p, n, l);
1180     d->p = BN_bin2bn(n->data, n->length, NULL);
1181     l = buf_geti(p);
1182     buf_get(p, n, l);
1183     d->g = BN_bin2bn(n->data, n->length, NULL);
1184     }
1185     break;
1186     }
1187     buf_appends(p, line);
1188     }
1189     }
1190     }
1191     }
1192     fclose(f);
1193     }
1194    
1195     buf_free(p);
1196     buf_free(n);
1197    
1198     if (dsa) {
1199     if (k == NULL) {
1200     errlog(NOTICE, "Generating DSA parameters.\n");
1201     k = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
1202     p = buf_new();
1203     l = BN_bn2bin(k->p, b);
1204     buf_appendi(p, l);
1205     buf_append(p, b, l);
1206     l = BN_bn2bin(k->q, b);
1207     buf_appendi(p, l);
1208     buf_append(p, b, l);
1209     l = BN_bn2bin(k->g, b);
1210     buf_appendi(p, l);
1211     buf_append(p, b, l);
1212     encode(p, 64);
1213     f = mix_openfile(DSAPARAMS, "a");
1214 weaselp 478 if (f != NULL) {
1215     fprintf(f, "%s\n%d\n", begin_param, bits);
1216     buf_write(p, f);
1217     fprintf(f, "%s\n", end_param);
1218     fclose(f);
1219     } else
1220     errlog(ERRORMSG, "Cannot open %s!\n", DSAPARAMS);
1221 rabbi 1 buf_free(p);
1222     }
1223     return (k);
1224     } else {
1225     if (d == NULL) {
1226     errlog(NOTICE, "Generating DH parameters. (This may take a long time!)\n");
1227     d = DH_generate_parameters(bits, DH_GENERATOR_5, NULL, NULL);
1228     p = buf_new();
1229     l = BN_bn2bin(d->p, b);
1230     buf_appendi(p, l);
1231     buf_append(p, b, l);
1232     l = BN_bn2bin(d->g, b);
1233     buf_appendi(p, l);
1234     buf_append(p, b, l);
1235     encode(p, 64);
1236     f = mix_openfile(DHPARAMS, "a");
1237 weaselp 478 if (f != NULL) {
1238     fprintf(f, "%s\n%d\n", begin_param, bits);
1239     buf_write(p, f);
1240     fprintf(f, "%s\n", end_param);
1241     fclose(f);
1242     } else
1243     errlog(ERRORMSG, "Cannot open %s!\n", DHPARAMS);
1244 rabbi 1 buf_free(p);
1245     }
1246     return (d);
1247     }
1248     }
1249    
1250     int pgp_dhkeygen(int bits, BUFFER *userid, BUFFER *pass, char *pubring,
1251     char *secring, int remail)
1252     /* remail==2: encrypt the secring */
1253     {
1254     DSA *s;
1255     DH *e;
1256     KEYRING *keydb;
1257     BUFFER *pkey, *skey, *subkey, *secret;
1258     BUFFER *dk, *sig, *iv, *p;
1259     long now;
1260     int err = 0;
1261    
1262     pkey = buf_new();
1263     skey = buf_new();
1264     subkey = buf_new();
1265     iv = buf_new();
1266     dk = buf_new();
1267     p = buf_new();
1268     sig = buf_new();
1269     secret = buf_new();
1270    
1271     s = params(1, bits);
1272     errlog(NOTICE, "Generating OpenPGP DSA key.\n");
1273     if (s == NULL || DSA_generate_key(s) != 1) {
1274     err = -1;
1275     goto end;
1276     }
1277     e = params(0, bits);
1278     errlog(NOTICE, "Generating OpenPGP ElGamal key.\n");
1279     if (e == NULL || DH_generate_key(e) != 1) {
1280     err = -1;
1281     goto end;
1282     }
1283    
1284     now = time(NULL);
1285     if (remail) /* fake time in nym keys */
1286     now -= rnd_number(4 * 24 * 60 * 60);
1287    
1288     /* DSA key */
1289     buf_setc(skey, 4);
1290     buf_appendl(skey, now);
1291     buf_appendc(skey, PGP_S_DSA);
1292     mpi_bnput(skey, s->p);
1293     mpi_bnput(skey, s->q);
1294     mpi_bnput(skey, s->g);
1295     mpi_bnput(skey, s->pub_key);
1296    
1297     mpi_bnput(secret, s->priv_key);
1298     buf_appendi(secret, pgp_csum(secret, 0));
1299     makeski(secret, pass, remail);
1300     buf_cat(skey, secret);
1301     pgp_packet(skey, PGP_SECKEY);
1302    
1303     /* ElGamal key */
1304     buf_setc(subkey, 4);
1305     buf_appendl(subkey, now);
1306     buf_appendc(subkey, PGP_E_ELG);
1307     mpi_bnput(subkey, e->p);
1308     mpi_bnput(subkey, e->g);
1309     mpi_bnput(subkey, e->pub_key);
1310    
1311     buf_clear(secret);
1312     mpi_bnput(secret, e->priv_key);
1313     buf_appendi(secret, pgp_csum(secret, 0));
1314     makeski(secret, pass, remail);
1315     buf_cat(subkey, secret);
1316    
1317     buf_set(p, userid);
1318     pgp_packet(p, PGP_USERID);
1319     buf_cat(skey, p);
1320    
1321     pgp_packet(subkey, PGP_SECSUBKEY);
1322     buf_cat(skey, subkey);
1323    
1324     if (secring == NULL)
1325     secring = PGPREMSECRING;
1326 weaselp 285 keydb = pgpdb_open(secring, remail == 2 ? pass : NULL, 1, PGP_TYPE_PRIVATE);
1327 rabbi 1 if (keydb == NULL) {
1328     err = -1;
1329     goto end;
1330     }
1331     if (keydb->filetype == -1)
1332 weaselp 185 keydb->filetype = ARMORED;
1333 rabbi 1 pgpdb_append(keydb, skey);
1334 weaselp 284 pgpdb_close(keydb);
1335 rabbi 1
1336     if (pubring != NULL) {
1337     pgp_makepubkey(skey, NULL, pkey, pass, 0);
1338 weaselp 285 keydb = pgpdb_open(pubring, NULL, 1, PGP_TYPE_PUBLIC);
1339 rabbi 1 if (keydb == NULL)
1340     goto end;
1341     if (keydb->filetype == -1)
1342     keydb->filetype = ARMORED;
1343     pgpdb_append(keydb, pkey);
1344 weaselp 284 pgpdb_close(keydb);
1345 rabbi 1 }
1346     end:
1347     buf_free(pkey);
1348     buf_free(skey);
1349     buf_free(subkey);
1350     buf_free(iv);
1351     buf_free(dk);
1352     buf_free(p);
1353     buf_free(sig);
1354     buf_free(secret);
1355     return (err);
1356     }
1357    
1358     int pgp_dsasign(BUFFER *data, BUFFER *key, BUFFER *out)
1359     {
1360     BUFFER *mpi, *b;
1361     DSA *d;
1362     DSA_SIG *sig = NULL;
1363    
1364     d = DSA_new();
1365     b = buf_new();
1366     mpi = buf_new();
1367     mpi_get(key, mpi);
1368     d->p = BN_bin2bn(mpi->data, mpi->length, NULL);
1369     mpi_get(key, mpi);
1370     d->q = BN_bin2bn(mpi->data, mpi->length, NULL);
1371     mpi_get(key, mpi);
1372     d->g = BN_bin2bn(mpi->data, mpi->length, NULL);
1373     mpi_get(key, mpi);
1374     d->pub_key = BN_bin2bn(mpi->data, mpi->length, NULL);
1375     if (mpi_get(key, mpi) == -1) {
1376     goto end;
1377     }
1378     d->priv_key = BN_bin2bn(mpi->data, mpi->length, NULL);
1379    
1380     sig = DSA_do_sign(data->data, data->length, d);
1381     if (sig) {
1382     buf_prepare(b, BN_num_bytes(sig->r));
1383     b->length = BN_bn2bin(sig->r, b->data);
1384     mpi_put(out, b);
1385     b->length = BN_bn2bin(sig->s, b->data);
1386     mpi_put(out, b);
1387     }
1388     end:
1389     buf_free(mpi);
1390     buf_free(b);
1391     DSA_SIG_free(sig);
1392     DSA_free(d);
1393     return(sig ? 0 : -1);
1394     }
1395    
1396     int pgp_dosign(int algo, BUFFER *data, BUFFER *key)
1397     {
1398     int err;
1399     BUFFER *out, *r, *s;
1400 weaselp 332
1401 rabbi 1 out = buf_new();
1402     r = buf_new();
1403     s = buf_new();
1404     switch (algo) {
1405     case PGP_ES_RSA:
1406     err = pgp_rsa(data, key, PK_SIGN);
1407     if (err == 0)
1408     mpi_put(out, data);
1409     break;
1410     case PGP_S_DSA:
1411     err = pgp_dsasign(data, key, out);
1412     break;
1413     default:
1414     errlog(NOTICE, "Unknown encryption algorithm!\n");
1415     return (-1);
1416     }
1417     if (err == -1)
1418     errlog(ERRORMSG, "Signing operation failed!\n");
1419    
1420     buf_move(data, out);
1421     buf_free(out);
1422     buf_free(r);
1423     buf_free(s);
1424     return (err);
1425     }
1426    
1427     int pgp_elgdecrypt(BUFFER *in, BUFFER *key)
1428     {
1429 weaselp 120 BIGNUM *a = NULL, *b = NULL, *c = NULL,
1430 weaselp 332 *p = NULL, *g = NULL, *x = NULL;
1431 rabbi 1 BN_CTX *ctx;
1432     BUFFER *i;
1433     int err = -1;
1434    
1435     i = buf_new();
1436     ctx = BN_CTX_new();
1437 weaselp 332 if (ctx == NULL) goto end;
1438 rabbi 1 mpi_get(key, i);
1439     p = BN_bin2bn(i->data, i->length, NULL);
1440     mpi_get(key, i);
1441     g = BN_bin2bn(i->data, i->length, NULL);
1442     mpi_get(key, i); /* y */
1443     mpi_get(key, i);
1444     x = BN_bin2bn(i->data, i->length, NULL);
1445     mpi_get(in, i);
1446     a = BN_bin2bn(i->data, i->length, NULL);
1447     if (mpi_get(in, i) == -1)
1448     goto e1;
1449     b = BN_bin2bn(i->data, i->length, NULL);
1450     c = BN_new();
1451    
1452     if (BN_mod_exp(c, a, x, p, ctx) == 0) goto end;
1453     if (BN_mod_inverse(a, c, p, ctx) == 0) goto end;
1454     if (BN_mod_mul(c, a, b, p, ctx) == 0) goto end;
1455    
1456     buf_prepare(i, BN_num_bytes(c));
1457     i->length = BN_bn2bin(c, i->data);
1458    
1459     buf_prepare(in, BN_num_bytes(c));
1460     in->length = RSA_padding_check_PKCS1_type_2(in->data, in->length, i->data,
1461     i->length, i->length + 1);
1462     if (in->length <= 0)
1463     in->length = 0;
1464     else
1465     err = 0;
1466    
1467     end:
1468     BN_free(b);
1469     BN_free(c);
1470     e1:
1471     buf_free(i);
1472     BN_free(a);
1473     BN_free(p);
1474     BN_free(g);
1475     BN_clear_free(x);
1476     BN_CTX_free(ctx);
1477    
1478     return (err);
1479     }
1480    
1481     int pgp_elgencrypt(BUFFER *in, BUFFER *key)
1482     {
1483 weaselp 120 BIGNUM *m, *k, *a, *b, *c, *p, *g, *y = NULL;
1484 rabbi 1 BN_CTX *ctx;
1485     BUFFER *i;
1486     int err = -1;
1487 weaselp 332
1488 rabbi 1 i = buf_new();
1489     ctx = BN_CTX_new();
1490 weaselp 332 if (ctx == NULL) goto end;
1491 rabbi 1 mpi_get(key, i);
1492     p = BN_bin2bn(i->data, i->length, NULL);
1493     mpi_get(key, i);
1494     g = BN_bin2bn(i->data, i->length, NULL);
1495     if (mpi_get(key, i) == -1)
1496     goto e1;
1497     y = BN_bin2bn(i->data, i->length, NULL);
1498    
1499     buf_prepare(i, BN_num_bytes(p));
1500     if (RSA_padding_add_PKCS1_type_2(i->data, i->length, in->data, in->length)
1501     != 1)
1502     goto end;
1503     m = BN_bin2bn(i->data, i->length, NULL);
1504    
1505     k = BN_new();
1506     BN_rand(k, BN_num_bits(p), 0, 0);
1507    
1508     a = BN_new();
1509     b = BN_new();
1510     c = BN_new();
1511    
1512     if (BN_mod_exp(a, g, k, p, ctx) == 0) goto end;
1513     if (BN_mod_exp(c, y, k, p, ctx) == 0) goto end;
1514     if (BN_mod_mul(b, m, c, p, ctx) == 0) goto end;
1515    
1516     buf_clear(in);
1517     i->length = BN_bn2bin(a, i->data);
1518     mpi_put(in, i);
1519     i->length = BN_bn2bin(b, i->data);
1520     mpi_put(in, i);
1521 weaselp 332
1522 rabbi 1 err = 0;
1523    
1524     BN_free(a);
1525     BN_free(b);
1526     BN_free(c);
1527     BN_free(m);
1528     e1:
1529     buf_free(i);
1530     BN_free(p);
1531     BN_free(g);
1532     BN_free(y);
1533     BN_CTX_free(ctx);
1534     end:
1535    
1536     return (err);
1537     }
1538    
1539     #endif /* USE_PGP */

Properties

Name Value
svn:keywords Id

  ViewVC Help
Powered by ViewVC 1.1.5