#include "libopgp.h"

const u8_t PGP_mtab[66] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=-";

void PGP_arm3x4(u8_t * in, u8_t * out)
{
  out[0] = PGP_mtab[in[0] >> 2];
  out[1] = PGP_mtab[((in[0] << 4) & 0x30) | ((in[1] >> 4) & 0x0f)];
  out[2] = PGP_mtab[((in[1] << 2) & 0x3c) | ((in[2] >> 6) & 0x03)];
  out[3] = PGP_mtab[in[2] & 0x3f];
}

static const char defcert[] = "MESSAGE";
static const char aaheader[] = "Version: OpenPrivacy 0.99";
/*-------------------------*/
/* armor - should allow specifying the cert type and header */
int PGP_armor(FILE * ifd, FILE * ofd, char *certype, char *headtxt)
{
  u8_t inb[48], outb[65], *in = inb, *out = outb;
  int i = 0, j, q = 0;
  unsigned long ccrc = 0xB704CE;
  char const *cert, *hdr;

  cert = certype ? certype : defcert;
  hdr = headtxt ? headtxt : aaheader;
  fprintf(ofd, "-----BEGIN PGP %s-----\n%s\n\n", cert, hdr);
  for (;;) {
    if (!q) {
      out = outb, in = inb;
      memset(in, 0, 48);
      if (0 >= (i = fread(in, 1, 48, ifd)))
        break;
      for (j = 0; j < i; j++)
        ccrc = ccrc << 8 ^ PGP_crc24t[0xff & ((ccrc >> 16) ^ in[j])];
    }
    PGP_arm3x4(in, out);
    if (i < 3)
      break;
    q += 4, i -= 3;
    if (q == 64) {
      out[4] = '\n', out[5] = 0;
      fputs(outb, ofd);
      q = 0;
    }
    if (q && !i)
      break;
    out += 4, in += 3;
  }
  if (i == 1)
    out[2] = '=';
  if (i)
    out[3] = '=', q = 4;
  if (q) {
    out[4] = '\n', out[5] = 0;
    fputs(outb, ofd);
  }
  fputc('=', ofd);
  in[0] = ccrc >> 16, in[1] = ccrc >> 8, in[2] = ccrc;
  PGP_arm3x4(in, out);
  out[4] = '\n', out[5] = 0;
  fputs(out, ofd);
  fprintf(ofd, "-----END PGP %s-----\n", cert);
  return 0;
}
