30#include <openssl/err.h>
31#include <openssl/evp.h>
32#include <openssl/pem.h>
33#include <openssl/x509.h>
34#include <openssl/x509v3.h>
37#include "openssl/applink.c"
48EVP_PKEY *generate_key() {
50 EVP_PKEY *pkey = EVP_PKEY_new();
52 cerr <<
"Unable to create EVP_PKEY structure." << endl;
57 RSA *rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL);
58 if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
59 cerr <<
"Unable to generate 2048-bit RSA key." << endl;
68int cs_cert_set_subject_alt_name(X509 *x509_cert,
string name) {
69 const char *subject_alt_name = name.c_str();
70 X509_EXTENSION *extension_san = NULL;
71 ASN1_OCTET_STRING *subject_alt_name_ASN1 = NULL;
74 subject_alt_name_ASN1 = ASN1_OCTET_STRING_new();
75 if (!subject_alt_name_ASN1) {
78 ASN1_OCTET_STRING_set(subject_alt_name_ASN1,
79 (
unsigned char *)subject_alt_name,
80 strlen(subject_alt_name));
81 if (!X509_EXTENSION_create_by_NID(&extension_san, NID_subject_alt_name, 0,
82 subject_alt_name_ASN1)) {
85 ASN1_OCTET_STRING_free(subject_alt_name_ASN1);
86 ret = X509_add_ext(x509_cert, extension_san, -1);
90 X509_EXTENSION_free(extension_san);
94 if (subject_alt_name_ASN1) ASN1_OCTET_STRING_free(subject_alt_name_ASN1);
95 if (extension_san) X509_EXTENSION_free(extension_san);
100X509 *generate_x509(EVP_PKEY *pkey,
string ip_v4) {
102 X509 *x509 = X509_new();
104 cerr <<
"Unable to create X509 structure." << endl;
109 ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
113 X509_gmtime_adj(X509_get_notBefore(x509), 0);
114 X509_gmtime_adj(X509_get_notAfter(x509), 31536000L);
117 X509_set_pubkey(x509, pkey);
120#if OPENSSL_VERSION_MAJOR >= 4
121 const X509_NAME *const_name = X509_get_subject_name(x509);
122 X509_NAME *name = X509_NAME_dup(const_name);
124 X509_NAME *name = X509_get_subject_name(x509);
128 X509_NAME_add_entry_by_txt(name,
"C", MBSTRING_ASC, (
unsigned char *)
"CA", -1,
130 X509_NAME_add_entry_by_txt(name,
"O", MBSTRING_ASC,
131 (
unsigned char *)
"MyCompany", -1, -1, 0);
132 X509_NAME_add_entry_by_txt(name,
"CN", MBSTRING_ASC,
133 (
unsigned char *)
"localhost", -1, -1, 0);
134 string ext_name(
"IP: ");
136 cs_cert_set_subject_alt_name(x509, ext_name);
139 X509_set_issuer_name(x509, name);
141#if OPENSSL_VERSION_MAJOR >= 4
143 X509_NAME_free(name);
147#if OPENSSL_VERSION_MAJOR * 10 + OPENSSL_VERSION_MINOR >= 32
148 const EVP_MD *evp_md = EVP_MD_fetch(0,
"SHA-256", 0);
150 const EVP_MD *evp_md = EVP_sha1();
152 if (!X509_sign(x509, pkey, evp_md)) {
153 unsigned long error = ERR_peek_error();
154 char *errmsg = ERR_error_string(error, 0);
155 cerr <<
"Error signing certificate:" << errmsg << endl;
163bool write_to_disk(EVP_PKEY *pkey, X509 *x509,
string cert_directory) {
165 string key_file = cert_directory;
166 key_file +=
"key.pem";
167 FILE *pkey_file = fopen(key_file.c_str(),
"wb");
169 cerr <<
"Unable to open \"key.pem\" for writing." << endl;
174 bool ret = PEM_write_PrivateKey(pkey_file, pkey, NULL, NULL, 0, NULL, NULL);
178 cerr <<
"Unable to write private key to disk." << endl;
183 string cert_file = cert_directory;
184 cert_file +=
"cert.pem";
186 FILE *x509_file = fopen(cert_file.c_str(),
"wb");
188 cerr <<
"Unable to open \"cert.pem\" for writing." << endl;
193 ret = PEM_write_X509(x509_file, x509);
197 cerr <<
"Unable to write certificate to disk." << endl;
204int make_certificate(
string ipv4,
string destination_dir) {
206 if (getenv(
"OCPN_DEBUG_CERT")) cout <<
"Generating RSA key..." << endl;
208 EVP_PKEY *pkey = generate_key();
212 if (getenv(
"OCPN_DEBUG_CERT"))
213 cout <<
"Generating x509 certificate..." << endl;
215 X509 *x509 = generate_x509(pkey, ipv4);
222 if (getenv(
"OCPN_DEBUG_CERT"))
223 cout <<
"Writing key and certificate to disk..." << endl;
225 bool ret = write_to_disk(pkey, x509, destination_dir);
230 if (getenv(
"OCPN_DEBUG_CERT")) cout <<
"Success!" << endl;
Enhanced logging interface on top of wx/log.h.