#include <stdio.h>
#include <string.h>
#include <md5.h>
#include "libpgp2.h"

extern unsigned char asnchk[];

/*------------------------------------*/
/* check signature - should also return type, time, etc. */
int sigchk2(FILE * cert, FILE * check, int dodelit)
{
  unsigned long long keyid = 0LL;
  unsigned long ll, i, j;
  unsigned char dbuf[4096], tstp[4], mdck[2], mdhash[16];
  int scf;
  RSA *key;
  MD5_CTX md5ctx;

  j = fgetc(cert);
  if ((j & 0xfc) != 0x88) {
    ungetc(j, cert);
    return -1;
  }
  ll = 1 << (j & 3);            /* length of length */
  fread(dbuf, 1, ll, cert);
  for (j = 0, i = 0; j < ll; j++)
    i = (i << 8) + dbuf[j];
  if (fgetc(cert) != 3)
    return -4;                  /* version, should be 3 */
  if (fgetc(cert) != 5)
    return -3;
  scf = fgetc(cert);
  fread(tstp, 1, 4, cert);
  fread(dbuf, 1, 8, cert);
  for (j = 0; j < 8; j++)
    keyid = (keyid << 8) + dbuf[j];
  if (getkey2(&key, NULL, NULL, &keyid))
    return 1;
  if (fgetc(cert) != 1 || fgetc(cert) != 1)
    return -3;
  fread(mdck, 1, 2, cert);
  fread(dbuf, 1, 2, cert);
  j = 256 * dbuf[0];
  j += dbuf[1];
  i -= 21;
  fread(dbuf, 1, i, cert);
  ll = BN_num_bytes(key->n);
  while (i < ll)
    memmove(&dbuf[1], dbuf, i++), dbuf[0] = 0;
  j = RSA_public_decrypt(ll, dbuf, dbuf, key, RSA_PKCS1_PADDING);
  RSA_free(key);
  if (memcmp(dbuf, asnchk, 18) || memcmp(&dbuf[18], mdck, 2))
    return -2;
  memcpy(mdhash, &dbuf[18], 16);
  if (dodelit)
    delit(check);
  MD5_Init(&md5ctx);
  while (!feof(check))          /* do message digest */
    if ((ll = fread(dbuf, 1, 4096, check)))
      MD5_Update(&md5ctx, dbuf, ll);
  dbuf[0] = scf;
  memcpy(&dbuf[1], tstp, 4);
  MD5_Update(&md5ctx, dbuf, 5);
  MD5_Final(dbuf, &md5ctx);
  if (memcmp(dbuf, mdhash, 16))
    return -1;
  return 0;
}
