
#include <stdio.h>
#include <stdlib.h>
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>

static const char* bin2hex( const void* bin, size_t bin_size)
{
static char printable[110];
unsigned char *_bin = bin;
char* print;

   if (bin_size > 50) bin_size = 50;

   print = printable;
   for (i = 0; i < bin_size; i++) {
      sprintf(print, "%.2x ", _bin[i]);
      print += 2;
   }

   return printable;
}

/* This function will print information about this session's peer
 * certificate. 
 */
static void print_x509_certificate_info(gnutls_session session)
{
   char serial[40];
   char dn[128];
   int i;
   size_t size;
   unsigned int algo, bits;
   time_t expiration_time, activation_time;
   const gnutls_datum *cert_list;
   int cert_list_size = 0;
   gnutls_x509_crt cert;

   /* This function only works for X.509 certificates.
    */
   if (gnutls_certificate_type_get(session) != GNUTLS_CRT_X509)
      return;

   cert_list = gnutls_certificate_get_peers(session, &cert_list_size);

   printf("Peer provided %d certificates.\n", cert_list_size);

   if (cert_list_size > 0) {

      /* we only print information about the first certificate.
       */
      gnutls_x509_crt_init( &cert);

      gnutls_x509_crt_import( cert, &cert_list[0]);

      printf("Certificate info:\n");

      expiration_time = gnutls_x509_crt_get_expiration_time( cert);
      activation_time = gnutls_x509_crt_get_activation_time( cert);

      printf("\tCertificate is valid since: %s", ctime(&activation_time));
      printf("\tCertificate expires: %s", ctime(&expiration_time));

      /* Print the serial number of the certificate.
       */
      size = sizeof(serial);
      gnutls_x509_crt_get_serial(cert, serial, &size);

      size = sizeof( serial);
      printf("\tCertificate serial number: %s\n", 
         bin2hex( serial, size));

      /* Extract some of the public key algorithm's parameters
       */
      algo =
          gnutls_x509_crt_get_pk_algorithm(cert, &bits);

      printf("Certificate public key: ");

      if (algo == GNUTLS_PK_RSA) {
         printf("RSA\n");
         printf(" Modulus: %d bits\n", bits);
      } else if (algo == GNUTLS_PK_DSA) {
         printf("DSA\n");
         printf(" Exponent: %d bits\n", bits);
      } else {
         printf("UNKNOWN\n");
      }

      /* Print the version of the X.509 
       * certificate.
       */
      printf("\tCertificate version: #%d\n",
             gnutls_x509_crt_get_version( cert));

      size = sizeof(dn);
      gnutls_x509_crt_get_dn( cert, dn, &size);
      printf("\tDN: %s\n", dn);

      size = sizeof(dn);
      gnutls_x509_crt_get_issuer_dn( cert, dn, &size);
      printf("\tIssuer's DN: %s\n", dn);

      gnutls_x509_crt_deinit( cert);

   }
}

