/[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 262 - (hide annotations) (download)
Wed Sep 18 23:26:17 2002 UTC (10 years, 8 months ago) by rabbi
File MIME type: text/plain
File size: 36537 byte(s)
Added closing comments for all #ifdef statements. All #endif's, as well as
nested braces, should be commented to reference their start.

We need to provide comments before every function as well.
1 rabbi 1 /* Mixmaster version 3 -- (C) 1999 Anonymizer Inc.
2    
3     Mixmaster may be redistributed and modified under certain conditions.
4     This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
5     ANY KIND, either express or implied. See the file COPYRIGHT for
6     details.
7    
8     OpenPGP data
9 rabbi 262 $Id: pgpdata.c,v 1.20 2002/09/18 23:26:16 rabbi Exp $ */
10 rabbi 1
11    
12     #include "mix3.h"
13     #ifdef USE_PGP
14     #include "pgp.h"
15     #include "crypto.h"
16     #include <assert.h>
17     #include <time.h>
18 weaselp 120 #include <string.h>
19 rabbi 1
20     int pgp_keylen(int symalgo)
21     {
22     switch (symalgo) {
23 rabbi 98 #ifdef USE_AES
24     case PGP_K_AES256:
25     return (32);
26     case PGP_K_AES192:
27     return (24);
28     case PGP_K_AES128:
29 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 185 int pgp_makeseckey(BUFFER *keypacket, BUFFER *outtxt,
978     BUFFER *pass, int keyalgo)
979     {
980     BUFFER *p, *pubkey, *seckey, *subkey, *sig, *tmp, *dummy;
981     int type, thisalgo, err = -1;
982     time_t created;
983    
984     p = buf_new();
985     seckey = buf_new();
986     pubkey = buf_new();
987     subkey = buf_new();
988     sig = buf_new();
989     tmp = buf_new();
990     dummy = buf_new();
991    
992     buf_set(seckey, keypacket);
993     type = pgp_getpacket(keypacket, p);
994     if (type != PGP_SECKEY)
995     goto end;
996    
997     thisalgo = pgp_makepkpacket(PGP_SECKEY, p, outtxt, tmp, pubkey, pass,
998     &created);
999     if (thisalgo == -1 || (keyalgo != 0 && keyalgo != thisalgo))
1000     goto end;
1001    
1002     while ((type = pgp_getpacket(keypacket, p)) > 0) {
1003     if (type == PGP_SECSUBKEY) {
1004     if (pgp_makepkpacket(PGP_SECSUBKEY, p, outtxt, dummy, subkey, pass,
1005     &created) == -1)
1006     goto end;
1007     buf_nl(outtxt);
1008     } else if (type == PGP_USERID) {
1009     buf_cat(outtxt, p);
1010     buf_nl(outtxt);
1011     pgp_packet(p, PGP_USERID);
1012     } else if (type == PGP_PUBKEY || type == PGP_SECKEY)
1013     break;
1014     }
1015     err = 0;
1016     end:
1017     buf_free(pubkey);
1018     buf_free(seckey);
1019     buf_free(subkey);
1020     buf_free(sig);
1021     buf_free(p);
1022     buf_free(dummy);
1023     buf_free(tmp);
1024     return (err);
1025     }
1026    
1027 rabbi 1 #ifdef USE_RSA
1028     int pgp_rsakeygen(int bits, BUFFER *userid, BUFFER *pass, char *pubring,
1029     char *secring, int remail)
1030     /* remail==2: encrypt the secring */
1031     {
1032     RSA *k;
1033     KEYRING *keydb;
1034     BUFFER *pkey, *skey;
1035     BUFFER *dk, *sig, *iv, *p;
1036     long now;
1037     int skalgo = 0;
1038     int err = 0;
1039    
1040     pkey = buf_new();
1041     skey = buf_new();
1042     iv = buf_new();
1043     dk = buf_new();
1044     p = buf_new();
1045     sig = buf_new();
1046    
1047     errlog(NOTICE, "Generating OpenPGP RSA key.\n");
1048 disastry 212 k = RSA_generate_key(bits == 0 ? 1024 : bits, 17, NULL, NULL);
1049 rabbi 1 if (k == NULL) {
1050     err = -1;
1051     goto end;
1052     }
1053     now = time(NULL);
1054     if (remail) /* fake time in nym keys */
1055     now -= rnd_number(4 * 24 * 60 * 60);
1056    
1057     buf_appendc(skey, 3);
1058     buf_appendl(skey, now);
1059 weaselp 205 buf_appendi(skey, KEYLIFETIME/(24*60*60));
1060 rabbi 1 buf_appendc(skey, PGP_ES_RSA);
1061     mpi_bnput(skey, k->n);
1062     mpi_bnput(skey, k->e);
1063    
1064     #ifdef USE_IDEA
1065     if (pass != NULL && pass->length > 0 && remail != 2) {
1066     skalgo = PGP_K_IDEA;
1067     digest_md5(pass, dk);
1068 rabbi 98 buf_setrnd(iv, pgp_blocklen(skalgo));
1069 rabbi 1 buf_appendc(skey, skalgo);
1070     buf_cat(skey, iv);
1071     }
1072     else
1073 rabbi 262 #endif /* USE_IDEA */
1074 rabbi 1 buf_appendc(skey, 0);
1075    
1076     mpi_bnputenc(skey, k->d, skalgo, dk, iv);
1077     mpi_bnputenc(skey, k->q, skalgo, dk, iv);
1078     mpi_bnputenc(skey, k->p, skalgo, dk, iv);
1079     mpi_bnputenc(skey, k->iqmp, skalgo, dk, iv);
1080    
1081     buf_clear(p);
1082     mpi_bnput(p, k->d);
1083     mpi_bnput(p, k->q);
1084     mpi_bnput(p, k->p);
1085     mpi_bnput(p, k->iqmp);
1086     buf_appendi(skey, pgp_csum(p, 0));
1087    
1088     pgp_packet(skey, PGP_SECKEY);
1089     buf_set(p, userid);
1090     pgp_packet(p, PGP_USERID);
1091     buf_cat(skey, p);
1092    
1093     if (secring == NULL)
1094     secring = PGPREMSECRING;
1095     keydb = pgpdb_open(secring, remail == 2 ? pass : NULL, 1);
1096     if (keydb == NULL) {
1097     err = -1;
1098     goto end;
1099     }
1100     if (keydb->filetype == -1)
1101 weaselp 185 keydb->filetype = ARMORED;
1102 rabbi 1 pgpdb_append(keydb, skey);
1103     pgpdb_close(keydb);
1104    
1105     if (pubring != NULL) {
1106     if (pgp_makepubkey(skey, NULL, pkey, pass, 0) == -1)
1107     goto end;
1108     keydb = pgpdb_open(pubring, NULL, 1);
1109     if (keydb == NULL)
1110     goto end;
1111     if (keydb->filetype == -1)
1112     keydb->filetype = ARMORED;
1113     pgpdb_append(keydb, pkey);
1114     pgpdb_close(keydb);
1115     }
1116     end:
1117 weaselp 86 RSA_free(k);
1118 rabbi 1 buf_free(pkey);
1119     buf_free(skey);
1120     buf_free(iv);
1121     buf_free(dk);
1122     buf_free(p);
1123     buf_free(sig);
1124     return (err);
1125     }
1126 rabbi 262 #endif /* USE_RSA */
1127 rabbi 1
1128     #define begin_param "-----BEGIN PUBLIC PARAMETER BLOCK-----"
1129     #define end_param "-----END PUBLIC PARAMETER BLOCK-----"
1130    
1131     static void *params(int dsa, int bits)
1132     {
1133     DSA *k = NULL;
1134     DH *d = NULL;
1135     FILE *f;
1136     BUFFER *p, *n;
1137     char line[LINELEN];
1138     byte b[1024];
1139     int m, l;
1140    
1141     if (bits == 0)
1142     bits = 1024;
1143     if (dsa && bits > 1024)
1144     bits = 1024;
1145    
1146     p = buf_new();
1147     n = buf_new();
1148     f = mix_openfile(dsa ? DSAPARAMS : DHPARAMS, "r");
1149     if (f != NULL) {
1150     for (;;) {
1151     if (fgets(line, sizeof(line), f) == NULL)
1152     break;
1153     if (strleft(line, begin_param)) {
1154     if (fgets(line, sizeof(line), f) == NULL)
1155     break;
1156     m = 0;
1157     sscanf(line, "%d", &m);
1158     if (bits == m) {
1159     buf_clear(p);
1160     while (fgets(line, sizeof(line), f) != NULL) {
1161     if (strleft(line, end_param)) {
1162     decode(p, p);
1163     if (dsa) {
1164     k = DSA_new();
1165     l = buf_geti(p);
1166     buf_get(p, n, l);
1167     k->p = BN_bin2bn(n->data, n->length, NULL);
1168     l = buf_geti(p);
1169     buf_get(p, n, l);
1170     k->q = BN_bin2bn(n->data, n->length, NULL);
1171     l = buf_geti(p);
1172     buf_get(p, n, l);
1173     k->g = BN_bin2bn(n->data, n->length, NULL);
1174     } else {
1175     d = DH_new();
1176     l = buf_geti(p);
1177     buf_get(p, n, l);
1178     d->p = BN_bin2bn(n->data, n->length, NULL);
1179     l = buf_geti(p);
1180     buf_get(p, n, l);
1181     d->g = BN_bin2bn(n->data, n->length, NULL);
1182     }
1183     break;
1184     }
1185     buf_appends(p, line);
1186     }
1187     }
1188     }
1189     }
1190     fclose(f);
1191     }
1192    
1193     buf_free(p);
1194     buf_free(n);
1195    
1196     if (dsa) {
1197     if (k == NULL) {
1198     errlog(NOTICE, "Generating DSA parameters.\n");
1199     k = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
1200     p = buf_new();
1201     l = BN_bn2bin(k->p, b);
1202     buf_appendi(p, l);
1203     buf_append(p, b, l);
1204     l = BN_bn2bin(k->q, b);
1205     buf_appendi(p, l);
1206     buf_append(p, b, l);
1207     l = BN_bn2bin(k->g, b);
1208     buf_appendi(p, l);
1209     buf_append(p, b, l);
1210     encode(p, 64);
1211     f = mix_openfile(DSAPARAMS, "a");
1212     fprintf(f, "%s\n%d\n", begin_param, bits);
1213     buf_write(p, f);
1214     fprintf(f, "%s\n", end_param);
1215     fclose(f);
1216     buf_free(p);
1217     }
1218     return (k);
1219     } else {
1220     if (d == NULL) {
1221     errlog(NOTICE, "Generating DH parameters. (This may take a long time!)\n");
1222     d = DH_generate_parameters(bits, DH_GENERATOR_5, NULL, NULL);
1223     p = buf_new();
1224     l = BN_bn2bin(d->p, b);
1225     buf_appendi(p, l);
1226     buf_append(p, b, l);
1227     l = BN_bn2bin(d->g, b);
1228     buf_appendi(p, l);
1229     buf_append(p, b, l);
1230     encode(p, 64);
1231     f = mix_openfile(DHPARAMS, "a");
1232     fprintf(f, "%s\n%d\n", begin_param, bits);
1233     buf_write(p, f);
1234     fprintf(f, "%s\n", end_param);
1235     fclose(f);
1236     buf_free(p);
1237     }
1238     return (d);
1239     }
1240     }
1241    
1242     int pgp_dhkeygen(int bits, BUFFER *userid, BUFFER *pass, char *pubring,
1243     char *secring, int remail)
1244     /* remail==2: encrypt the secring */
1245     {
1246     DSA *s;
1247     DH *e;
1248     KEYRING *keydb;
1249     BUFFER *pkey, *skey, *subkey, *secret;
1250     BUFFER *dk, *sig, *iv, *p;
1251     long now;
1252     int err = 0;
1253    
1254     pkey = buf_new();
1255     skey = buf_new();
1256     subkey = buf_new();
1257     iv = buf_new();
1258     dk = buf_new();
1259     p = buf_new();
1260     sig = buf_new();
1261     secret = buf_new();
1262    
1263     s = params(1, bits);
1264     errlog(NOTICE, "Generating OpenPGP DSA key.\n");
1265     if (s == NULL || DSA_generate_key(s) != 1) {
1266     err = -1;
1267     goto end;
1268     }
1269     e = params(0, bits);
1270     errlog(NOTICE, "Generating OpenPGP ElGamal key.\n");
1271     if (e == NULL || DH_generate_key(e) != 1) {
1272     err = -1;
1273     goto end;
1274     }
1275    
1276     now = time(NULL);
1277     if (remail) /* fake time in nym keys */
1278     now -= rnd_number(4 * 24 * 60 * 60);
1279    
1280     /* DSA key */
1281     buf_setc(skey, 4);
1282     buf_appendl(skey, now);
1283     buf_appendc(skey, PGP_S_DSA);
1284     mpi_bnput(skey, s->p);
1285     mpi_bnput(skey, s->q);
1286     mpi_bnput(skey, s->g);
1287     mpi_bnput(skey, s->pub_key);
1288    
1289     mpi_bnput(secret, s->priv_key);
1290     buf_appendi(secret, pgp_csum(secret, 0));
1291     makeski(secret, pass, remail);
1292     buf_cat(skey, secret);
1293     pgp_packet(skey, PGP_SECKEY);
1294    
1295     /* ElGamal key */
1296     buf_setc(subkey, 4);
1297     buf_appendl(subkey, now);
1298     buf_appendc(subkey, PGP_E_ELG);
1299     mpi_bnput(subkey, e->p);
1300     mpi_bnput(subkey, e->g);
1301     mpi_bnput(subkey, e->pub_key);
1302    
1303     buf_clear(secret);
1304     mpi_bnput(secret, e->priv_key);
1305     buf_appendi(secret, pgp_csum(secret, 0));
1306     makeski(secret, pass, remail);
1307     buf_cat(subkey, secret);
1308    
1309     buf_set(p, userid);
1310     pgp_packet(p, PGP_USERID);
1311     buf_cat(skey, p);
1312    
1313     pgp_packet(subkey, PGP_SECSUBKEY);
1314     buf_cat(skey, subkey);
1315    
1316     if (secring == NULL)
1317     secring = PGPREMSECRING;
1318     keydb = pgpdb_open(secring, remail == 2 ? pass : NULL, 1);
1319     if (keydb == NULL) {
1320     err = -1;
1321     goto end;
1322     }
1323     if (keydb->filetype == -1)
1324 weaselp 185 keydb->filetype = ARMORED;
1325 rabbi 1 pgpdb_append(keydb, skey);
1326     pgpdb_close(keydb);
1327    
1328     if (pubring != NULL) {
1329     pgp_makepubkey(skey, NULL, pkey, pass, 0);
1330     keydb = pgpdb_open(pubring, NULL, 1);
1331     if (keydb == NULL)
1332     goto end;
1333     if (keydb->filetype == -1)
1334     keydb->filetype = ARMORED;
1335     pgpdb_append(keydb, pkey);
1336     pgpdb_close(keydb);
1337     }
1338     end:
1339     buf_free(pkey);
1340     buf_free(skey);
1341     buf_free(subkey);
1342     buf_free(iv);
1343     buf_free(dk);
1344     buf_free(p);
1345     buf_free(sig);
1346     buf_free(secret);
1347     return (err);
1348     }
1349    
1350     int pgp_dsasign(BUFFER *data, BUFFER *key, BUFFER *out)
1351     {
1352     BUFFER *mpi, *b;
1353     DSA *d;
1354     DSA_SIG *sig = NULL;
1355    
1356     d = DSA_new();
1357     b = buf_new();
1358     mpi = buf_new();
1359     mpi_get(key, mpi);
1360     d->p = BN_bin2bn(mpi->data, mpi->length, NULL);
1361     mpi_get(key, mpi);
1362     d->q = BN_bin2bn(mpi->data, mpi->length, NULL);
1363     mpi_get(key, mpi);
1364     d->g = BN_bin2bn(mpi->data, mpi->length, NULL);
1365     mpi_get(key, mpi);
1366     d->pub_key = BN_bin2bn(mpi->data, mpi->length, NULL);
1367     if (mpi_get(key, mpi) == -1) {
1368     goto end;
1369     }
1370     d->priv_key = BN_bin2bn(mpi->data, mpi->length, NULL);
1371    
1372     sig = DSA_do_sign(data->data, data->length, d);
1373     if (sig) {
1374     buf_prepare(b, BN_num_bytes(sig->r));
1375     b->length = BN_bn2bin(sig->r, b->data);
1376     mpi_put(out, b);
1377     b->length = BN_bn2bin(sig->s, b->data);
1378     mpi_put(out, b);
1379     }
1380     end:
1381     buf_free(mpi);
1382     buf_free(b);
1383     DSA_SIG_free(sig);
1384     DSA_free(d);
1385     return(sig ? 0 : -1);
1386     }
1387    
1388     int pgp_dosign(int algo, BUFFER *data, BUFFER *key)
1389     {
1390     int err;
1391     BUFFER *out, *r, *s;
1392    
1393     out = buf_new();
1394     r = buf_new();
1395     s = buf_new();
1396     switch (algo) {
1397     #ifdef USE_RSA
1398     case PGP_ES_RSA:
1399     err = pgp_rsa(data, key, PK_SIGN);
1400     if (err == 0)
1401     mpi_put(out, data);
1402     break;
1403 rabbi 262 #endif /* USE_RSA */
1404 rabbi 1 case PGP_S_DSA:
1405     err = pgp_dsasign(data, key, out);
1406     break;
1407     default:
1408     errlog(NOTICE, "Unknown encryption algorithm!\n");
1409     return (-1);
1410     }
1411     if (err == -1)
1412     errlog(ERRORMSG, "Signing operation failed!\n");
1413    
1414     buf_move(data, out);
1415     buf_free(out);
1416     buf_free(r);
1417     buf_free(s);
1418     return (err);
1419     }
1420    
1421     int pgp_elgdecrypt(BUFFER *in, BUFFER *key)
1422     {
1423 weaselp 120 BIGNUM *a = NULL, *b = NULL, *c = NULL,
1424     *p = NULL, *g = NULL, *x = NULL;
1425 rabbi 1 BN_CTX *ctx;
1426     BUFFER *i;
1427     int err = -1;
1428    
1429     i = buf_new();
1430     ctx = BN_CTX_new();
1431     if (ctx == NULL) goto end;
1432     mpi_get(key, i);
1433     p = BN_bin2bn(i->data, i->length, NULL);
1434     mpi_get(key, i);
1435     g = BN_bin2bn(i->data, i->length, NULL);
1436     mpi_get(key, i); /* y */
1437     mpi_get(key, i);
1438     x = BN_bin2bn(i->data, i->length, NULL);
1439     mpi_get(in, i);
1440     a = BN_bin2bn(i->data, i->length, NULL);
1441     if (mpi_get(in, i) == -1)
1442     goto e1;
1443     b = BN_bin2bn(i->data, i->length, NULL);
1444     c = BN_new();
1445    
1446     if (BN_mod_exp(c, a, x, p, ctx) == 0) goto end;
1447     if (BN_mod_inverse(a, c, p, ctx) == 0) goto end;
1448     if (BN_mod_mul(c, a, b, p, ctx) == 0) goto end;
1449    
1450     buf_prepare(i, BN_num_bytes(c));
1451     i->length = BN_bn2bin(c, i->data);
1452    
1453     buf_prepare(in, BN_num_bytes(c));
1454     in->length = RSA_padding_check_PKCS1_type_2(in->data, in->length, i->data,
1455     i->length, i->length + 1);
1456     if (in->length <= 0)
1457     in->length = 0;
1458     else
1459     err = 0;
1460    
1461     end:
1462     BN_free(b);
1463     BN_free(c);
1464     e1:
1465     buf_free(i);
1466     BN_free(a);
1467     BN_free(p);
1468     BN_free(g);
1469     BN_clear_free(x);
1470     BN_CTX_free(ctx);
1471    
1472     return (err);
1473     }
1474    
1475     int pgp_elgencrypt(BUFFER *in, BUFFER *key)
1476     {
1477 weaselp 120 BIGNUM *m, *k, *a, *b, *c, *p, *g, *y = NULL;
1478 rabbi 1 BN_CTX *ctx;
1479     BUFFER *i;
1480     int err = -1;
1481    
1482     i = buf_new();
1483     ctx = BN_CTX_new();
1484     if (ctx == NULL) goto end;
1485     mpi_get(key, i);
1486     p = BN_bin2bn(i->data, i->length, NULL);
1487     mpi_get(key, i);
1488     g = BN_bin2bn(i->data, i->length, NULL);
1489     if (mpi_get(key, i) == -1)
1490     goto e1;
1491     y = BN_bin2bn(i->data, i->length, NULL);
1492    
1493     buf_prepare(i, BN_num_bytes(p));
1494     if (RSA_padding_add_PKCS1_type_2(i->data, i->length, in->data, in->length)
1495     != 1)
1496     goto end;
1497     m = BN_bin2bn(i->data, i->length, NULL);
1498    
1499     k = BN_new();
1500     BN_rand(k, BN_num_bits(p), 0, 0);
1501    
1502     a = BN_new();
1503     b = BN_new();
1504     c = BN_new();
1505    
1506     if (BN_mod_exp(a, g, k, p, ctx) == 0) goto end;
1507     if (BN_mod_exp(c, y, k, p, ctx) == 0) goto end;
1508     if (BN_mod_mul(b, m, c, p, ctx) == 0) goto end;
1509    
1510     buf_clear(in);
1511     i->length = BN_bn2bin(a, i->data);
1512     mpi_put(in, i);
1513     i->length = BN_bn2bin(b, i->data);
1514     mpi_put(in, i);
1515    
1516     err = 0;
1517    
1518     BN_free(a);
1519     BN_free(b);
1520     BN_free(c);
1521     BN_free(m);
1522     e1:
1523     buf_free(i);
1524     BN_free(p);
1525     BN_free(g);
1526     BN_free(y);
1527     BN_CTX_free(ctx);
1528     end:
1529    
1530     return (err);
1531     }
1532    
1533     #endif /* USE_PGP */

  ViewVC Help
Powered by ViewVC 1.1.5