shaynlink / ssl-cert-generator-lib

OpenSSL C++ X509 certificate generator library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SSL cert generator library

http://bertrandmartel.github.io/ssl-cert-generator-lib/

Last update 11/10/2015

Generate SSL certificates using openssl api :

  • generate X509 public/private key pair, output can be PEM, PKCS12 certs
  • generate self-signed cert (which can be used as CA cert)
  • generate X509 public/private key pair signed with a specific issuer cert or a CA
  • generate a diffie hellman key
  • output can be a specific file / certificates can be accessed programmatically as well

Generality

cd sslcertgenerator
make

Library release is under release directory.


Generate self-signed certificates

Declare new instance of SslGen :

#include "crypto/sslgen.h"

....

sslgen ssl_gen;

Generate self-signed certificates :

ssl_gen.create_standalone_keys(cert_entries *entries,struct tm *date_start,struct tm *date_end,int serial,char *passin,int rsa_key_size,certificate_raw *certs);
  • entries : a set of certificate entries with following structure :
typedef struct {
    std::string country_name;
    std::string state_province_name;
    std::string locality_name;
    std::string organization_name;
    std::string organizational_unit_name;
    std::string common_name;
} cert_entries;
  • date_start and date_end specifying certificate validation timings
  • serial : specifying certificate serial number to be used
  • passin : optional password for private key
  • rsa_key_size : size of key (2048 or more is prefered)
  • certificate_raw : output pointer structure as following :
typedef struct {
    std::string       public_key_pem;
    std::string       private_key_pem;
    std::vector<char> key_pkcs12;
} certificate_raw;

Generate signed certificates

ssl_gen.create_signed_keys(cert_entries *entries,struct tm *date_start,struct tm *date_end,int serial,char *passin,int rsa_key_size,ca_cert *cert_item,certificate_raw *certs);
  • entries : a set of certificate entries with following structure :
typedef struct {
    std::string country_name;
    std::string state_province_name;
    std::string locality_name;
    std::string organization_name;
    std::string organizational_unit_name;
    std::string common_name;
} cert_entries;
  • date_start and date_end specifying certificate validation timings
  • serial : specifying certificate serial number to be used
  • passin : optional password for private key
  • rsa_key_size : size of key (2048 or more is prefered)
  • ca_cert : structure defining public/private key of CA cert or cert issuer
typedef struct{
    std::string public_key_pem;
    std::string private_key_pem;
    std::string pass;
} ca_cert;
  • certificate_raw : output pointer structure as following :
typedef struct {
    std::string       public_key_pem;
    std::string       private_key_pem;
    std::vector<char> key_pkcs12;
} certificate_raw;

Specify output format and file output

By default public and private key are given in PEM format. By default, no output file path is specified.

You can specify cert output files for PEM cert as following :

ssl_gen.setOutputPEM(bool enable_pem,char* public_key_file,char* private_key_file);
  • enable_pem : enable PEM format (default)
  • public_key_file : output file for public key in PEM format
  • private_key_file : output file for private key in PEM format

You can specify cert output files for PKCS12 cert as following :

ssl_gen.setOutputP12(bool enable_p12,char* key_file);
  • enable_p12 : enable PKCS12 format
  • key_file : output file for public/private key in PKCS12 format

Generate DH key

Generate Diffie-Hellman key with :

ssl_gen.create_dh_key(int key_size,char* file_path);
  • key_size : key size to be used (2048 is preferred)
  • file_path : required output file path for the key

Examples

From test project in main.cpp

Generate self-signed certificates


/*instanciate certificate generation lib*/
sslgen ssl_gen;

/* get system time for date start*/
time_t systime;
struct tm *sys_time;
time(&systime);
sys_time=localtime(&systime);

/* set end date to 30/08/2019 00:00:00 (current timezone)*/
struct tm  date_end;
date_end.tm_year = 2019 - 1900;
date_end.tm_mon = 8 - 1;
date_end.tm_mday = 30;
date_end.tm_hour = 0;
date_end.tm_min = 0;
date_end.tm_sec = 0;
date_end.tm_isdst = sys_time->tm_isdst;

/*set certificate entries*/
cert_entries entries;
entries.country_name=CERT_COUNTRY_NAME;
entries.state_province_name=CERT_STATE_OR_PROVINCE_NAME;
entries.locality_name=CERT_LOCALITY_NAME;
entries.organization_name=CERT_ORGANIZATION_NAME;
entries.organizational_unit_name=CERT_ORGANIZATION_UNIT_NAME;

/* generate public/private key (we want PEM + PKCS12 format) + output is retrieved through input pointer + file output name*/

/*set output cert as pem certificate (default). If you set file output name. Cert will be written under these files*/
ssl_gen.setOutputPEM(true,"../../output_test/test.crt","../../output_test/test.key");

/*set output cert as p12 certificate. If you set file output name. Cert will be written under these files*/
ssl_gen.setOutputP12(true,"../../output_test/test.p12");

certificate_raw certs;
certificate_raw *certs_ptr;
certs_ptr=&certs;
certs_ptr->public_key_pem="";
certs_ptr->private_key_pem="";

entries.common_name="Github ssl-cert-generator";

/* generate standalone keys (not signed with other certificate) */
ssl_gen.create_standalone_keys(&entries,sys_time,&date_end,509,"123456",2048,&certs);

cout << "public cert  : " << certs_ptr->public_key_pem << endl;
cout << "private cert : " << certs_ptr->private_key_pem << endl;
cout << "p12 binary content : " << endl;
utils::printHexFormattedCert(certs_ptr->key_pkcs12,certs_ptr->key_pkcs12.size());

Generate signed certificate


std::ifstream in1("../../cert/ca.key");
std::string root_ca_key_input((std::istreambuf_iterator<char>(in1)),std::istreambuf_iterator<char>());

std::ifstream in2("../../cert/ca.crt");
std::string root_ca_pub_input((std::istreambuf_iterator<char>(in2)),std::istreambuf_iterator<char>());

/*set output cert as pem certificate (default). If you set file output name. Cert will be written under these files*/
ssl_gen.setOutputPEM(true,"../../output_test/client.crt","../../output_test/client.key");

/*set output cert as p12 certificate. If you set file output name. Cert will be written under these files*/
ssl_gen.setOutputP12(true,"../../output_test/client.p12");

ca_cert ca;
ca.public_key_pem=root_ca_pub_input;
ca.private_key_pem=root_ca_key_input;
ca.pass="123456";

entries.common_name="Github ssl-cert-generator signed cert";

ssl_gen.create_signed_keys(&entries,sys_time,&date_end,22555,"123456",2048,&ca,&certs);

cout << "public cert  : " << certs_ptr->public_key_pem << endl;
cout << "private cert : " << certs_ptr->private_key_pem << endl;
cout << "p12 binary content : " << endl;
utils::printHexFormattedCert(certs_ptr->key_pkcs12,certs_ptr->key_pkcs12.size());


Checking and Verifying certificates

Here are some useful openssl command to test your output :

Check start date and end date for a PEM certificate

  • openssl x509 -startdate -noout -in cert.crt
  • openssl x509 -enddate -noout -in cert.crt

Check a public PEM key

  • openssl x509 -in cert.crt -text -noout

Check a private PEM key

  • openssl rsa -in cert.key -check

Check a PKCS12 file

  • openssl pkcs12 -info -in cert.p12

Check that public/key pair is uncorrupted

Those commands should return same md5 :

  • openssl x509 -noout -modulus -in cert.crt | openssl md5
  • openssl rsa -noout -modulus -in cert.key | openssl md5

Verify certificate

  • openssl verify cert.pem

Verify certificate chain

  • openssl verify -CAfile ca.crt server.crt

Install certificates on Linux

sudo mkdir /usr/share/ca-certificates/extra

sudo cp your_cert.pem /usr/share/ca-certificates/extra/your_cert.crt

sudo dpkg-reconfigure ca-certificates

sudo update-ca-certificates

Memory checking

Project is memcheck free

valgrind --tool=memcheck --leak-check=full ./main

Project is built with openssl library built with -DPURIFY option to avoid valgrind to complain about uninitialized data ("Conditional jump or move depends on uninitialised value(s)" warnings).

https://www.openssl.org/docs/faq.html#PROG14

TODO

  • add static library
  • add certificate extensions
  • add CA certificate to PKCS12 for signed certificate
  • add pass for PKCS12 (distinguished from private key)

About

OpenSSL C++ X509 certificate generator library

License:MIT License


Languages

Language:C 86.9%Language:C++ 13.1%Language:Makefile 0.1%