From 87530e9ebc872761c06506f3cb6a4fa5c494a614 Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Tue, 7 Jan 2020 14:32:01 -0500 Subject: [PATCH 10/10] Better validation of command line arguments Check that key passphrases are within 4-1023 characters OpenSSL CLI tools cannot handle files with passphrases outside this range. Resolves: rhbz#1784441 Signed-off-by: Stephen Gallagher Output private keys with 2048 iteration count Signed-off-by: Stephen Gallagher Rework passphrase handling Handle passphrases as part of the sscg_stream for a file. This will allow us to check for relevance as well as reducing code duplication. Resolves: rhbz#1784443 Signed-off-by: Stephen Gallagher Fix wrong x509 version in CSR This was, fortunately, not causing any problems because the signing process resulted in the certificates being generated with the correct version. It's best to be correct anyway. Signed-off-by: Stephen Gallagher Fix memory leaks Signed-off-by: Stephen Gallagher Fix alignment issue with popt The boolean values need to be explicitly defined as int because a bool may not be aligned properly. It was working prior to some recent changes by lucky accident. Signed-off-by: Stephen Gallagher Prevent uninitialized read error Signed-off-by: Stephen Gallagher Add missing newline for error message Signed-off-by: Stephen Gallagher Fix OpenSSL 1.0 support The symbol UI_F_UI_SET_RESULT changed to UI_F_UI_SET_RESULT_EX in OpenSSL 1.1, but no other semantics changed that we care about. Signed-off-by: Stephen Gallagher Fix formatting Signed-off-by: Stephen Gallagher Fix missing error check Signed-off-by: Stephen Gallagher Read long password files properly Long passphrase files may require more than a single call to BIO_read() to gather the whole string. Signed-off-by: Stephen Gallagher --- include/io_utils.h | 37 ++++++- include/key.h | 6 +- include/sscg.h | 42 +++++--- include/x509.h | 6 +- meson.build | 1 + src/io_utils.c | 199 ++++++++++++++++++++++++++++++++++++- src/sscg.c | 239 +++++++-------------------------------------- src/x509.c | 6 +- 8 files changed, 310 insertions(+), 226 deletions(-) diff --git a/include/io_utils.h b/include/io_utils.h index 6a89a476b3d982447b6603153c6765835cd67464..907097c7ff1f7ae3c3adf35d0dfba0f5763dc8c0 100644 --- a/include/io_utils.h +++ b/include/io_utils.h @@ -24,6 +24,7 @@ #include #include +#include "include/key.h" #include "include/sscg.h" @@ -33,6 +34,9 @@ struct sscg_stream char *path; int mode; int filetypes; + + bool pass_prompt; + char *passphrase; }; @@ -69,8 +73,6 @@ sscg_io_utils_get_path_by_type (struct sscg_stream **streams, * @path: The path to the file on disk. * @mode: The filesystem mode this file should have when written to disk. * See chmod(1) for the possible values. - * @overwrite: If true, replace any existing file at @normalized_path. If - * false, opening will fail if it already exists and return an error. * * Prepares all output filenames to be opened. Files are not created until * sscg_io_utils_open_output_files() is called. @@ -82,9 +84,40 @@ sscg_io_utils_add_output_file (struct sscg_stream **streams, int mode); +/** + * sscg_io_utils_add_output_key: + * @streams: The array of streams from the sscg_options + * @filetype: + * @path: The path to the file on disk. + * @mode: The filesystem mode this file should have when written to disk. + * See chmod(1) for the possible values. + * @pass_prompt: Whether the user should be prompted to enter a passphrase + * interactively. + * @passphrase: The passphrase supplied at the command line. + * @passfile: The path to a file containing the passphrase. + * + * Prepares all output filenames to be opened. Files are not created until + * sscg_io_utils_open_output_files() is called. + */ +int +sscg_io_utils_add_output_key (struct sscg_stream **streams, + enum sscg_file_type filetype, + const char *path, + int mode, + bool pass_prompt, + char *passphrase, + char *passfile); + + int sscg_io_utils_open_output_files (struct sscg_stream **streams, bool overwrite); +int +sscg_io_utils_write_privatekey (struct sscg_stream **streams, + enum sscg_file_type filetype, + struct sscg_evp_pkey *key, + struct sscg_options *options); + /* If this function fails, some of the output files may be left as 0400 */ int sscg_io_utils_finalize_output_files (struct sscg_stream **streams); diff --git a/include/key.h b/include/key.h index ef871d6937e2fc805a445d6686263b023a38eaaa..4c32cad04950ee7fd75ec4144147eb919280c00a 100644 --- a/include/key.h +++ b/include/key.h @@ -17,15 +17,15 @@ Copyright 2017 by Stephen Gallagher */ +#ifndef _SSCG_KEY_H +#define _SSCG_KEY_H + #include #include #include "include/sscg.h" #include "include/bignum.h" -#ifndef _SSCG_KEY_H -#define _SSCG_KEY_H - struct sscg_evp_pkey { EVP_PKEY *evp_pkey; diff --git a/include/sscg.h b/include/sscg.h index 2744404c25c68ed905ca621bb955e0c04b33ca81..96b78152ccc492deafbbc61eb98702562a8fe5e6 100644 --- a/include/sscg.h +++ b/include/sscg.h @@ -20,17 +20,18 @@ /* This is a master header file that should be included by all sscg source files. */ + +#ifndef _SSCG_H +#define _SSCG_H + #include #include #include +#include #include #include #include -#include "include/io_utils.h" - -#ifndef _SSCG_H -#define _SSCG_H /* TODO: implement internationalization */ @@ -81,15 +82,34 @@ } \ while (0) +/* The function changed in 1.1, but the library and reason names did not */ +#ifndef UI_F_UI_SET_RESULT_EX +#define UI_F_UI_SET_RESULT_EX UI_F_UI_SET_RESULT +#endif + #define CHECK_SSL(_sslret, _fn) \ do \ { \ if (_sslret != 1) \ { \ /* Get information about error from OpenSSL */ \ + unsigned long _ssl_error = ERR_get_error (); \ + if ((ERR_GET_LIB (_ssl_error) == ERR_LIB_UI) && \ + (ERR_GET_FUNC (_ssl_error) == UI_F_UI_SET_RESULT_EX) && \ + ((ERR_GET_REASON (_ssl_error) == UI_R_RESULT_TOO_LARGE) || \ + (ERR_GET_REASON (_ssl_error) == UI_R_RESULT_TOO_SMALL))) \ + { \ + fprintf ( \ + stderr, \ + "Passphrases must be between %d and %d characters. \n", \ + SSCG_MIN_KEY_PASS_LEN, \ + SSCG_MAX_KEY_PASS_LEN); \ + ret = EINVAL; \ + goto done; \ + } \ fprintf (stderr, \ "Error occurred in " #_fn ": [%s].\n", \ - ERR_error_string (ERR_get_error (), NULL)); \ + ERR_error_string (_ssl_error, NULL)); \ ret = EIO; \ goto done; \ } \ @@ -223,12 +243,9 @@ struct sscg_options const EVP_CIPHER *cipher; const EVP_MD *hash_fn; - bool ca_key_pass_prompt; - char *ca_key_pass; - bool cert_key_pass_prompt; - char *cert_key_pass; - bool client_key_pass_prompt; - char *client_key_pass; + int ca_key_pass_prompt; + int cert_key_pass_prompt; + int client_key_pass_prompt; /* Output Files */ struct sscg_stream **streams; @@ -251,4 +268,7 @@ enum sscg_cert_type SSCG_NUM_CERT_TYPES }; +#define SSCG_MIN_KEY_PASS_LEN 4 +#define SSCG_MAX_KEY_PASS_LEN 1023 + #endif /* _SSCG_H */ diff --git a/include/x509.h b/include/x509.h index 865cd0018d3ea77915cd86349e333ae6f4de2af0..cc7e498d06c4d2e503d7d8748dfd5386f9ad0794 100644 --- a/include/x509.h +++ b/include/x509.h @@ -17,6 +17,9 @@ Copyright 2017 by Stephen Gallagher */ +#ifndef _SSCG_X509_H +#define _SSCG_X509_H + #include #include @@ -24,9 +27,6 @@ #include "include/bignum.h" #include "include/key.h" -#ifndef _SSCG_X509_H -#define _SSCG_X509_H - struct sscg_cert_info { /* === Input Data === */ diff --git a/meson.build b/meson.build index eb339ea8c768adab6d576736fbe476b83529e78d..3d8937ce73dc84f652f6fdad461a1468a532f0f2 100644 --- a/meson.build +++ b/meson.build @@ -76,6 +76,7 @@ sscg_lib_hdrs = [ 'include/dhparams.h', 'include/io_utils.h', 'include/key.h', + 'include/sscg.h', 'include/x509.h', ] diff --git a/src/io_utils.c b/src/io_utils.c index a2502afb20f4bcb536428f3528900c2bb06997f5..1b8bc41c3849acbe4657ae14dfe55e3010957129 100644 --- a/src/io_utils.c +++ b/src/io_utils.c @@ -24,8 +24,14 @@ #include #include "include/io_utils.h" +#include "include/key.h" #include "include/sscg.h" + +/* Same as OpenSSL CLI */ +#define MAX_PW_LEN 1024 + + int sscg_normalize_path (TALLOC_CTX *mem_ctx, const char *path, @@ -62,6 +68,12 @@ sscg_stream_destructor (TALLOC_CTX *ptr) BIO_free (stream->bio); + /* Zero out the memory before freeing it so we don't leak passwords */ + if (stream->passphrase) + { + memset (stream->passphrase, 0, strnlen (stream->passphrase, MAX_PW_LEN)); + } + return 0; } @@ -147,11 +159,101 @@ sscg_io_utils_get_path_by_type (struct sscg_stream **streams, } +/* This function takes a copy of a string into a talloc hierarchy and memsets + * the original string to zeroes to avoid leaking it when that memory is freed. + */ +static char * +sscg_secure_string_steal (TALLOC_CTX *mem_ctx, char *src) +{ + char *dest = talloc_strdup (mem_ctx, src); + + memset ((void *)src, 0, strlen (src)); + + return dest; +} + + +static int +validate_passphrase (struct sscg_stream *stream) +{ + /* Ignore non-key types */ + if (!(stream->filetypes & SSCG_FILE_TYPE_KEYS)) + return EOK; + + /* Ignore unset passwords; these will be prompted for when writing out the + * key file + */ + if (!stream->passphrase) + return EOK; + + size_t pass_len = strnlen (stream->passphrase, SSCG_MAX_KEY_PASS_LEN + 1); + + if ((pass_len < SSCG_MIN_KEY_PASS_LEN) || (pass_len > SSCG_MAX_KEY_PASS_LEN)) + { + SSCG_ERROR ("Passphrases must be between %d and %d characters. \n", + SSCG_MIN_KEY_PASS_LEN, + SSCG_MAX_KEY_PASS_LEN); + return EINVAL; + } + return EOK; +} + + +static char * +sscg_read_pw_file (TALLOC_CTX *mem_ctx, char *path) +{ + int i; + BIO *pwdbio = NULL; + char tpass[MAX_PW_LEN + 1]; + int offset = 0; + char *tmp = NULL; + char *password = NULL; + + pwdbio = BIO_new_file (path, "r"); + if (pwdbio == NULL) + { + fprintf (stderr, "Can't open file %s\n", path); + return NULL; + } + + /* Read up to one more character than the MAX_PW_LEN */ + for (offset = 0; + (i = BIO_read (pwdbio, tpass + offset, MAX_PW_LEN + 1 - offset)) > 0 && + offset < (MAX_PW_LEN + 1); + offset += i) + ; + + tpass[MAX_PW_LEN] = '\0'; + + BIO_free_all (pwdbio); + pwdbio = NULL; + + if (i < 0) + { + fprintf (stderr, "Error reading password from BIO\n"); + return NULL; + } + + tmp = strchr (tpass, '\n'); + if (tmp != NULL) + *tmp = 0; + + password = talloc_strdup (mem_ctx, tpass); + + memset (tpass, 0, MAX_PW_LEN + 1); + + return password; +} + + int -sscg_io_utils_add_output_file (struct sscg_stream **streams, - enum sscg_file_type filetype, - const char *path, - int mode) +sscg_io_utils_add_output_key (struct sscg_stream **streams, + enum sscg_file_type filetype, + const char *path, + int mode, + bool pass_prompt, + char *passphrase, + char *passfile) { int ret, i; TALLOC_CTX *tmp_ctx = NULL; @@ -163,6 +265,22 @@ sscg_io_utils_add_output_file (struct sscg_stream **streams, */ if (path == NULL) { + if (pass_prompt) + { + SSCG_ERROR ( + "Passphrase prompt requested for %s, but no file path provided.\n", + sscg_get_file_type_name (filetype)); + return EINVAL; + } + + if (passphrase) + { + SSCG_ERROR ( + "Passphrase provided for %s, but no file path provided.\n", + sscg_get_file_type_name (filetype)); + return EINVAL; + } + SSCG_LOG (SSCG_DEBUG, "Got a NULL path with filetype: %s\n", sscg_get_file_type_name (filetype)); @@ -220,6 +338,31 @@ sscg_io_utils_add_output_file (struct sscg_stream **streams, /* Add the file type */ stream->filetypes |= (1 << filetype); + + /* Set the password options */ + stream->pass_prompt = pass_prompt; + + if (passphrase) + { + stream->passphrase = sscg_secure_string_steal (stream, passphrase); + ret = validate_passphrase (stream); + if (ret != EOK) + goto done; + } + else if (passfile) + { + stream->passphrase = sscg_read_pw_file (stream, passfile); + if (!stream->passphrase) + { + fprintf (stderr, "Failed to read passphrase from %s", passfile); + ret = EIO; + goto done; + } + } + ret = validate_passphrase (stream); + if (ret != EOK) + goto done; + ret = EOK; done: @@ -228,6 +371,17 @@ done: } +int +sscg_io_utils_add_output_file (struct sscg_stream **streams, + enum sscg_file_type filetype, + const char *path, + int mode) +{ + return sscg_io_utils_add_output_key ( + streams, filetype, path, mode, false, NULL, NULL); +} + + enum io_utils_errors { IO_UTILS_OK = 0, @@ -400,6 +554,43 @@ done: } +int +sscg_io_utils_write_privatekey (struct sscg_stream **streams, + enum sscg_file_type filetype, + struct sscg_evp_pkey *key, + struct sscg_options *options) +{ + int ret, sret; + + struct sscg_stream *stream = + sscg_io_utils_get_stream_by_type (streams, filetype); + if (stream) + { + /* This function has a default mechanism for prompting for the + * password if it is passed a cipher and gets a NULL password. + * + * Only pass the cipher if we have a password or were instructed + * to prompt for one. + */ + sret = PEM_write_bio_PKCS8PrivateKey ( + stream->bio, + key->evp_pkey, + stream->pass_prompt || stream->passphrase ? options->cipher : NULL, + stream->passphrase, + stream->passphrase ? strlen (stream->passphrase) : 0, + NULL, + NULL); + CHECK_SSL (sret, PEM_write_bio_PKCS8PrivateKey); + ANNOUNCE_WRITE (filetype); + } + + ret = EOK; + +done: + return ret; +} + + int sscg_io_utils_finalize_output_files (struct sscg_stream **streams) { diff --git a/src/sscg.c b/src/sscg.c index 4d009a67488e83c4332f58ee52f7d6ea72a8ddbd..96a9be1232d890590e97c126f8f4a78d571d7247 100644 --- a/src/sscg.c +++ b/src/sscg.c @@ -18,6 +18,7 @@ */ #define _GNU_SOURCE +#include #include #include #include @@ -40,9 +41,6 @@ int verbosity; -/* Same as OpenSSL CLI */ -#define MAX_PW_LEN 1024 - static int get_security_level (void) { @@ -140,79 +138,6 @@ print_options (struct sscg_options *opts) } -/* This function takes a copy of a string into a talloc hierarchy and memsets - * the original string to zeroes to avoid leaking it when that memory is freed. - */ -static char * -sscg_secure_string_steal (TALLOC_CTX *mem_ctx, char *src) -{ - char *dest = talloc_strdup (mem_ctx, src); - - memset (src, 0, strlen (src)); - - return dest; -} - - -static int -sscg_options_destructor (TALLOC_CTX *opts) -{ - struct sscg_options *options = - talloc_get_type_abort (opts, struct sscg_options); - - /* Zero out the memory before freeing it so we don't leak passwords */ - if (options->ca_key_pass) - { - memset (options->ca_key_pass, 0, strlen (options->ca_key_pass)); - } - - if (options->cert_key_pass) - { - memset (options->cert_key_pass, 0, strlen (options->cert_key_pass)); - } - - return 0; -} - - -static char * -sscg_read_pw_file (TALLOC_CTX *mem_ctx, char *path) -{ - int i; - BIO *pwdbio = NULL; - char tpass[MAX_PW_LEN]; - char *tmp = NULL; - char *password = NULL; - - pwdbio = BIO_new_file (path, "r"); - if (pwdbio == NULL) - { - fprintf (stderr, "Can't open file %s\n", path); - return NULL; - } - - i = BIO_gets (pwdbio, tpass, MAX_PW_LEN); - BIO_free_all (pwdbio); - pwdbio = NULL; - - if (i <= 0) - { - fprintf (stderr, "Error reading password from BIO\n"); - return NULL; - } - - tmp = strchr (tpass, '\n'); - if (tmp != NULL) - *tmp = 0; - - password = talloc_strdup (mem_ctx, tpass); - - memset (tpass, 0, MAX_PW_LEN); - - return password; -} - - const char * sscg_get_verbosity_name (enum sscg_verbosity type) { @@ -310,12 +235,14 @@ main (int argc, const char **argv) struct sscg_evp_pkey *cakey; struct sscg_x509_cert *svc_cert; struct sscg_evp_pkey *svc_key; - struct sscg_x509_cert *client_cert; - struct sscg_evp_pkey *client_key; + struct sscg_x509_cert *client_cert = NULL; + struct sscg_evp_pkey *client_key = NULL; int dhparams_mode = SSCG_CERT_DEFAULT_MODE; struct sscg_dhparams *dhparams = NULL; + struct sscg_stream *stream = NULL; + /* Always use umask 0577 for generating certificates and keys This means that it's opened as write-only by the effective user. */ @@ -335,7 +262,6 @@ main (int argc, const char **argv) options = talloc_zero (main_ctx, struct sscg_options); CHECK_MEM (options); - talloc_set_destructor ((TALLOC_CTX *)options, sscg_options_destructor); options->streams = talloc_zero_array (options, struct sscg_stream *, SSCG_NUM_FILE_TYPES); @@ -965,56 +891,6 @@ main (int argc, const char **argv) } } - /* Password handling */ - if (ca_key_password) - { - options->ca_key_pass = - sscg_secure_string_steal (options, ca_key_password); - } - else if (ca_key_passfile) - { - options->ca_key_pass = sscg_read_pw_file (options, ca_key_passfile); - if (!options->ca_key_pass) - { - fprintf ( - stderr, "Failed to read passphrase from %s", ca_key_passfile); - goto done; - } - } - - if (cert_key_password) - { - options->cert_key_pass = - sscg_secure_string_steal (options, cert_key_password); - } - else if (cert_key_passfile) - { - options->cert_key_pass = sscg_read_pw_file (options, cert_key_passfile); - if (!options->cert_key_pass) - { - fprintf ( - stderr, "Failed to read passphrase from %s", cert_key_passfile); - goto done; - } - } - - if (client_key_password) - { - options->client_key_pass = - sscg_secure_string_steal (options, client_key_password); - } - else if (client_key_passfile) - { - options->client_key_pass = - sscg_read_pw_file (options, client_key_passfile); - if (!options->client_key_pass) - { - fprintf ( - stderr, "Failed to read passphrase from %s", client_key_passfile); - goto done; - } - } - if (options->key_strength < options->minimum_key_strength) { fprintf (stderr, @@ -1055,8 +931,13 @@ main (int argc, const char **argv) ca_mode); CHECK_OK (ret); - ret = sscg_io_utils_add_output_file ( - options->streams, SSCG_FILE_TYPE_CA_KEY, ca_key_file, ca_key_mode); + ret = sscg_io_utils_add_output_key (options->streams, + SSCG_FILE_TYPE_CA_KEY, + ca_key_file, + ca_key_mode, + options->ca_key_pass_prompt, + ca_key_password, + ca_key_passfile); CHECK_OK (ret); ret = sscg_io_utils_add_output_file (options->streams, @@ -1065,11 +946,14 @@ main (int argc, const char **argv) cert_mode); CHECK_OK (ret); - ret = sscg_io_utils_add_output_file (options->streams, - SSCG_FILE_TYPE_SVC_KEY, - cert_key_file ? cert_key_file : - "./service-key.pem", - cert_key_mode); + ret = sscg_io_utils_add_output_key (options->streams, + SSCG_FILE_TYPE_SVC_KEY, + cert_key_file ? cert_key_file : + "./service-key.pem", + cert_key_mode, + options->cert_key_pass_prompt, + cert_key_password, + cert_key_passfile); CHECK_OK (ret); @@ -1078,11 +962,14 @@ main (int argc, const char **argv) CHECK_OK (ret); - ret = sscg_io_utils_add_output_file (options->streams, - SSCG_FILE_TYPE_CLIENT_KEY, - client_key_file ? client_key_file : - client_file, - client_key_mode); + ret = sscg_io_utils_add_output_key (options->streams, + SSCG_FILE_TYPE_CLIENT_KEY, + client_key_file ? client_key_file : + client_file, + client_key_mode, + options->client_key_pass_prompt, + client_key_password, + client_key_passfile); CHECK_OK (ret); ret = sscg_io_utils_add_output_file ( @@ -1136,67 +1023,17 @@ main (int argc, const char **argv) /* Write private keys first */ - if (build_client_cert) - { - /* This function has a default mechanism for prompting for the - * password if it is passed a cipher and gets a NULL password. - * - * Only pass the cipher if we have a password or were instructed - * to prompt for one. - */ - sret = PEM_write_bio_PrivateKey ( - GET_BIO (SSCG_FILE_TYPE_CLIENT_KEY), - client_key->evp_pkey, - options->client_key_pass_prompt || options->client_key_pass ? - options->cipher : - NULL, - (unsigned char *)options->client_key_pass, - options->client_key_pass ? strlen (options->client_key_pass) : 0, - NULL, - NULL); - CHECK_SSL (sret, PEM_write_bio_PrivateKey (svc)); - ANNOUNCE_WRITE (SSCG_FILE_TYPE_SVC_KEY); - } + ret = sscg_io_utils_write_privatekey ( + options->streams, SSCG_FILE_TYPE_CLIENT_KEY, client_key, options); + CHECK_OK (ret); - /* This function has a default mechanism for prompting for the - * password if it is passed a cipher and gets a NULL password. - * - * Only pass the cipher if we have a password or were instructed - * to prompt for one. - */ - sret = PEM_write_bio_PrivateKey ( - GET_BIO (SSCG_FILE_TYPE_SVC_KEY), - svc_key->evp_pkey, - options->cert_key_pass_prompt || options->cert_key_pass ? options->cipher : - NULL, - (unsigned char *)options->cert_key_pass, - options->cert_key_pass ? strlen (options->cert_key_pass) : 0, - NULL, - NULL); - CHECK_SSL (sret, PEM_write_bio_PrivateKey (svc)); - ANNOUNCE_WRITE (SSCG_FILE_TYPE_SVC_KEY); + ret = sscg_io_utils_write_privatekey ( + options->streams, SSCG_FILE_TYPE_SVC_KEY, svc_key, options); + CHECK_OK (ret); - /* Create CA private key, if requested */ - if (GET_BIO (SSCG_FILE_TYPE_CA_KEY)) - { - /* This function has a default mechanism for prompting for the - * password if it is passed a cipher and gets a NULL password. - * - * Only pass the cipher if we have a password or were instructed - * to prompt for one. - */ - sret = PEM_write_bio_PrivateKey ( - GET_BIO (SSCG_FILE_TYPE_CA_KEY), - cakey->evp_pkey, - options->ca_key_pass_prompt || options->ca_key_pass ? options->cipher : - NULL, - (unsigned char *)options->ca_key_pass, - options->ca_key_pass ? strlen (options->ca_key_pass) : 0, - NULL, - NULL); - CHECK_SSL (sret, PEM_write_bio_PrivateKey (CA)); - ANNOUNCE_WRITE (SSCG_FILE_TYPE_CA_KEY); - } + ret = sscg_io_utils_write_privatekey ( + options->streams, SSCG_FILE_TYPE_CA_KEY, cakey, options); + CHECK_OK (ret); /* Public keys come next, in chain order */ @@ -1217,7 +1054,7 @@ main (int argc, const char **argv) /* Create CA public certificate */ - struct sscg_stream *stream = + stream = sscg_io_utils_get_stream_by_type (options->streams, SSCG_FILE_TYPE_CA); sret = PEM_write_bio_X509 (stream->bio, cacert->certificate); CHECK_SSL (sret, PEM_write_bio_X509 (CA)); diff --git a/src/x509.c b/src/x509.c index c173f539791fbbc51e52e6b121e587dca43924d4..42315d42d1e03460a8121e1592d8e7fcc0fef1df 100644 --- a/src/x509.c +++ b/src/x509.c @@ -72,7 +72,7 @@ _sscg_certinfo_destructor (TALLOC_CTX *ctx) struct sscg_cert_info *certinfo = talloc_get_type_abort (ctx, struct sscg_cert_info); - sk_X509_EXTENSION_free (certinfo->extensions); + sk_X509_EXTENSION_pop_free (certinfo->extensions, X509_EXTENSION_free); return 0; } @@ -155,7 +155,7 @@ sscg_x509v3_csr_new (TALLOC_CTX *mem_ctx, talloc_set_destructor ((TALLOC_CTX *)csr, _sscg_csr_destructor); /* We will generate only x509v3 certificates */ - sslret = X509_REQ_set_version (csr->x509_req, 3); + sslret = X509_REQ_set_version (csr->x509_req, 2); CHECK_SSL (sslret, X509_REQ_set_version); subject = X509_REQ_get_subject_name (csr->x509_req); @@ -461,6 +461,8 @@ sscg_sign_x509_csr (TALLOC_CTX *mem_ctx, } sslret = X509_add_ext (cert, ext, -1); CHECK_SSL (sslret, X509_add_ext); + + X509_EXTENSION_free (ext); } /* Sign the new certificate */ -- 2.24.1