From b3000495c05ff40d848f6357974cd4d5294a66c2 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 24 May 2021 13:28:47 +0200 Subject: Handle errors with more care when creating certificates. --- src/analysis/db/certs.c | 96 ++++++++++++++++++++++++++++------------------ tests/analysis/db/certs.py | 4 +- 2 files changed, 60 insertions(+), 40 deletions(-) diff --git a/src/analysis/db/certs.c b/src/analysis/db/certs.c index dabc127..11d12fd 100644 --- a/src/analysis/db/certs.c +++ b/src/analysis/db/certs.c @@ -255,6 +255,7 @@ static RSA *generate_rsa_key(unsigned int bits, unsigned long e) bool build_keys_and_ca(const char *dir, const char *label, unsigned long valid, const x509_entries *entries) { + bool result; /* Bilan à retourner */ RSA *rsa; /* Clef RSA pour le certificat */ EVP_PKEY *pk; /* Enveloppe pour clef publique*/ int ret; /* Bilan d'un appel */ @@ -263,20 +264,30 @@ bool build_keys_and_ca(const char *dir, const char *label, unsigned long valid, char *filename; /* Chemin d'accès à un fichier */ FILE *stream; /* Flux ouvert en écriture */ + result = false; + rsa = generate_rsa_key(4096, 17); if (rsa == NULL) goto rsa_failed; pk = EVP_PKEY_new(); - if (pk == NULL) goto pk_failed; + if (pk == NULL) + { + RSA_free(rsa); + goto pk_failed; + } ret = EVP_PKEY_assign_RSA(pk, rsa); - if (ret != 1) goto asign_failed; + if (ret != 1) + { + RSA_free(rsa); + goto asign_failed; + } x509 = X509_new(); if (x509 == NULL) goto x509_failed; ret = X509_set_pubkey(x509, pk); - if (ret != 1) goto ca_failed; + if (ret != 1) goto ca_asign_failed; ret = X509_set_version(x509, 2); if (ret != 1) goto ca_failed; @@ -344,7 +355,11 @@ bool build_keys_and_ca(const char *dir, const char *label, unsigned long valid, asprintf(&filename, "%s%c%s-key.pem", dir, G_DIR_SEPARATOR, label); stream = fopen(filename, "wb"); - if (stream == NULL) goto ca_failed; + if (stream == NULL) + { + free(filename); + goto ca_failed; + } ret = PEM_write_PrivateKey(stream, pk, NULL, NULL, 0, NULL, NULL); @@ -361,7 +376,11 @@ bool build_keys_and_ca(const char *dir, const char *label, unsigned long valid, asprintf(&filename, "%s%c%s-cert.pem", dir, G_DIR_SEPARATOR, label); stream = fopen(filename, "wb"); - if (stream == NULL) goto ca_failed; + if (stream == NULL) + { + free(filename); + goto ca_failed; + } ret = PEM_write_X509(stream, x509); @@ -375,34 +394,24 @@ bool build_keys_and_ca(const char *dir, const char *label, unsigned long valid, if (ret != 1) goto ca_failed; - /* Libérations finales */ - - X509_free(x509); - EVP_PKEY_free(pk); + result = true; - return true; + /* Libérations finales */ ca_failed: + ca_asign_failed: X509_free(x509); x509_failed: - - EVP_PKEY_free(pk); - - return false; - asign_failed: EVP_PKEY_free(pk); pk_failed: - - RSA_free(rsa); - rsa_failed: - return false; + return result; } @@ -458,6 +467,7 @@ static bool add_extension_to_req(STACK_OF(X509_EXTENSION) *sk, int nid, /*const bool build_keys_and_request(const char *dir, const char *label, const x509_entries *entries) { + bool result; /* Bilan à retourner */ RSA *rsa; /* Clef RSA pour le certificat */ EVP_PKEY *pk; /* Enveloppe pour clef publique*/ int ret; /* Bilan d'un appel */ @@ -467,20 +477,30 @@ bool build_keys_and_request(const char *dir, const char *label, const x509_entri char *filename; /* Chemin d'accès à un fichier */ FILE *stream; /* Flux ouvert en écriture */ + result = false; + rsa = generate_rsa_key(2048, 17); if (rsa == NULL) goto rsa_failed; pk = EVP_PKEY_new(); - if (pk == NULL) goto pk_failed; + if (pk == NULL) + { + RSA_free(rsa); + goto pk_failed; + } ret = EVP_PKEY_assign_RSA(pk, rsa); - if (ret != 1) goto asign_failed; + if (ret != 1) + { + RSA_free(rsa); + goto asign_failed; + } x509 = X509_REQ_new(); if (x509 == NULL) goto x509_failed; ret = X509_REQ_set_pubkey(x509, pk); - if (ret != 1) goto asign_failed; + if (ret != 1) goto req_asign_failed; /* Etablissement d'une identité */ @@ -523,8 +543,6 @@ bool build_keys_and_request(const char *dir, const char *label, const x509_entri ret = X509_REQ_add_extensions(x509, exts); if (ret != 1) goto exts_failed; - sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); - /* Signature */ ret = X509_REQ_sign(x509, pk, EVP_sha256()); @@ -538,7 +556,11 @@ bool build_keys_and_request(const char *dir, const char *label, const x509_entri asprintf(&filename, "%s%c%s-key.pem", dir, G_DIR_SEPARATOR, label); stream = fopen(filename, "wb"); - if (stream == NULL) goto req_failed_2; + if (stream == NULL) + { + free(filename); + goto req_failed_2; + } ret = PEM_write_PrivateKey(stream, pk, NULL, NULL, 0, NULL, NULL); @@ -555,7 +577,11 @@ bool build_keys_and_request(const char *dir, const char *label, const x509_entri asprintf(&filename, "%s%c%s-csr.pem", dir, G_DIR_SEPARATOR, label); stream = fopen(filename, "wb"); - if (stream == NULL) goto req_failed_2; + if (stream == NULL) + { + free(filename); + goto req_failed_2; + } ret = PEM_write_X509_REQ(stream, x509); @@ -569,35 +595,29 @@ bool build_keys_and_request(const char *dir, const char *label, const x509_entri if (ret != 1) goto req_failed_2; - return true; + result = true; - req_failed_2: + /* Libérations finales */ + req_failed_2: exts_failed: - sk_X509_EXTENSION_free(exts); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); req_failed: + req_asign_failed: X509_REQ_free(x509); x509_failed: - - EVP_PKEY_free(pk); - - return false; - asign_failed: EVP_PKEY_free(pk); pk_failed: - - RSA_free(rsa); - rsa_failed: - return false; + return result; } diff --git a/tests/analysis/db/certs.py b/tests/analysis/db/certs.py index ead768e..dcf7d71 100644 --- a/tests/analysis/db/certs.py +++ b/tests/analysis/db/certs.py @@ -58,7 +58,7 @@ class TestRestrictedContent(ChrysalideTestCase): } - ret = certs.make_ca(self._tmppath, 'ca', 3650 * 24 * 60 * 60, identity) + ret = certs.build_keys_and_ca(self._tmppath, 'ca', 3650 * 24 * 60 * 60, identity) self.assertTrue(ret) cmd = 'openssl x509 -in %s/ca-cert.pem -subject -noout' % self._tmppath @@ -85,7 +85,7 @@ class TestRestrictedContent(ChrysalideTestCase): } - ret = certs.make_request(self._tmppath, 'server', identity); + ret = certs.build_keys_and_request(self._tmppath, 'server', identity); self.assertTrue(ret) -- cgit v0.11.2-87-g4458