#include <stdio.h>
#include <string.h>
#include "libpgp5.h"

extern unsigned long crctab[256];
extern unsigned char dmtab[84];

/*-------------------------*/
/* Same as in dearmor, except returns a buffer */
static unsigned char inbuf[256], *ip = inbuf;
long unmime(FILE * ifd, char *ofd)
{
  int i = 3, j;
  unsigned long t, ccrc = 0xB704CE;
  char cx[4], *c = cx;

  if (ofd)
    c = ofd;
  inbuf[0] = 0;
  while (i == 3) {
    for (i = 0; i < 4; i++) {
      while (!(j = *ip++) || j > 124 || j < 40 || (c[i] = dmtab[j - 40]) > 65)
        if (!j && !fgets(ip = inbuf, 255, ifd))
          return -1;
      if (c[i] < 64)
        continue;
      if (ofd)
        break;
      i--;
    }
    t = (c[0] << 18) | (c[1] << 12) | (c[2] << 6) | c[3];
    if (!ofd)
      return t;
    c[0] = t >> 16, c[1] = t >> 8, c[2] = t;
    i -= (i > 1);
    c += i;
  }
  for (t = 0; t < c - ofd; t++)
    ccrc = ccrc << 8 ^ crctab[0xff & ((ccrc >> 16) ^ ofd[t])];
  return ccrc & 0xffffff;
}

/*-------------------------*/
/* canonicalize string (and remove dash escape) */
void fixstr(char *s)
{
  while (strlen(s) && s[strlen(s) - 1] <= ' ')
    s[strlen(s) - 1] = 0;
  strcat(s, "\r");
  strcat(s, "\n");
  if (!strncmp(s, "- -", 3))
    memmove(s, &s[2], strlen(s));
};

/*-------------------------*/
int main(int argc, char *argv[])
{
  unsigned char dbuf[4096], xbuf[4096], *bp;
  int cnt;
  void *hctx;
  FILE *inf = stdin;

  if (argc > 1 && !(inf = fopen(argv[1], "r")))
    exit(-1);

  while (!feof(inf)) {
    fgets(dbuf, 4095, inf);
    if (!strncmp(dbuf, "-----BEGIN PGP SIGNED MESSAGE-----", 34))
      break;
  }
  cnt = 1;                      /* default hash */
  while (dbuf[0] != '\n' && dbuf[0] != '\r') {
    fgets(dbuf, 4095, inf);
    if (!strstr(dbuf, "Hash:"))
      continue;
    if (strstr(dbuf, "SHA1"))
      cnt = 2;
    else if (strstr(dbuf, "RIPEMD160"))
      cnt = 3;
    else if (strstr(dbuf, "HAVAL"))
      cnt = 4;
    else if (strstr(dbuf, "MD2"))
      cnt = 5;
  }
  hctx = hashinit(cnt);
  xbuf[0] = 0;
  cnt = 0;
  bp = dbuf;
  while (!feof(inf)) {          /* doubled - don't hash last TWO lines */
    fgets(bp, 4095, inf);
    fixstr(bp);
    if (!strncmp(bp, "-----BEGIN PGP SIGNATURE-----", 29))
      break;
    bp = cnt++ & 1 ? xbuf : dbuf;
    hashupdate(hctx, bp, strlen(bp));
  }
  while (bp[0] != '\n' && bp[0] != '\r')
    fgets(bp, 4095, inf);
  if (unmime(inf, xbuf) != unmime(inf, NULL)) {
    fprintf(stderr, "Bad Signature Armor\n");
    return -1;
  }
  cnt = sigchk5(&xbuf[1 + (1 << (xbuf[0] & 3))], hctx);
  fprintf(stderr, "%s\n", cnt ? "FAILED SIGNATURE" : "Good Signature");
  return cnt;
}
