SSL cert generator library
http://akinaru.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
Library is generated as a shared library (.dll or .so)
cd sslcertgenerator
make
Library release is under release
directory.
You can export shared library to your library path to use it.
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
anddate_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
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)