#include <stdio.h>
#include <openssl/objects.h>
#include <openssl/dsa.h>
#include <openssl/md5.h>

int main()
{
  DSA *dsa;
  unsigned char message[] = "This is the message to be signed";
  unsigned char md[16];
  unsigned char sign[128];
  unsigned int sign_len;
  int i;

  dsa = DSA_generate_parameters(512, NULL, 0, NULL, NULL, NULL, NULL);
  if (DSA_generate_key(dsa) != 1) {
    ERR_load_crypto_strings();
    unsigned long err = ERR_get_error();
    printf("%s\n", ERR_error_string(err, NULL));
  }

  printf("DSA_size = %d\n", DSA_size(dsa));
  DSA_print_fp(stdout, dsa, 0);

  MD5(message, strlen(message), md);
  printf("md5: ");
  for (i = 0; i < 16; i++)
    printf("%02x", md[i]);
  printf("\n");

  if (DSA_sign(NULL, md, 16, sign, &sign_len, dsa) != 1) {
    ERR_load_crypto_strings();
    unsigned long err = ERR_get_error();
    printf("%s\n", ERR_error_string(err, NULL));
  }

  printf("signature (len=%u): ", sign_len);
  for (i = 0; i < sign_len; i++)
    printf("%02x", sign[i]);
  printf("\n");

  /* Verify should still work after blanking out the private
     components of key. */
  dsa->priv_key = NULL;

  if (DSA_verify(NULL, md, 16, sign, sign_len, dsa) == 1)
    printf("Verified\n");
  else
    printf("*** Verification Failed ***\n");

  return 0;
}

