Rewrite
This commit is contained in:
+140
@@ -0,0 +1,140 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
static EVP_PKEY *generate_rsa_key_pair(int key_bits)
|
||||
{
|
||||
EVP_PKEY_CTX *ctx;
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
// Create the context for key generation
|
||||
ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
if (EVP_PKEY_keygen_init(ctx) <= 0) {
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, key_bits) <= 0) {
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_keygen(ctx, &pkey) <= 0) {
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return pkey;
|
||||
}
|
||||
|
||||
static X509 *create_certificate(EVP_PKEY *pkey, HTTP_String C, HTTP_String O, HTTP_String CN, int days)
|
||||
{
|
||||
X509 *x509 = X509_new();
|
||||
if (!x509)
|
||||
return NULL;
|
||||
|
||||
// Set version (version 3)
|
||||
X509_set_version(x509, 2);
|
||||
|
||||
// Set serial number
|
||||
ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
|
||||
|
||||
// Set validity period
|
||||
X509_gmtime_adj(X509_get_notBefore(x509), 0);
|
||||
X509_gmtime_adj(X509_get_notAfter(x509), 31536000L * days); // days * seconds_per_year
|
||||
|
||||
// Set public key
|
||||
X509_set_pubkey(x509, pkey);
|
||||
|
||||
// Set subject name
|
||||
X509_NAME *name = X509_get_subject_name(x509);
|
||||
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char*) C.ptr, C.len, -1, 0);
|
||||
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char*) O.ptr, O.len, -1, 0);
|
||||
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char*) CN.ptr, CN.len, -1, 0);
|
||||
|
||||
// Set issuer name (same as subject for self-signed)
|
||||
X509_set_issuer_name(x509, name);
|
||||
|
||||
if (!X509_sign(x509, pkey, EVP_sha256())) {
|
||||
X509_free(x509);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return x509;
|
||||
}
|
||||
|
||||
static int save_private_key(EVP_PKEY *pkey, const char *filename)
|
||||
{
|
||||
FILE *fp = fopen(filename, "wb");
|
||||
if (!fp)
|
||||
return -1;
|
||||
|
||||
// Write private key in PEM format
|
||||
if (!PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL)) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cert_save(X509 *x509, const char *filename)
|
||||
{
|
||||
FILE *fp = fopen(filename, "wb");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Error opening file for certificate: %s\n", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Write certificate in PEM format
|
||||
if (!PEM_write_X509(fp, x509)) {
|
||||
fprintf(stderr, "Error writing certificate\n");
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
printf("Certificate saved to: %s\n", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int http_create_test_certificate(HTTP_String C, HTTP_String O, HTTP_String CN,
|
||||
HTTP_String cert_file, HTTP_String key_file)
|
||||
{
|
||||
EVP_PKEY *pkey = generate_rsa_key_pair(2048);
|
||||
if (pkey == NULL)
|
||||
return -1;
|
||||
|
||||
X509 *x509 = create_certificate(pkey, C, O, CN, 1)
|
||||
if (x509 == NULL) {
|
||||
EVP_PKEY_free(pkey);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (save_private_key(pkey, key_file) < 0) {
|
||||
X509_free(x509);
|
||||
EVP_PKEY_free(pkey);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (save_certificate(x509, cert_file) < 0) {
|
||||
X509_free(x509);
|
||||
EVP_PKEY_free(pkey);
|
||||
return -1;
|
||||
}
|
||||
|
||||
X509_free(x509);
|
||||
EVP_PKEY_free(pkey);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user