Introduction


The example 'C' program certsignature.c demonstrates how to extract the serial number from a X.509 digitial certificate, using the OpenSSL library functions.

Example Code Listing


/* ------------------------------------------------------------ *
 * file:        certsignature.c                                 *
 * purpose:     Example to extract and display cert signatures  *
 * author:      09/30/2012 Frank4DD                             *
 *                                                              *
 * gcc -o certsignature certsignature.c -lssl -lcrypto          *
 * ------------------------------------------------------------ */

#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>


/* ---------------------------------------------------------- *
 * This function is taken from openssl/crypto/asn1/t_x509.c.  *
 * ---------------------------------------------------------- */
int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent);

int main() {

  const char cert_filestr[] = "./cert-file.pem";
  ASN1_STRING     *asn1_sig = NULL;
  X509_ALGOR      *sig_type = NULL;
  size_t          sig_bytes = 0;
  BIO              *certbio = NULL;
  BIO               *outbio = NULL;
  X509                *cert = NULL;
  int ret;

  /* ---------------------------------------------------------- *
   * These function calls initialize openssl for correct work.  *
   * ---------------------------------------------------------- */
  OpenSSL_add_all_algorithms();
  ERR_load_BIO_strings();
  ERR_load_crypto_strings();

  /* ---------------------------------------------------------- *
   * Create the Input/Output BIO's.                             *
   * ---------------------------------------------------------- */
  certbio = BIO_new(BIO_s_file());
  outbio  = BIO_new_fp(stdout, BIO_NOCLOSE);

  /* ---------------------------------------------------------- *
   * Load the certificate from file (PEM).                      *
   * ---------------------------------------------------------- */
  ret = BIO_read_filename(certbio, cert_filestr);
  if (! (cert = PEM_read_bio_X509(certbio, NULL, 0, NULL))) {
    BIO_printf(outbio, "Error loading cert into memory\n");
    exit(-1);
  }

  /* ---------------------------------------------------------- *
   * Extract the certificate's signature data.                  *
   * ---------------------------------------------------------- */
  sig_type = cert->sig_alg;
  asn1_sig = cert->signature;
  sig_bytes = asn1_sig->length;

  /* ---------------------------------------------------------- *
   * Print the signature type here                              *
   * ---------------------------------------------------------- */
  BIO_printf(outbio, "Signature Algorithm:\n");
  if (i2a_ASN1_OBJECT(outbio, sig_type->algorithm) <= 0)
    BIO_printf(outbio, "Error getting the signature algorithm.\n");
  else BIO_puts(outbio, "\n\n");

  /* ---------------------------------------------------------- *
   * Print the signature length here                            *
   * ---------------------------------------------------------- */
  BIO_printf(outbio, "Signature Length:\n%d Bytes\n\n", sig_bytes);

  /* ---------------------------------------------------------- *
   * Print the signature data here                              *
   * ---------------------------------------------------------- */
  BIO_printf(outbio, "Signature Data:");
  if (X509_signature_dump(outbio, asn1_sig, 0) != 1)
    BIO_printf(outbio, "Error printing the signature data\n");

  /* ---------------------------------------------------------- *
   * Free up all structures                                     *
   * ---------------------------------------------------------- */
  X509_free(cert);
  BIO_free_all(certbio);
  BIO_free_all(outbio);
  exit(0);
}

/* ---------------------------------------------------------- *
 * X509_signature_dump() converts binary signature data into  *
 * hex bytes, separated with : and a newline after 54 chars.  *
 * (2 chars + 1 ':' = 3 chars, 3 chars * 18 = 54)             *
 * ---------------------------------------------------------- */
int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) {
  const unsigned char *s;
  int i, n;

  n=sig->length;
  s=sig->data;
  for (i=0; i<n; i++) {
    if ((i%18) == 0) {
      if (BIO_write(bp,"\n",1) <= 0) return 0;
      if (BIO_indent(bp, indent, indent) <= 0) return 0;
    }
    if (BIO_printf(bp,"%02x%s",s[i],
      ((i+1) == n)?"":":") <= 0) return 0;
  }

  if (BIO_write(bp,"\n",1) != 1) return 0;

  return 1;
}

Compiling the Code


Compile the test program with:

fm@susie114:~> gcc -o certsignature certsignature.c -lssl -lcrypto

Example Output


The program expects a certificate file called cert-file.pem in the same directory. If the certificate is found and loaded, the following examplary output is produced:

fm@susie114:~> ./certsignature
Signature Algorithm:
sha1WithRSAEncryption

Signature Length:
256 Bytes

Signature Data:
5f:69:7d:de:ed:95:99:c3:43:03:a8:0f:91:bc:d7:0a:b9:c7:
0b:93:3f:0e:4e:c8:19:2d:7e:70:01:35:16:67:79:a6:45:87:
9f:6d:c6:63:04:c7:e2:49:53:83:d2:94:ba:1d:db:4d:57:54:
1c:d2:20:75:05:4c:c9:79:67:d2:5b:9c:b5:58:b9:80:bd:8f:
80:3f:7e:79:d1:86:93:e8:75:74:e2:0b:4a:81:74:3a:67:10:
ea:e1:d5:4d:a2:3c:c2:da:4c:b0:60:73:24:50:4a:96:2d:da:
11:f4:6a:b7:f3:84:1e:1a:08:b9:6c:41:b8:2d:59:1a:3f:a5:
af:d0:82:60:c1:98:57:ab:65:e5:ee:c5:b7:e8:82:9d:0d:29:
a6:b2:6c:d9:6c:49:70:35:ec:85:15:c0:3b:47:82:9f:52:7e:
85:c3:c7:73:ed:bd:35:98:38:4d:ee:3a:e7:3d:73:5e:e6:3b:
e9:4a:14:f6:f0:b6:5d:39:8a:c6:cf:1b:6d:e4:8c:1a:14:e5:
02:f2:0c:c4:c9:3c:74:4c:04:f4:52:b8:5e:dc:b0:d5:f8:86:
b1:59:d8:fa:5c:b3:eb:cf:96:14:50:c7:db:14:a9:3a:d9:99:
3e:e0:28:ca:84:03:a2:f7:1f:7e:fd:3f:08:3a:2d:8a:22:cf:
42:7f:d5:26

Remarks


The certificate signature is generated by using the private key of the signing CA certificate. The exception are so-called "self-signed" certificates, where the certificates own private key is used to sign itself. Self-signed certificates are also identifyable by having their subject data identical to their issuer section.


OpenSSL Logo

Topics:

Source:

Documentation: