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

extern unsigned char asnchk[];

/*------------------------------------*/
/* make signature - need to pass type, etc. */
int sigmak2(FILE * inpf, FILE * cert, unsigned char *passwdhash,
            unsigned long long keyid, int dodelit, int text)
{
  int ll, j;
  unsigned char dbuf[4096], mdhash[16], extramd[5];
  MD5_CTX md5ctx;
  RSA *key;

  if (getkey2(&key, NULL, passwdhash, &keyid))  /* get seckey */
    return 1;                   /* no secret key */
  if (dodelit)
    delit(inpf);
  MD5_Init(&md5ctx);
  do {
    if ((ll = fread(dbuf, 1, 4096, inpf)))
      MD5_Update(&md5ctx, dbuf, ll);
  } while (ll == 4096);
  extramd[0] = text;            /* binary-generic */
  ll = time(NULL);              /* timestamp */
  extramd[1] = ll >> 24;
  extramd[2] = ll >> 16;
  extramd[3] = ll >> 8;
  extramd[4] = ll;
  MD5_Update(&md5ctx, extramd, 5);
  MD5_Final(mdhash, &md5ctx);
  memcpy(dbuf, asnchk, 18);
  memcpy(&dbuf[18], mdhash, 16);
  j = 8 * RSA_private_encrypt(34, dbuf, dbuf, key, RSA_PKCS1_PADDING);
  RSA_free(key);
  while (dbuf[0] == 0)
    memmove(dbuf, &dbuf[1], (j + 7) / 8), j -= 8;
  ll = dbuf[0];
  while (!(ll & 0x80)) {
    j--;
    ll <<= 1;
  }
  ll = 21 + (j + 7) / 8;
  fputc(0x89, cert);
  fputc(ll >> 8, cert);         /* packet length */
  fputc(ll, cert);
  fputc(3, cert);               /* version */
  fputc(5, cert);               /* number of bytes in hash append */
  fwrite(extramd, 1, 5, cert);  /* bin/text and timestamp */
  for (ll = 0; ll < 8; ll++)    /* keyid */
    fputc(0xff & (keyid >> (56 - 8 * ll)), cert);
  fputc(1, cert);               /* crypto alg */
  fputc(1, cert);               /* hash alg */
  fputc(mdhash[0], cert);       /* hashcheck */
  fputc(mdhash[1], cert);
  fputc(j >> 8, cert);
  fputc(j, cert);
  fwrite(dbuf, 1, (j + 7) / 8, cert);
  return 0;
}
