Introduction
The example 'C' program certpubkey.c demonstrates how to extract the public key data from a X.509 digitial certificate, using the OpenSSL library functions.
Example Code Listing
/* ------------------------------------------------------------ *
* file: certpubkey.c *
* purpose: Example code to extract public keydata in certs *
* author: 09/24/2012 Frank4DD *
* *
* gcc -o certpubkey certpubkey.c -lssl -lcrypto *
* ------------------------------------------------------------ */
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
int main() {
const char cert_filestr[] = "./cert-file.pem";
EVP_PKEY *pkey = NULL;
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 public key data. *
* ---------------------------------------------------------- */
if ((pkey = X509_get_pubkey(cert)) == NULL)
BIO_printf(outbio, "Error getting public key from certificate");
/* ---------------------------------------------------------- *
* Print the public key information and the key in PEM format *
* ---------------------------------------------------------- */
/* display the key type and size here */
if (pkey) {
switch (pkey->type) {
case EVP_PKEY_RSA:
BIO_printf(outbio, "%d bit RSA Key\n\n", EVP_PKEY_bits(pkey));
break;
case EVP_PKEY_DSA:
BIO_printf(outbio, "%d bit DSA Key\n\n", EVP_PKEY_bits(pkey));
break;
default:
BIO_printf(outbio, "%d bit non-RSA/DSA Key\n\n", EVP_PKEY_bits(pkey));
break;
}
}
if(!PEM_write_bio_PUBKEY(outbio, pkey))
BIO_printf(outbio, "Error writing public key data in PEM format");
EVP_PKEY_free(pkey);
X509_free(cert);
BIO_free_all(certbio);
BIO_free_all(outbio);
exit(0);
}
Compiling the Code
Compile the test program with:
fm@susie114:~> gcc -o certpubkey certpubkey.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 output is produced:
fm@susie114:~> ./certpubkey 2048 bit RSA Key -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9VnD7Y5zjMDFeQsw7CWP Rb/tpOiUkvHETGo6XFIG2dkmEgWy0zb/1o4Q28Vla6zOoyTAwZpRqq0EQoQpUqtq rvQPX//JLcyYH8OOkGyetHDum1L+lDdnc3z3d2BxvYVw2gP0NlG4c2GbOlB5LGsn vO8YCGpzLcO8rQmMFp43MbTPZV6emmeI6mn9cB9SyWGgvTvJVCRvrcqTMuakEv/6 t6IRkmhkwD7pJr0qeREynuBWqKRrofWvxc+/JlVjzAofH+Jt6mZpJSNKpCoZRLiR s7vEGWW1OSwvvcx9s0JI7zTefJzECE74FerjMLuTbr+r2+ThgmMTrnFvOYl5SmaL rQIDAQAB -----END PUBLIC KEY-----
Remarks
Most certificates today seem to come with a RSA key between 1024 and 4096 bits, while DSA keys are less common.