#include "libopgp.h"
#include <rand.h>

u8_t PGP_s2kca = 3, PGP_s2kha = 2, PGP_s2ksa = 3, PGP_s2kic = 0x60;

void PGP_encrx(FILE * inf, FILE * outf, int encf, int convf, keyid_t keyid[],
               int syma, char *pp[], int ca, int ha, int sa, int ic)
{

  if (ca > 0)
    PGP_s2kca = ca;
  if (ha > 0)
    PGP_s2kha = ha;
  if (sa > 0)
    PGP_s2ksa = sa;
  if (ic > 0)
    PGP_s2kic = ic;
  PGP_encry(inf, outf, encf, convf, keyid, syma, pp);
  PGP_s2kca = 3, PGP_s2kha = 2, PGP_s2ksa = 3, PGP_s2kic = 0x60;
}

int PGP_encry(FILE * inf, FILE * outf, int encf, int convf, keyid_t keyid[],
              int syma, char *pp[])
{
  u8_t dbuf[625], convkey[30], *bp;
  void *ccfb = NULL;
  int i, j, ll;
  u8_t phdr[6] =
  {0xa8, 3, 'P', 'G', 'P', 0};

  if (convf != -1 || PGP_s2kca != 1 || PGP_s2kha != 1 || PGP_s2ksa != 0)
    fwrite(phdr, 1, strlen(phdr), outf);
  /* prepare conventional key (not used if convf == -1) */
  convkey[0] = syma;
  j = PGP_cksz(syma);           /* key len */
  RAND_bytes(&convkey[1], j);
  for (ll = 0, i = 1; i <= j; i++)
    ll += convkey[i];           /* conv key checksum */
  convkey[++j] = ll >> 8, convkey[j + 1] = ll;
  if (convf == -1)
    PGP_s2kca = syma;
  while (encf) {                /* pubkey encrypted headers */
    if (0 >= (ll = PGP_pkenc(keyid[--encf], dbuf, convkey, j + 2)))
      exit(-2);
    fwrite(dbuf, 1, ll, outf);
  }
  while (convf) {               /* do passphrase headers */
    /* for each passphrase (in keybuf) if multiple, and convf == 2 */
    dbuf[0] = 4, dbuf[1] = PGP_s2kca, dbuf[2] = PGP_s2ksa, dbuf[3] = PGP_s2kha;
    dbuf[4] = PGP_s2kic;
    ll = PGP_wrs2k(dbuf, *pp, &ccfb);
    bp = dbuf + ll;
    if (convf != -1) {
      memcpy(bp, convkey, j);
      PGP_cblk(bp, j, ccfb);
      free(ccfb);
      ccfb = NULL;
      ll += j;
    }
    /* omit if pgp 2.x conventional default */
    if (convf != -1 || PGP_s2kca != 1 || PGP_s2kha != 1 || PGP_s2ksa != 0) {
      fputc(0xc3, outf);
      if (ll > 192) {
        fputc(0xc0 | ((ll - 192) >> 8), outf);
        fputc(ll - 192, outf);
      } else
        fputc(ll, outf);
      fwrite(dbuf, 1, ll, outf);
    }
    if (--convf < 0)
      break;
    pp++;
  }
  /* end of key headers */
  memset(dbuf, 0, 256);
  if (!ccfb)
    ccfb = PGP_cini(&convkey[1], dbuf, syma, 1);
  PGP_cenc(inf, outf, ccfb);
  return 0;
}
