mixmaster

mixmaster 3.0 patched for libressl
git clone git://parazyd.org/mixmaster.git
Log | Files | Refs | README

pgpdata.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 */