Here is a solution I found using OpenSSL libraries. I am posting a question and answer about stack overflows in the hope that this will save others from the need and time to figure it out ourselves.
#include <stdio.h> #include <sys/stat.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/x509.h> #include <openssl/bio.h> int main(int argc, char * argv[]) { struct stat sb; unsigned char * buff; int fd; ssize_t len; BIO * bio; X509 * x; unsigned err; int pos; char errmsg[1024]; const EVP_MD * digest; unsigned char md[EVP_MAX_MD_SIZE]; unsigned int n; // checks arguments if (argc != 2) { fprintf(stderr, "Usage: peminfo <pemfile>\n"); return(1); }; // checks file if ((stat(argv[1], &sb)) == -1) { perror("peminfo: stat()"); return(1); }; len = (sb.st_size * 2); // allocates memory if (!(buff = malloc(len))) { fprintf(stderr, "peminfo: out of virtual memory\n"); return(1); }; // opens file for reading if ((fd = open(argv[1], O_RDONLY)) == -1) { perror("peminfo: open()"); free(buff); return(1); }; // reads file if ((len = read(fd, buff, len)) == -1) { perror("peminfo: read()"); free(buff); return(1); }; // closes file close(fd); // initialize OpenSSL SSL_load_error_strings(); SSL_library_init(); OpenSSL_add_all_algorithms(); // creates BIO buffer bio = BIO_new_mem_buf(buff, len); // decodes buffer if (!(x = PEM_read_bio_X509(bio, NULL, 0L, NULL))) { while((err = ERR_get_error())) { errmsg[1023] = '\0'; ERR_error_string_n(err, errmsg, 1023); fprintf(stderr, "peminfo: %s\n", errmsg); }; BIO_free(bio); free(buff); return(1); }; // prints x509 info printf("name: %s\n", x->name); printf("serial: "); printf("%02X", x->cert_info->serialNumber->data[0]); for(pos = 1; pos < x->cert_info->serialNumber->length; pos++) printf(":%02X", x->cert_info->serialNumber->data[pos]); printf("\n"); // calculate & print fingerprint digest = EVP_get_digestbyname("sha1"); X509_digest(x, digest, md, &n); printf("Fingerprint: "); for(pos = 0; pos < 19; pos++) printf("%02x:", md[pos]); printf("%02x\n", md[19]); // frees memory BIO_free(bio); free(buff); return(0); }
Here is the compilation and output of the above program:
$ cc -pedantic -W -Wall -Werror -O2 -Wno-deprecated -o peminfo peminfo.c \ > -lcrypto -lssl $ ./peminfo /usr/local/etc/openldap/keys/ca-certs.pem serial: 98:61:EB:C4:F2:C9:59:72 Fingerprint: 1d:59:d3:d4:4f:c9:e3:dc:f3:d7:66:b0:b8:7e:87:0b:01:73:c2:7e
Here is the output from the openssl utility:
$ openssl x509 -noout -in /usr/local/etc/openldap/keys/ca-certs.pem \ > -fingerprint -serial SHA1 Fingerprint=1D:59:D3:D4:4F:C9:E3:DC:F3:D7:66:B0:B8:7E:87:0B:01:73:C2:7E serial=9861EBC4F2C95972
source share