/[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 295 - (hide annotations) (download)
Tue Oct 1 08:23:20 2002 UTC (10 years, 8 months ago) by weaselp
File MIME type: text/plain
File size: 36660 byte(s)
Write keyid, creation date, etc header along with armored keys to pgpkey.txt
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 weaselp 295 $Id: pgpdata.c,v 1.24 2002/10/01 08:23:20 weaselp 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 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     #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 rabbi 262 #endif /* 1 */
184 rabbi 1 }
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 rabbi 262 #endif /* USE_RSA */
218 rabbi 1
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 rabbi 262 #endif /* 0 */
239 rabbi 1 ))
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 disastry 255 static int pgp_get_sig_subpacket(BUFFER * p1, BUFFER *out)
424 disastry 254 {
425     int suptype, len = buf_getc(p1);
426     if (len > 192 && len < 255)
427     len = (len - 192) * 256 + buf_getc(p1) + 192;
428     else if (len == 255)
429     len = buf_getl(p1);
430     suptype = buf_getc(p1);
431     if (len)
432     buf_get(p1, out, len-1); /* len-1 - exclude type */
433     else
434     buf_clear(out);
435     return suptype;
436     }
437    
438     typedef struct _UIDD {
439     struct _UIDD * next;
440     long created, expires;
441     int revoked, sym, mdc, uid, primary;
442     BUFFER *uidstr;
443     } UIDD;
444    
445     static UIDD * new_uidd_c(UIDD *uidd_c, int uidno)
446     {
447     UIDD * tmp;
448    
449     if (!uidd_c || uidd_c->uid < uidno) {
450     tmp = (UIDD *)malloc(sizeof(UIDD));
451     if (!tmp)
452     return uidd_c;
453     if (uidd_c) {
454     uidd_c->next = tmp;
455     uidd_c = uidd_c->next;
456     } else
457     uidd_c = tmp;
458     if (uidd_c) {
459     memset(uidd_c, 0, sizeof(UIDD));
460     uidd_c->uid = uidno;
461     }
462     }
463     return uidd_c;
464     }
465    
466     int pgp_getkey(int mode, int algo, int *psym, int *pmdc, long *pexpires, BUFFER *keypacket, BUFFER *key,
467 rabbi 1 BUFFER *keyid, BUFFER *userid, BUFFER *pass)
468 disastry 254 /* IN: mode - PK_SIGN, PK_VERIFY, PK_DECRYPT, PK_ENCRYPT
469     * algo - PGP_ANY, PGP_ES_RSA, PGP_E_ELG, PGP_S_DSA
470     * psym - reyested sym PGP_K_ANY, PGP_K_IDEA, PGP_K_3DES, ... or NULL
471     * pass - passprase or NULL
472     * keypacket - key, with key uid sig subkey packets, possibly encrypted
473     * keyid - reyested (sub)keyid or empty buffer or NULL
474 weaselp 261 * OUT: psym - found sym algo (or NULL)
475     * pmdc - found mdc flag (or NULL)
476 disastry 254 * key - found key, only key packet, decrypted
477 weaselp 261 * may be the same buffer as keypacket
478     * keyid - found (sub)keyid (or NULL)
479     * userid - found userid (or NULL)
480     * pexpires - expiry time, or 0 if don't expire (or NULL)
481 disastry 254 */
482 rabbi 1 {
483     int tempbuf = 0;
484     int keytype = -1, type, j;
485 weaselp 120 int thisalgo = 0, version, skalgo;
486 rabbi 135 int needsym = 0, symfound = 0, mdcfound = 0;
487 disastry 254 BUFFER *p1, *iv, *sk, *i, *thiskeyid, *mainkeyid;
488 rabbi 98 int ivlen;
489 rabbi 1 int csstart;
490 disastry 254 long now = time(NULL);
491     long created = 0, expires = 0, subexpires = 0;
492     int uidno = 0, primary = 0, subkeyno = 0, subkeyok = 0;
493     UIDD * uidd_1 = NULL, * uidd_c = NULL;
494 rabbi 1
495     p1 = buf_new();
496     i = buf_new();
497     iv = buf_new();
498     sk = buf_new();
499 ulfm 51 thiskeyid = buf_new();
500 disastry 254 mainkeyid = buf_new();
501 rabbi 1 if (psym)
502     needsym = *psym;
503     if (keypacket == key) {
504     key = buf_new();
505     tempbuf = 1;
506     }
507     if (userid)
508     buf_clear(userid);
509    
510     while ((type = pgp_getpacket(keypacket, p1)) > 0) {
511     switch (type) {
512     case PGP_SIG:
513 disastry 254 {
514 rabbi 1 /* it is assumed that only valid keys have been imported */
515 disastry 254 long a;
516     int self = 0, certexpires = 0, suptype;
517     int sigtype, sigver = buf_getc(p1);
518     created = 0, expires = 0, primary = 0;
519     if (sigver == 4) {
520     sigtype = buf_getc(p1);
521     if (isPGP_SIG_CERT(sigtype) || sigtype == PGP_SIG_BINDSUBKEY || sigtype == PGP_SIG_CERTREVOKE) {
522     int revoked = (sigtype == PGP_SIG_CERTREVOKE), sym = PGP_K_3DES, mdc = 0;
523     buf_getc(p1); /* pk algo */
524     buf_getc(p1); /* hash algo */
525     j = buf_geti(p1); /* length of hashed signature subpackets */
526 rabbi 1 j += p1->ptr;
527     while (p1->ptr < j) {
528 disastry 254 suptype = pgp_get_sig_subpacket(p1, i);
529     switch (suptype & 0x7F) {
530     case PGP_SUB_PSYMMETRIC:
531 rabbi 1 while ((a = buf_getc(i)) != -1)
532 rabbi 135 if ((a == PGP_K_3DES || a == PGP_K_CAST5 || a == PGP_K_BF
533 rabbi 1 #ifdef USE_IDEA
534     || a == PGP_K_IDEA
535 rabbi 262 #endif /* USE_IDEA */
536 rabbi 135 #ifdef USE_AES
537     || a == PGP_K_AES128 || a == PGP_K_AES192 || a == PGP_K_AES256
538 rabbi 262 #endif /* USE_AES */
539 disastry 254 ) && (a == needsym || needsym == PGP_K_ANY)) {
540     sym = a;
541 rabbi 221 break; /* while ((a = buf_getc(i)) != -1) */
542     } /* if ((a == PGP_K_3DES)... */
543 disastry 254 break;
544     case PGP_SUB_FEATURES:
545 rabbi 135 if ((a = buf_getc(i)) != -1)
546     if (a & 0x01)
547 disastry 254 mdc = 1;
548     break;
549     case PGP_SUB_CREATIME:
550     if ((a = buf_getl(i)) != -1)
551     created = a;
552     break;
553     case PGP_SUB_KEYEXPIRETIME:
554     if ((a = buf_getl(i)) != -1)
555     expires = a;
556     break;
557     case PGP_SUB_CERTEXPIRETIME:
558     if ((a = buf_getl(i)) != -1)
559     certexpires = a;
560     break;
561     case PGP_SUB_ISSUER: /* ISSUER normaly is in unhashed data, but check anyway */
562     if (i->length == 8)
563     self = buf_eq(i, mainkeyid);
564     break;
565     case PGP_SUB_PRIMARY:
566     if ((a = buf_getl(i)) != -1)
567     primary = a;
568     break;
569     default:
570     if (suptype & 0x80) {
571     ; /* "critical" bit set! now what? */
572     }
573     } /* switch (suptype) */
574 rabbi 221 } /* while (p1->ptr < j) */
575 disastry 254 if (p1->ptr == j) {
576     j = buf_geti(p1); /* length of unhashed signature subpackets */
577     j += p1->ptr;
578     while (p1->ptr < j) {
579     suptype = pgp_get_sig_subpacket(p1, i);
580     if (suptype == PGP_SUB_ISSUER) {
581     if (i->length == 8)
582     self = buf_eq(i, mainkeyid);
583     } /* if (suptype == PGP_SUB_ISSUER) */
584     } /* while (p1->ptr < j) #2 */
585     } /* if (p1->ptr == j) */
586     if (p1->ptr != j) /* sig damaged ? */
587     break; /* switch (type) */
588     if (self) {
589     if (certexpires)
590     certexpires = ((created + certexpires < now) || (created + certexpires < 0));
591     if ((isPGP_SIG_CERT(sigtype) && !certexpires) || sigtype == PGP_SIG_CERTREVOKE) {
592     uidd_c = new_uidd_c(uidd_c, uidno);
593     if (!uidd_1)
594     uidd_1 = uidd_c;
595     if (uidd_c && uidd_c->uid == uidno) {
596     if (uidd_c->created <= created) {
597     /* if there is several selfsigs on that uid, find the newest one */
598     uidd_c->created = created;
599     uidd_c->expires = expires;
600     uidd_c->revoked = revoked;
601     uidd_c->primary = primary;
602     uidd_c->sym = sym;
603     uidd_c->mdc = mdc;
604     }
605     }
606     } /* if ((isPGP_SIG_CERT(sigtype) && !certexpires) || sigtype == PGP_SIG_CERTREVOKE) */
607     else if (sigtype == PGP_SIG_BINDSUBKEY) {
608     if (!subkeyok) {
609     subexpires = expires ? created + expires : 0;
610     if (expires && ((created + expires < now) || (created + expires < 0))) {
611     if (mode == PK_ENCRYPT) { /* allow decrypt with expired subkeys, but not encrypt */
612     keytype = -1;
613     }
614     }
615     if (keytype != -1)
616     subkeyok = subkeyno;
617     }
618     } /* if (sigtype == PGP_SIG_BINDSUBKEY) */
619     } /* if (self) */
620     } /* if (isPGP_SIG_CERT(sigtype) || sigtype == PGP_SIG_BINDSUBKEY || sigtype == PGP_SIG_CERTREVOKE) */
621     } /* if (sigver == 4) */
622     else if (sigver == 2 || sigver == 3) {
623     buf_getc(p1); /* One-octet length of following hashed material. MUST be 5 */
624     sigtype = buf_getc(p1);
625     } /* if (sigver == 2 || sigver == 3) */
626     if (sigtype == PGP_SIG_KEYREVOKE) {
627     /* revocation can be either v3 or v4. if v4 we could check issuer, but we don't do it... */
628     if (mode == PK_SIGN || mode == PK_ENCRYPT) { /* allow verify and decrypt with revokeded keys, but not sign and encrypt */
629     keytype = -1;
630     }
631     } /* if (sigtype == PGP_SIG_KEYREVOKE) */
632     else if (sigtype == PGP_SIG_SUBKEYREVOKE) {
633     if (!subkeyok || subkeyok == subkeyno)
634     if (mode == PK_ENCRYPT) { /* allow decrypt with revokeded subkeys, but not encrypt */
635     keytype = -1;
636     }
637     } /* if (sigtype == PGP_SIG_SUBKEYREVOKE) */
638 rabbi 221 break; /* switch (type) */
639 disastry 254 } /* case PGP_SIG: */
640 rabbi 1 case PGP_USERID:
641 disastry 254 uidno++;
642     uidd_c = new_uidd_c(uidd_c, uidno);
643     if (!uidd_1)
644     uidd_1 = uidd_c;
645     if (uidd_c && uidd_c->uid == uidno) {
646     uidd_c->uidstr = buf_new();
647     buf_set(uidd_c->uidstr, p1);
648     }
649 rabbi 1 if (userid)
650     buf_move(userid, p1);
651     break;
652     case PGP_PUBSUBKEY:
653     case PGP_SECSUBKEY:
654 disastry 254 subkeyno++;
655     if (keytype != -1 && subkeyno > 1) {
656     /* usable subkey already found, don't bother to check other */
657     continue;
658     }
659 rabbi 1 if (keytype != -1 && (mode == PK_SIGN || mode == PK_VERIFY))
660     continue;
661     case PGP_PUBKEY:
662     if ((type == PGP_PUBKEY || type == PGP_PUBSUBKEY) &&
663     (mode == PK_DECRYPT || mode == PK_SIGN))
664     continue;
665 disastry 254 case PGP_SECKEY:
666     if (type == PGP_PUBKEY || type == PGP_SECKEY)
667     pgp_keyid(p1, mainkeyid);
668 rabbi 1 keytype = type;
669     version = buf_getc(p1);
670     switch (version) {
671     case 2:
672     case 3:
673 disastry 254 created = buf_getl(p1); /* created */
674     expires = buf_geti(p1) * (24*60*60); /* valid */
675     if (uidno == 0) {
676     uidd_c = new_uidd_c(uidd_c, uidno);
677     if (!uidd_1)
678     uidd_1 = uidd_c;
679     if (uidd_c && uidd_c->uid == uidno) {
680     uidd_c->created = created;
681     uidd_c->expires = expires;
682     uidd_c->sym = PGP_K_IDEA;
683     }
684     }
685 rabbi 1 thisalgo = buf_getc(p1);
686     if (thisalgo != PGP_ES_RSA) {
687     keytype = -1;
688     goto end;
689     }
690     symfound = PGP_K_IDEA;
691 disastry 254 mdcfound = 0;
692 rabbi 1 break;
693     case 4:
694     buf_appendc(key, version);
695     buf_appendl(key, buf_getl(p1));
696     thisalgo = buf_getc(p1);
697     buf_appendc(key, thisalgo);
698     if (symfound == 0)
699     symfound = PGP_K_3DES; /* default algorithm */
700     break;
701     default:
702     keytype = -1;
703     goto end;
704 disastry 254 } /* switch (version) */
705 rabbi 1 if (algo != PGP_ANY && thisalgo != algo) {
706     keytype = -1;
707     continue;
708     }
709     if (keyid && keyid->length && !pgp_iskeyid(p1, keyid))
710     continue;
711 ulfm 51 pgp_keyid(p1, thiskeyid);
712 rabbi 1 if (key) {
713     buf_clear(key);
714     for (j = 0; j < pgp_nummpi(thisalgo); j++) {
715     if (mpi_get(p1, i) == -1)
716     goto end;
717     mpi_put(key, i);
718     }
719     if (keytype == PGP_SECKEY || keytype == PGP_SECSUBKEY) {
720     csstart = key->length;
721     skalgo = getski(p1, pass, sk, iv);
722     switch (version) {
723     case 2:
724     case 3:
725 rabbi 98 ivlen = pgp_blocklen(skalgo);
726 rabbi 1 for (j = 0; j < pgp_numsecmpi(thisalgo); j++) {
727 rabbi 98 unsigned char lastb[16];
728 rabbi 1 if (mpi_get(p1, i) == -1) {
729     keytype = -1;
730     goto end;
731     }
732 rabbi 98 assert(ivlen <= 16);
733     memcpy(lastb, i->data+i->length-ivlen, ivlen);
734 rabbi 1 skcrypt(i, skalgo, sk, iv, DECRYPT);
735 rabbi 98 buf_clear(iv);
736     buf_append(iv, lastb, ivlen);
737 rabbi 1 mpi_put(key, i);
738 disastry 254 } /* for */
739     break; /* switch (version) */
740 rabbi 1 case 4:
741     buf_clear(i);
742     buf_rest(i, p1);
743     skcrypt(i, skalgo, sk, iv, DECRYPT);
744     buf_move(p1, i);
745     for (j = 0; j < pgp_numsecmpi(thisalgo); j++) {
746     if (mpi_get(p1, i) == -1) {
747     keytype = PGP_PASS;
748     goto end;
749     }
750     mpi_put(key, i);
751     }
752     break;
753 disastry 254 } /* switch (version) */
754 rabbi 1 if (pgp_csum(key, csstart) != buf_geti(p1)) {
755     keytype = PGP_PASS;
756     goto end;
757     }
758     }
759 disastry 254 } /* if (key) */
760     break; /* switch (type) */
761 rabbi 1 default:
762     /* ignore trust packets etc */
763     break;
764 rabbi 221 } /* switch (type) */
765     } /* while ((type = pgp_getpacket(keypacket, p1)) > 0) */
766 rabbi 1 end:
767 ulfm 51 if (keyid) buf_set(keyid, thiskeyid);
768 rabbi 1 if (tempbuf) {
769     buf_move(keypacket, key);
770     buf_free(key);
771     }
772     buf_free(p1);
773     buf_free(i);
774     buf_free(iv);
775     buf_free(sk);
776 ulfm 51 buf_free(thiskeyid);
777 disastry 254 buf_free(mainkeyid);
778 rabbi 1 #ifndef USE_RSA
779     if (thisalgo == PGP_ES_RSA)
780     keytype = -1;
781 rabbi 262 #endif /* not USE_RSA */
782 disastry 254
783     if (uidd_1) {
784     primary = 0;
785     created = expires = 0;
786     while (uidd_1) {
787     /* find newest uid which is not revoked or expired */
788     if (primary <= uidd_1->primary && created <= uidd_1->created && !uidd_1->revoked) {
789     created = uidd_1->created;
790     expires = uidd_1->expires;
791     primary = uidd_1->primary;
792     symfound = uidd_1->sym;
793     mdcfound = uidd_1->mdc;
794     if (userid && uidd_1->uidstr)
795     buf_set(userid, uidd_1->uidstr);
796     }
797     uidd_c = uidd_1;
798     uidd_1 = uidd_1->next;
799     if (uidd_c->uidstr)
800     buf_free(uidd_c->uidstr);
801     free(uidd_c);
802     }
803     if (expires && ((created + expires < now) || (created + expires < 0))) {
804     if (mode == PK_SIGN || mode == PK_ENCRYPT) { /* allow verify and decrypt with expired keys, but not sign and encrypt */
805     keytype = -1;
806     }
807     }
808     } /* if (uidd_1) */
809     expires = expires ? created + expires : 0;
810     if (subexpires > 0 && expires > 0 && subexpires < expires)
811     expires = subexpires;
812     if (pexpires)
813     *pexpires = expires;
814    
815     if (!subkeyok && keytype == PGP_E_ELG && (mode == PK_DECRYPT || mode == PK_ENCRYPT))
816     keytype = -1; /* no usable subkey found, one with valid binding */
817    
818     if (needsym != PGP_K_ANY && needsym != symfound)
819 rabbi 1 keytype = -1;
820 disastry 254 else if (psym && *psym == PGP_K_ANY)
821 rabbi 1 *psym = symfound;
822 rabbi 135 if (pmdc)
823     *pmdc = mdcfound;
824 rabbi 1
825     return (keytype <= 0 ? keytype : thisalgo);
826     }
827    
828     int pgp_makepkpacket(int type, BUFFER *p, BUFFER *outtxt, BUFFER *out,
829     BUFFER *key, BUFFER *pass, time_t *created)
830     {
831     BUFFER *i, *id;
832     char txt[LINELEN], algoid;
833     int version, algo, valid = 0, err = 0;
834     int len, j;
835     struct tm *tc;
836    
837     i = buf_new();
838     id = buf_new();
839    
840     version = buf_getc(p);
841     buf_clear(key);
842     switch (version) {
843     case 2:
844     case 3:
845     *created = buf_getl(p);
846     valid = buf_geti(p);
847     algo = buf_getc(p);
848     if (algo != PGP_ES_RSA)
849     return(-1);
850     break;
851     case 4:
852     *created = buf_getl(p);
853     algo = buf_getc(p);
854     break;
855     default:
856     return(-1);
857     }
858    
859     switch (version) {
860     case 2:
861     case 3:
862     buf_appendc(key, version);
863     buf_appendl(key, *created);
864     buf_appendi(key, valid);
865     buf_appendc(key, algo);
866     break;
867     case 4:
868     buf_appendc(key, version);
869     buf_appendl(key, *created);
870     buf_appendc(key, algo);
871     break;
872     }
873    
874     pgp_keyid(p, id);
875     len = mpi_get(p, i);
876     mpi_put(key, i);
877     for (j = 1; j < pgp_nummpi(algo); j++) {
878     if (mpi_get(p, i) == -1) {
879     err = -1;
880     goto end;
881     }
882     mpi_put(key, i);
883     }
884     pgp_packet(key, type);
885     buf_cat(out, key);
886    
887     if (outtxt != NULL) {
888     switch(algo) {
889     case PGP_ES_RSA:
890     algoid = 'R';
891     break;
892     case PGP_S_DSA:
893     algoid = 'D';
894     break;
895     case PGP_E_ELG:
896     algoid = 'g';
897     break;
898     default:
899     algoid = '?';
900     }
901 weaselp 259 buf_appendf(outtxt, "%s %5d%c/%02X%02X%02X%02X ",
902 weaselp 185 type == PGP_PUBSUBKEY ? "sub" :
903     type == PGP_PUBKEY ? "pub" :
904     type == PGP_SECKEY ? "sec" :
905     type == PGP_SECSUBKEY ? "ssb" :
906     "???", len, algoid,
907 rabbi 1 id->data[4], id->data[5], id->data[6], id->data[7]);
908     tc = localtime(created);
909 weaselp 259 strftime(txt, LINELEN, "%Y-%m-%d ", tc);
910 rabbi 1 buf_appends(outtxt, txt);
911     }
912     end:
913     buf_free(i);
914     buf_free(id);
915     return(err == 0 ? algo : err);
916     }
917    
918     int pgp_makepubkey(BUFFER *keypacket, BUFFER *outtxt, BUFFER *out,
919     BUFFER *pass, int keyalgo)
920     {
921     BUFFER *p, *pubkey, *seckey, *subkey, *sig, *tmp;
922     int err = -1, type, thisalgo;
923     time_t created;
924    
925     p = buf_new();
926     seckey = buf_new();
927     pubkey = buf_new();
928     subkey = buf_new();
929     sig = buf_new();
930     tmp = buf_new();
931    
932     buf_set(seckey, keypacket);
933     type = pgp_getpacket(keypacket, p);
934     if (type != PGP_SECKEY)
935     goto end;
936    
937     thisalgo = pgp_makepkpacket(PGP_PUBKEY, p, outtxt, tmp, pubkey, pass,
938     &created);
939     if (thisalgo == -1 || (keyalgo != 0 && keyalgo != thisalgo))
940     goto end;
941     buf_cat(out, tmp);
942    
943     while ((type = pgp_getpacket(keypacket, p)) > 0) {
944     if (type == PGP_SECSUBKEY) {
945     if (pgp_makepkpacket(PGP_PUBSUBKEY, p, outtxt, out, subkey, pass,
946     &created) == -1)
947     goto end;
948     if (pgp_sign(pubkey, subkey, sig, NULL, pass, PGP_SIG_BINDSUBKEY, 0,
949     created, 0, seckey, NULL) != -1)
950     buf_cat(out, sig);
951     if (outtxt)
952     buf_nl(outtxt);
953     } else if (type == PGP_USERID) {
954     if (outtxt != NULL) {
955     buf_cat(outtxt, p);
956     buf_nl(outtxt);
957     }
958     pgp_packet(p, PGP_USERID);
959     err = pgp_sign(pubkey, p, sig, NULL, pass, PGP_SIG_CERT, 1, created, 0,
960 disastry 254 seckey, NULL); /* maybe PGP_SIG_CERT3 ? */
961 rabbi 1 buf_cat(out, p);
962     if (err == 0)
963     buf_cat(out, sig);
964     } else if (type == PGP_PUBKEY || type == PGP_SECKEY)
965     break;
966     }
967     end:
968     buf_free(pubkey);
969     buf_free(seckey);
970     buf_free(subkey);
971     buf_free(sig);
972     buf_free(p);
973     buf_free(tmp);
974     return (err);
975     }
976    
977 weaselp 295 int pgp_makekeyheader(int type, BUFFER *keypacket, BUFFER *outtxt,
978 weaselp 185 BUFFER *pass, int keyalgo)
979     {
980     BUFFER *p, *pubkey, *seckey, *subkey, *sig, *tmp, *dummy;
981 weaselp 295 int thisalgo, err = -1;
982 weaselp 185 time_t created;
983    
984 weaselp 295 assert(type == PGP_SECKEY || type == PGP_PUBKEY);
985    
986 weaselp 185 p = buf_new();
987     seckey = buf_new();
988     pubkey = buf_new();
989     subkey = buf_new();
990     sig = buf_new();
991     tmp = buf_new();
992     dummy = buf_new();
993    
994     buf_set(seckey, keypacket);
995 weaselp 295 if (type != pgp_getpacket(keypacket, p))
996 weaselp 185 goto end;
997    
998 weaselp 295 thisalgo = pgp_makepkpacket(type, p, outtxt, tmp, pubkey, pass,
999 weaselp 185 &created);
1000     if (thisalgo == -1 || (keyalgo != 0 && keyalgo != thisalgo))
1001     goto end;
1002    
1003     while ((type = pgp_getpacket(keypacket, p)) > 0) {
1004 weaselp 295 if (type == PGP_SECSUBKEY || type == PGP_PUBSUBKEY) {
1005     if (pgp_makepkpacket(type, p, outtxt, dummy, subkey, pass,
1006 weaselp 185 &created) == -1)
1007     goto end;
1008     buf_nl(outtxt);
1009     } else if (type == PGP_USERID) {
1010     buf_cat(outtxt, p);
1011     buf_nl(outtxt);
1012     pgp_packet(p, PGP_USERID);
1013     } else if (type == PGP_PUBKEY || type == PGP_SECKEY)
1014     break;
1015     }
1016     err = 0;
1017     end:
1018     buf_free(pubkey);
1019     buf_free(seckey);
1020     buf_free(subkey);
1021     buf_free(sig);
1022     buf_free(p);
1023     buf_free(dummy);
1024     buf_free(tmp);
1025     return (err);
1026     }
1027    
1028 rabbi 1 #ifdef USE_RSA
1029     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 205 buf_appendi(skey, KEYLIFETIME/(24*60*60));
1061 rabbi 1 buf_appendc(skey, PGP_ES_RSA);
1062     mpi_bnput(skey, k->n);
1063     mpi_bnput(skey, k->e);
1064    
1065     #ifdef USE_IDEA
1066     if (pass != NULL && pass->length > 0 && remail != 2) {
1067     skalgo = PGP_K_IDEA;
1068     digest_md5(pass, dk);
1069 rabbi 98 buf_setrnd(iv, pgp_blocklen(skalgo));
1070 rabbi 1 buf_appendc(skey, skalgo);
1071     buf_cat(skey, iv);
1072     }
1073     else
1074 rabbi 262 #endif /* USE_IDEA */
1075 rabbi 1 buf_appendc(skey, 0);
1076    
1077     mpi_bnputenc(skey, k->d, skalgo, dk, iv);
1078     mpi_bnputenc(skey, k->q, skalgo, dk, iv);
1079     mpi_bnputenc(skey, k->p, skalgo, dk, iv);
1080     mpi_bnputenc(skey, k->iqmp, skalgo, dk, iv);
1081    
1082     buf_clear(p);
1083     mpi_bnput(p, k->d);
1084     mpi_bnput(p, k->q);
1085     mpi_bnput(p, k->p);
1086     mpi_bnput(p, k->iqmp);
1087     buf_appendi(skey, pgp_csum(p, 0));
1088    
1089     pgp_packet(skey, PGP_SECKEY);
1090     buf_set(p, userid);
1091     pgp_packet(p, PGP_USERID);
1092     buf_cat(skey, p);
1093    
1094     if (secring == NULL)
1095     secring = PGPREMSECRING;
1096 weaselp 285 keydb = pgpdb_open(secring, remail == 2 ? pass : NULL, 1, PGP_TYPE_PRIVATE);
1097 rabbi 1 if (keydb == NULL) {
1098     err = -1;
1099     goto end;
1100     }
1101     if (keydb->filetype == -1)
1102 weaselp 185 keydb->filetype = ARMORED;
1103 rabbi 1 pgpdb_append(keydb, skey);
1104 weaselp 284 pgpdb_close(keydb);
1105 rabbi 1
1106     if (pubring != NULL) {
1107     if (pgp_makepubkey(skey, NULL, pkey, pass, 0) == -1)
1108     goto end;
1109 weaselp 285 keydb = pgpdb_open(pubring, NULL, 1, PGP_TYPE_PUBLIC);
1110 rabbi 1 if (keydb == NULL)
1111     goto end;
1112     if (keydb->filetype == -1)
1113     keydb->filetype = ARMORED;
1114     pgpdb_append(keydb, pkey);
1115 weaselp 284 pgpdb_close(keydb);
1116 rabbi 1 }
1117     end:
1118 weaselp 86 RSA_free(k);
1119 rabbi 1 buf_free(pkey);
1120     buf_free(skey);
1121     buf_free(iv);
1122     buf_free(dk);
1123     buf_free(p);
1124     buf_free(sig);
1125     return (err);
1126     }
1127 rabbi 262 #endif /* USE_RSA */
1128 rabbi 1
1129     #define begin_param "-----BEGIN PUBLIC PARAMETER BLOCK-----"
1130     #define end_param "-----END PUBLIC PARAMETER BLOCK-----"
1131    
1132     static void *params(int dsa, int bits)
1133     {
1134     DSA *k = NULL;
1135     DH *d = NULL;
1136     FILE *f;
1137     BUFFER *p, *n;
1138     char line[LINELEN];
1139     byte b[1024];
1140     int m, l;
1141    
1142     if (bits == 0)
1143     bits = 1024;
1144     if (dsa && bits > 1024)
1145     bits = 1024;
1146    
1147     p = buf_new();
1148     n = buf_new();
1149     f = mix_openfile(dsa ? DSAPARAMS : DHPARAMS, "r");
1150     if (f != NULL) {
1151     for (;;) {
1152     if (fgets(line, sizeof(line), f) == NULL)
1153     break;
1154     if (strleft(line, begin_param)) {
1155     if (fgets(line, sizeof(line), f) == NULL)
1156     break;
1157     m = 0;
1158     sscanf(line, "%d", &m);
1159     if (bits == m) {
1160     buf_clear(p);
1161     while (fgets(line, sizeof(line), f) != NULL) {
1162     if (strleft(line, end_param)) {
1163     decode(p, p);
1164     if (dsa) {
1165     k = DSA_new();
1166     l = buf_geti(p);
1167     buf_get(p, n, l);
1168     k->p = BN_bin2bn(n->data, n->length, NULL);
1169     l = buf_geti(p);
1170     buf_get(p, n, l);
1171     k->q = BN_bin2bn(n->data, n->length, NULL);
1172     l = buf_geti(p);
1173     buf_get(p, n, l);
1174     k->g = BN_bin2bn(n->data, n->length, NULL);
1175     } else {
1176     d = DH_new();
1177     l = buf_geti(p);
1178     buf_get(p, n, l);
1179     d->p = BN_bin2bn(n->data, n->length, NULL);
1180     l = buf_geti(p);
1181     buf_get(p, n, l);
1182     d->g = BN_bin2bn(n->data, n->length, NULL);
1183     }
1184     break;
1185     }
1186     buf_appends(p, line);
1187     }
1188     }
1189     }
1190     }
1191     fclose(f);
1192     }
1193    
1194     buf_free(p);
1195     buf_free(n);
1196    
1197     if (dsa) {
1198     if (k == NULL) {
1199     errlog(NOTICE, "Generating DSA parameters.\n");
1200     k = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
1201     p = buf_new();
1202     l = BN_bn2bin(k->p, b);
1203     buf_appendi(p, l);
1204     buf_append(p, b, l);
1205     l = BN_bn2bin(k->q, b);
1206     buf_appendi(p, l);
1207     buf_append(p, b, l);
1208     l = BN_bn2bin(k->g, b);
1209     buf_appendi(p, l);
1210     buf_append(p, b, l);
1211     encode(p, 64);
1212     f = mix_openfile(DSAPARAMS, "a");
1213     fprintf(f, "%s\n%d\n", begin_param, bits);
1214     buf_write(p, f);
1215     fprintf(f, "%s\n", end_param);
1216     fclose(f);
1217     buf_free(p);
1218     }
1219     return (k);
1220     } else {
1221     if (d == NULL) {
1222     errlog(NOTICE, "Generating DH parameters. (This may take a long time!)\n");
1223     d = DH_generate_parameters(bits, DH_GENERATOR_5, NULL, NULL);
1224     p = buf_new();
1225     l = BN_bn2bin(d->p, b);
1226     buf_appendi(p, l);
1227     buf_append(p, b, l);
1228     l = BN_bn2bin(d->g, b);
1229     buf_appendi(p, l);
1230     buf_append(p, b, l);
1231     encode(p, 64);
1232     f = mix_openfile(DHPARAMS, "a");
1233     fprintf(f, "%s\n%d\n", begin_param, bits);
1234     buf_write(p, f);
1235     fprintf(f, "%s\n", end_param);
1236     fclose(f);
1237     buf_free(p);
1238     }
1239     return (d);
1240     }
1241     }
1242    
1243     int pgp_dhkeygen(int bits, BUFFER *userid, BUFFER *pass, char *pubring,
1244     char *secring, int remail)
1245     /* remail==2: encrypt the secring */
1246     {
1247     DSA *s;
1248     DH *e;
1249     KEYRING *keydb;
1250     BUFFER *pkey, *skey, *subkey, *secret;
1251     BUFFER *dk, *sig, *iv, *p;
1252     long now;
1253     int err = 0;
1254    
1255     pkey = buf_new();
1256     skey = buf_new();
1257     subkey = buf_new();
1258     iv = buf_new();
1259     dk = buf_new();
1260     p = buf_new();
1261     sig = buf_new();
1262     secret = buf_new();
1263    
1264     s = params(1, bits);
1265     errlog(NOTICE, "Generating OpenPGP DSA key.\n");
1266     if (s == NULL || DSA_generate_key(s) != 1) {
1267     err = -1;
1268     goto end;
1269     }
1270     e = params(0, bits);
1271     errlog(NOTICE, "Generating OpenPGP ElGamal key.\n");
1272     if (e == NULL || DH_generate_key(e) != 1) {
1273     err = -1;
1274     goto end;
1275     }
1276    
1277     now = time(NULL);
1278     if (remail) /* fake time in nym keys */
1279     now -= rnd_number(4 * 24 * 60 * 60);
1280    
1281     /* DSA key */
1282     buf_setc(skey, 4);
1283     buf_appendl(skey, now);
1284     buf_appendc(skey, PGP_S_DSA);
1285     mpi_bnput(skey, s->p);
1286     mpi_bnput(skey, s->q);
1287     mpi_bnput(skey, s->g);
1288     mpi_bnput(skey, s->pub_key);
1289    
1290     mpi_bnput(secret, s->priv_key);
1291     buf_appendi(secret, pgp_csum(secret, 0));
1292     makeski(secret, pass, remail);
1293     buf_cat(skey, secret);
1294     pgp_packet(skey, PGP_SECKEY);
1295    
1296     /* ElGamal key */
1297     buf_setc(subkey, 4);
1298     buf_appendl(subkey, now);
1299     buf_appendc(subkey, PGP_E_ELG);
1300     mpi_bnput(subkey, e->p);
1301     mpi_bnput(subkey, e->g);
1302     mpi_bnput(subkey, e->pub_key);
1303    
1304     buf_clear(secret);
1305     mpi_bnput(secret, e->priv_key);
1306     buf_appendi(secret, pgp_csum(secret, 0));
1307     makeski(secret, pass, remail);
1308     buf_cat(subkey, secret);
1309    
1310     buf_set(p, userid);
1311     pgp_packet(p, PGP_USERID);
1312     buf_cat(skey, p);
1313    
1314     pgp_packet(subkey, PGP_SECSUBKEY);
1315     buf_cat(skey, subkey);
1316    
1317     if (secring == NULL)
1318     secring = PGPREMSECRING;
1319 weaselp 285 keydb = pgpdb_open(secring, remail == 2 ? pass : NULL, 1, PGP_TYPE_PRIVATE);
1320 rabbi 1 if (keydb == NULL) {
1321     err = -1;
1322     goto end;
1323     }
1324     if (keydb->filetype == -1)
1325 weaselp 185 keydb->filetype = ARMORED;
1326 rabbi 1 pgpdb_append(keydb, skey);
1327 weaselp 284 pgpdb_close(keydb);
1328 rabbi 1
1329     if (pubring != NULL) {
1330     pgp_makepubkey(skey, NULL, pkey, pass, 0);
1331 weaselp 285 keydb = pgpdb_open(pubring, NULL, 1, PGP_TYPE_PUBLIC);
1332 rabbi 1 if (keydb == NULL)
1333     goto end;
1334     if (keydb->filetype == -1)
1335     keydb->filetype = ARMORED;
1336     pgpdb_append(keydb, pkey);
1337 weaselp 284 pgpdb_close(keydb);
1338 rabbi 1 }
1339     end:
1340     buf_free(pkey);
1341     buf_free(skey);
1342     buf_free(subkey);
1343     buf_free(iv);
1344     buf_free(dk);
1345     buf_free(p);
1346     buf_free(sig);
1347     buf_free(secret);
1348     return (err);
1349     }
1350    
1351     int pgp_dsasign(BUFFER *data, BUFFER *key, BUFFER *out)
1352     {
1353     BUFFER *mpi, *b;
1354     DSA *d;
1355     DSA_SIG *sig = NULL;
1356    
1357     d = DSA_new();
1358     b = buf_new();
1359     mpi = buf_new();
1360     mpi_get(key, mpi);
1361     d->p = BN_bin2bn(mpi->data, mpi->length, NULL);
1362     mpi_get(key, mpi);
1363     d->q = BN_bin2bn(mpi->data, mpi->length, NULL);
1364     mpi_get(key, mpi);
1365     d->g = BN_bin2bn(mpi->data, mpi->length, NULL);
1366     mpi_get(key, mpi);
1367     d->pub_key = BN_bin2bn(mpi->data, mpi->length, NULL);
1368     if (mpi_get(key, mpi) == -1) {
1369     goto end;
1370     }
1371     d->priv_key = BN_bin2bn(mpi->data, mpi->length, NULL);
1372    
1373     sig = DSA_do_sign(data->data, data->length, d);
1374     if (sig) {
1375     buf_prepare(b, BN_num_bytes(sig->r));
1376     b->length = BN_bn2bin(sig->r, b->data);
1377     mpi_put(out, b);
1378     b->length = BN_bn2bin(sig->s, b->data);
1379     mpi_put(out, b);
1380     }
1381     end:
1382     buf_free(mpi);
1383     buf_free(b);
1384     DSA_SIG_free(sig);
1385     DSA_free(d);
1386     return(sig ? 0 : -1);
1387     }
1388    
1389     int pgp_dosign(int algo, BUFFER *data, BUFFER *key)
1390     {
1391     int err;
1392     BUFFER *out, *r, *s;
1393    
1394     out = buf_new();
1395     r = buf_new();
1396     s = buf_new();
1397     switch (algo) {
1398     #ifdef USE_RSA
1399     case PGP_ES_RSA:
1400     err = pgp_rsa(data, key, PK_SIGN);
1401     if (err == 0)
1402     mpi_put(out, data);
1403     break;
1404 rabbi 262 #endif /* USE_RSA */
1405 rabbi 1 case PGP_S_DSA:
1406     err = pgp_dsasign(data, key, out);
1407     break;
1408     default:
1409     errlog(NOTICE, "Unknown encryption algorithm!\n");
1410     return (-1);
1411     }
1412     if (err == -1)
1413     errlog(ERRORMSG, "Signing operation failed!\n");
1414    
1415     buf_move(data, out);
1416     buf_free(out);
1417     buf_free(r);
1418     buf_free(s);
1419     return (err);
1420     }
1421    
1422     int pgp_elgdecrypt(BUFFER *in, BUFFER *key)
1423     {
1424 weaselp 120 BIGNUM *a = NULL, *b = NULL, *c = NULL,
1425     *p = NULL, *g = NULL, *x = NULL;
1426 rabbi 1 BN_CTX *ctx;
1427     BUFFER *i;
1428     int err = -1;
1429    
1430     i = buf_new();
1431     ctx = BN_CTX_new();
1432     if (ctx == NULL) goto end;
1433     mpi_get(key, i);
1434     p = BN_bin2bn(i->data, i->length, NULL);
1435     mpi_get(key, i);
1436     g = BN_bin2bn(i->data, i->length, NULL);
1437     mpi_get(key, i); /* y */
1438     mpi_get(key, i);
1439     x = BN_bin2bn(i->data, i->length, NULL);
1440     mpi_get(in, i);
1441     a = BN_bin2bn(i->data, i->length, NULL);
1442     if (mpi_get(in, i) == -1)
1443     goto e1;
1444     b = BN_bin2bn(i->data, i->length, NULL);
1445     c = BN_new();
1446    
1447     if (BN_mod_exp(c, a, x, p, ctx) == 0) goto end;
1448     if (BN_mod_inverse(a, c, p, ctx) == 0) goto end;
1449     if (BN_mod_mul(c, a, b, p, ctx) == 0) goto end;
1450    
1451     buf_prepare(i, BN_num_bytes(c));
1452     i->length = BN_bn2bin(c, i->data);
1453    
1454     buf_prepare(in, BN_num_bytes(c));
1455     in->length = RSA_padding_check_PKCS1_type_2(in->data, in->length, i->data,
1456     i->length, i->length + 1);
1457     if (in->length <= 0)
1458     in->length = 0;
1459     else
1460     err = 0;
1461    
1462     end:
1463     BN_free(b);
1464     BN_free(c);
1465     e1:
1466     buf_free(i);
1467     BN_free(a);
1468     BN_free(p);
1469     BN_free(g);
1470     BN_clear_free(x);
1471     BN_CTX_free(ctx);
1472    
1473     return (err);
1474     }
1475    
1476     int pgp_elgencrypt(BUFFER *in, BUFFER *key)
1477     {
1478 weaselp 120 BIGNUM *m, *k, *a, *b, *c, *p, *g, *y = NULL;
1479 rabbi 1 BN_CTX *ctx;
1480     BUFFER *i;
1481     int err = -1;
1482    
1483     i = buf_new();
1484     ctx = BN_CTX_new();
1485     if (ctx == NULL) goto end;
1486     mpi_get(key, i);
1487     p = BN_bin2bn(i->data, i->length, NULL);
1488     mpi_get(key, i);
1489     g = BN_bin2bn(i->data, i->length, NULL);
1490     if (mpi_get(key, i) == -1)
1491     goto e1;
1492     y = BN_bin2bn(i->data, i->length, NULL);
1493    
1494     buf_prepare(i, BN_num_bytes(p));
1495     if (RSA_padding_add_PKCS1_type_2(i->data, i->length, in->data, in->length)
1496     != 1)
1497     goto end;
1498     m = BN_bin2bn(i->data, i->length, NULL);
1499    
1500     k = BN_new();
1501     BN_rand(k, BN_num_bits(p), 0, 0);
1502    
1503     a = BN_new();
1504     b = BN_new();
1505     c = BN_new();
1506    
1507     if (BN_mod_exp(a, g, k, p, ctx) == 0) goto end;
1508     if (BN_mod_exp(c, y, k, p, ctx) == 0) goto end;
1509     if (BN_mod_mul(b, m, c, p, ctx) == 0) goto end;
1510    
1511     buf_clear(in);
1512     i->length = BN_bn2bin(a, i->data);
1513     mpi_put(in, i);
1514     i->length = BN_bn2bin(b, i->data);
1515     mpi_put(in, i);
1516    
1517     err = 0;
1518    
1519     BN_free(a);
1520     BN_free(b);
1521     BN_free(c);
1522     BN_free(m);
1523     e1:
1524     buf_free(i);
1525     BN_free(p);
1526     BN_free(g);
1527     BN_free(y);
1528     BN_CTX_free(ctx);
1529     end:
1530    
1531     return (err);
1532     }
1533    
1534     #endif /* USE_PGP */

  ViewVC Help
Powered by ViewVC 1.1.5