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