Auto sync2gitlab import of sscg-3.0.0-5.el8.src.rpm
This commit is contained in:
		
							parent
							
								
									216ca0ae9c
								
							
						
					
					
						commit
						a8c31b9e2f
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1 +1,2 @@ | ||||
| /sscg-2.3.3-stripped.tar.xz | ||||
| /sscg-3.0.0.tar.xz | ||||
|  | ||||
							
								
								
									
										34
									
								
								0001-Drop-usage-of-ERR_GET_FUNC.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								0001-Drop-usage-of-ERR_GET_FUNC.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| From d2277e711bb16e3b98f43565e71b7865b5fed423 Mon Sep 17 00:00:00 2001 | ||||
| From: Stephen Gallagher <sgallagh@redhat.com> | ||||
| Date: Sat, 7 Aug 2021 11:48:04 -0400 | ||||
| Subject: [PATCH 1/2] Drop usage of ERR_GET_FUNC() | ||||
| 
 | ||||
| This macro was dropped in OpenSSL 3.0 and has actually not been | ||||
| providing a valid return code for some time. | ||||
| 
 | ||||
| Related: rhbz#1964837 | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| ---
 | ||||
|  include/sscg.h | 1 - | ||||
|  1 file changed, 1 deletion(-) | ||||
| 
 | ||||
| diff --git a/include/sscg.h b/include/sscg.h
 | ||||
| index faf86ba4f68e186bd35c7bc3ec77b98b8e37d253..851dc93175607e5223a70ef40a5feb24b7b69215 100644
 | ||||
| --- a/include/sscg.h
 | ||||
| +++ b/include/sscg.h
 | ||||
| @@ -94,11 +94,10 @@
 | ||||
|        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,                                                       \ | ||||
| -- 
 | ||||
| 2.33.0 | ||||
| 
 | ||||
| @ -1,50 +0,0 @@ | ||||
| From b0157a6a4c5385dfe720d7eb2f91a473ab0bd592 Mon Sep 17 00:00:00 2001 | ||||
| From: Stephen Gallagher <sgallagh@redhat.com> | ||||
| Date: Mon, 17 Sep 2018 09:58:25 -0400 | ||||
| Subject: [PATCH 01/11] Generate manpage | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| ---
 | ||||
|  meson.build | 22 +++++++++++++++++++++- | ||||
|  1 file changed, 21 insertions(+), 1 deletion(-) | ||||
| 
 | ||||
| diff --git a/meson.build b/meson.build
 | ||||
| index e6f33475cce6891d17656bcd10e1afabd43bdc07..a2ca4ba1472bfff61fbbd30ba1ddc7ecc89e723c 100644
 | ||||
| --- a/meson.build
 | ||||
| +++ b/meson.build
 | ||||
| @@ -7,7 +7,7 @@ project('sscg', 'c',
 | ||||
|            'b_asneeded=true', | ||||
|          ], | ||||
|          license : 'MIT', | ||||
| -        meson_version : '>=0.36.0')
 | ||||
| +        meson_version : '>=0.40.0')
 | ||||
|   | ||||
|  cc = meson.get_compiler('c') | ||||
|  test_cflags = [ | ||||
| @@ -141,3 +141,23 @@ configure_file(
 | ||||
|      output : 'config.h', | ||||
|      configuration : cdata) | ||||
|   | ||||
| +# Generate a manpage from the POPT documentation
 | ||||
| +help2man = find_program('help2man')
 | ||||
| +
 | ||||
| +manpage = custom_target('manpage',
 | ||||
| +    output : 'sscg.8',
 | ||||
| +    capture : true,
 | ||||
| +    command : [
 | ||||
| +        help2man,
 | ||||
| +        '-s', '8',
 | ||||
| +        '-n', 'Tool for generating x.509 certificates',
 | ||||
| +        '-N',
 | ||||
| +        sscg,
 | ||||
| +    ],
 | ||||
| +    install : true,
 | ||||
| +    build_by_default : true,
 | ||||
| +    install_dir : join_paths(
 | ||||
| +        get_option('prefix'),
 | ||||
| +        get_option('mandir'),
 | ||||
| +        'man8'),
 | ||||
| +)
 | ||||
| -- 
 | ||||
| 2.35.1 | ||||
| 
 | ||||
| @ -1,208 +0,0 @@ | ||||
| From 7074c05cfb250aaa639cf88f54564db852223165 Mon Sep 17 00:00:00 2001 | ||||
| From: Stephen Gallagher <sgallagh@redhat.com> | ||||
| Date: Tue, 27 Nov 2018 13:24:37 -0500 | ||||
| Subject: [PATCH 02/11] Adjust defaults based on system security level | ||||
| 
 | ||||
| Also permit arbitrary keylengths. | ||||
| 
 | ||||
| Disallow keylengths smaller than the configured system minimum. | ||||
| 
 | ||||
| Resolves: rhbz#1653323 | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| ---
 | ||||
|  config.h.in    |  1 - | ||||
|  include/sscg.h |  1 + | ||||
|  meson.build    | 10 ++++++-- | ||||
|  src/sscg.c     | 64 ++++++++++++++++++++++++++++++++++++++++++++++---- | ||||
|  4 files changed, 68 insertions(+), 8 deletions(-) | ||||
|  delete mode 100644 config.h.in | ||||
| 
 | ||||
| diff --git a/config.h.in b/config.h.in
 | ||||
| deleted file mode 100644 | ||||
| index 6044a4355f6c8bfac8d36e533f48f395c597e5ac..0000000000000000000000000000000000000000
 | ||||
| --- a/config.h.in
 | ||||
| +++ /dev/null
 | ||||
| @@ -1 +0,0 @@
 | ||||
| -#define PACKAGE_VERSION "@version@"
 | ||||
| diff --git a/include/sscg.h b/include/sscg.h
 | ||||
| index 2bd42bbee965c754efb91febd10b6a94af6f508e..3e97cfe49a5cd8fc734ecf43a94156e376227eb7 100644
 | ||||
| --- a/include/sscg.h
 | ||||
| +++ b/include/sscg.h
 | ||||
| @@ -139,6 +139,7 @@ struct sscg_options
 | ||||
|   | ||||
|    /* Encryption requirements */ | ||||
|    int key_strength; | ||||
| +  int minimum_key_strength;
 | ||||
|    const EVP_MD *hash_fn; | ||||
|   | ||||
|    /* Output Files */ | ||||
| diff --git a/meson.build b/meson.build
 | ||||
| index a2ca4ba1472bfff61fbbd30ba1ddc7ecc89e723c..c7b08ed3d6dff686f08a90ca869ba5881a9e8aaa 100644
 | ||||
| --- a/meson.build
 | ||||
| +++ b/meson.build
 | ||||
| @@ -34,6 +34,7 @@ endforeach
 | ||||
|   | ||||
|  pkg = import('pkgconfig') | ||||
|  crypto = dependency('libcrypto') | ||||
| +ssl = dependency('libssl')
 | ||||
|  path_utils = dependency('path_utils') | ||||
|  talloc = dependency('talloc') | ||||
|   | ||||
| @@ -49,6 +50,10 @@ else
 | ||||
|      popt_incdirs = include_directories('subprojects/popt') | ||||
|  endif | ||||
|   | ||||
| +has_get_sec_level = cc.has_function(
 | ||||
| +    'SSL_CTX_get_security_level',
 | ||||
| +    dependencies: [ ssl])
 | ||||
| +
 | ||||
|  sscg_lib_srcs = [ | ||||
|      'src/authority.c', | ||||
|      'src/bignum.c', | ||||
| @@ -70,6 +75,7 @@ sscg_lib = static_library(
 | ||||
|      sources : sscg_lib_srcs, | ||||
|      dependencies : [ | ||||
|          crypto, | ||||
| +        ssl,
 | ||||
|          talloc, | ||||
|      ], | ||||
|      install : false, | ||||
| @@ -135,9 +141,9 @@ init_bignum_test = executable(
 | ||||
|  test('init_bignum_test', init_bignum_test) | ||||
|   | ||||
|  cdata = configuration_data() | ||||
| -cdata.set('version', meson.project_version())
 | ||||
| +cdata.set_quoted('PACKAGE_VERSION', meson.project_version())
 | ||||
| +cdata.set('HAVE_SSL_CTX_GET_SECURITY_LEVEL', has_get_sec_level)
 | ||||
|  configure_file( | ||||
| -    input : 'config.h.in',
 | ||||
|      output : 'config.h', | ||||
|      configuration : cdata) | ||||
|   | ||||
| diff --git a/src/sscg.c b/src/sscg.c
 | ||||
| index b2c7cbbfd9dc69d9f55a18bc91ed6023c0e64c2e..85a42404aa94524b560755d506b893300a4414cd 100644
 | ||||
| --- a/src/sscg.c
 | ||||
| +++ b/src/sscg.c
 | ||||
| @@ -17,6 +17,7 @@
 | ||||
|      Copyright 2017 by Stephen Gallagher <sgallagh@redhat.com> | ||||
|  */ | ||||
|   | ||||
| +#define _GNU_SOURCE
 | ||||
|  #include <popt.h> | ||||
|  #include <stdlib.h> | ||||
|  #include <stdio.h> | ||||
| @@ -25,6 +26,7 @@
 | ||||
|  #include <path_utils.h> | ||||
|  #include <unistd.h> | ||||
|  #include <openssl/evp.h> | ||||
| +#include <openssl/ssl.h>
 | ||||
|  #include <sys/param.h> | ||||
|   | ||||
|  #include "config.h" | ||||
| @@ -32,11 +34,59 @@
 | ||||
|  #include "include/authority.h" | ||||
|  #include "include/service.h" | ||||
|   | ||||
| +static int
 | ||||
| +get_security_level (void)
 | ||||
| +{
 | ||||
| +#ifdef HAVE_SSL_CTX_GET_SECURITY_LEVEL
 | ||||
| +  SSL_CTX *ssl_ctx = SSL_CTX_new (TLS_method ());
 | ||||
| +  int security_level = SSL_CTX_get_security_level (ssl_ctx);
 | ||||
| +  SSL_CTX_free (ssl_ctx);
 | ||||
| +  ssl_ctx = NULL;
 | ||||
| +  return security_level;
 | ||||
| +#else
 | ||||
| +  return 0;
 | ||||
| +#endif
 | ||||
| +}
 | ||||
| +
 | ||||
|  static int | ||||
|  set_default_options (struct sscg_options *opts) | ||||
|  { | ||||
| +  int security_level = get_security_level ();
 | ||||
| +
 | ||||
|    opts->lifetime = 3650; | ||||
| -  opts->key_strength = 2048;
 | ||||
| +
 | ||||
| +  /* Select the default key strength based on the system security level
 | ||||
| +   * See:
 | ||||
| +   * https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_get_security_level.html
 | ||||
| +   * for the specification of the minimums.
 | ||||
| +   */
 | ||||
| +  switch (security_level)
 | ||||
| +    {
 | ||||
| +    case 0:
 | ||||
| +    case 1:
 | ||||
| +    case 2:
 | ||||
| +      /* Security level 2 and below permits lower key-strengths, but SSCG
 | ||||
| +       * will set a minimum of 2048 bits
 | ||||
| +       */
 | ||||
| +      opts->key_strength = 2048;
 | ||||
| +      break;
 | ||||
| +
 | ||||
| +    case 3: opts->key_strength = 3072; break;
 | ||||
| +
 | ||||
| +    case 4: opts->key_strength = 7680; break;
 | ||||
| +
 | ||||
| +    default:
 | ||||
| +      /* Unknown security level. Default to the highest we know about */
 | ||||
| +      fprintf (stderr,
 | ||||
| +               "Unknown system security level %d. Defaulting to highest-known "
 | ||||
| +               "level.\n",
 | ||||
| +               security_level);
 | ||||
| +      /* Fall through */
 | ||||
| +
 | ||||
| +    case 5: opts->key_strength = 15360; break;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  opts->minimum_key_strength = opts->key_strength;
 | ||||
|    return 0; | ||||
|  } | ||||
|   | ||||
| @@ -117,6 +167,7 @@ main (int argc, const char **argv)
 | ||||
|    size_t i; | ||||
|    poptContext pc; | ||||
|    struct sscg_options *options; | ||||
| +  char *minimum_key_strength_help = NULL;
 | ||||
|   | ||||
|    char *country = NULL; | ||||
|    char *state = NULL; | ||||
| @@ -172,6 +223,9 @@ main (int argc, const char **argv)
 | ||||
|    if (ret != EOK) | ||||
|      goto done; | ||||
|   | ||||
| +  minimum_key_strength_help =
 | ||||
| +    talloc_asprintf (main_ctx, "%d or larger", options->minimum_key_strength);
 | ||||
| +
 | ||||
|    options->verbosity = SSCG_DEFAULT; | ||||
|    struct poptOption long_options[] = { | ||||
|      POPT_AUTOHELP{ "quiet", | ||||
| @@ -293,7 +347,7 @@ main (int argc, const char **argv)
 | ||||
|        &options->key_strength, | ||||
|        0, | ||||
|        _ ("Strength of the certificate private keys in bits."), | ||||
| -      _ ("{512,1024,2048,4096}") },
 | ||||
| +      minimum_key_strength_help },
 | ||||
|      { | ||||
|        "hash-alg", | ||||
|        '\0', | ||||
| @@ -529,11 +583,11 @@ main (int argc, const char **argv)
 | ||||
|          } | ||||
|      } | ||||
|   | ||||
| -  if (options->key_strength != 512 && options->key_strength != 1024 &&
 | ||||
| -      options->key_strength != 2048 && options->key_strength != 4096)
 | ||||
| +  if (options->key_strength < options->minimum_key_strength)
 | ||||
|      { | ||||
|        fprintf (stderr, | ||||
| -               "Key strength must be one of {512, 1024, 2048, 4096}.\n");
 | ||||
| +               "Key strength must be at least %d bits.\n",
 | ||||
| +               options->minimum_key_strength);
 | ||||
|        ret = EINVAL; | ||||
|        goto done; | ||||
|      } | ||||
| -- 
 | ||||
| 2.35.1 | ||||
| 
 | ||||
							
								
								
									
										46
									
								
								0002-Correct-certificate-lifetime-calculation.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								0002-Correct-certificate-lifetime-calculation.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| From 87604820a935f87a8f533e3f294419d27c0514eb Mon Sep 17 00:00:00 2001 | ||||
| From: Allison Karlitskaya <allison.karlitskaya@redhat.com> | ||||
| Date: Tue, 26 Oct 2021 12:32:13 +0200 | ||||
| Subject: [PATCH 2/2] Correct certificate lifetime calculation | ||||
| 
 | ||||
| sscg allows passing the certificate lifetime, as a number of days, as a | ||||
| commandline argument.  It converts this value to seconds using the | ||||
| formula | ||||
| 
 | ||||
|   days * 24 * 3650 | ||||
| 
 | ||||
| which is incorrect.  The correct value is 3600. | ||||
| 
 | ||||
| This effectively adds an extra 20 minutes to the lifetime of the | ||||
| certificate for each day as given on the commandline, and was enough to | ||||
| cause some new integration tests in cockpit to fail. | ||||
| 
 | ||||
| Interestingly, 3650 is the old default value for the number of days of | ||||
| certificate validity (~10 years) so this probably slipped in as a sort | ||||
| of muscle-memory-assisted typo. | ||||
| 
 | ||||
| Let's just write `24 * 60 * 60` to make things clear. | ||||
| ---
 | ||||
|  src/x509.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
| 
 | ||||
| diff --git a/src/x509.c b/src/x509.c
 | ||||
| index dc1594a4bdcb9d81607f0fe5ad2d4562e5edb533..7c7e4dfe56d5756862f3e0f851941e846ce96f31 100644
 | ||||
| --- a/src/x509.c
 | ||||
| +++ b/src/x509.c
 | ||||
| @@ -416,11 +416,11 @@ sscg_sign_x509_csr (TALLOC_CTX *mem_ctx,
 | ||||
|        X509_set_issuer_name (cert, X509_REQ_get_subject_name (csr)); | ||||
|      } | ||||
|   | ||||
|    /* set time */ | ||||
|    X509_gmtime_adj (X509_get_notBefore (cert), 0); | ||||
| -  X509_gmtime_adj (X509_get_notAfter (cert), days * 24 * 3650);
 | ||||
| +  X509_gmtime_adj (X509_get_notAfter (cert), days * 24 * 60 * 60);
 | ||||
|   | ||||
|    /* set subject */ | ||||
|    subject = X509_NAME_dup (X509_REQ_get_subject_name (csr)); | ||||
|    sslret = X509_set_subject_name (cert, subject); | ||||
|    CHECK_SSL (sslret, X509_set_subject_name); | ||||
| -- 
 | ||||
| 2.33.0 | ||||
| 
 | ||||
| @ -1,115 +0,0 @@ | ||||
| From 0cf3235a6d21f17657b78863576a9adda227cc31 Mon Sep 17 00:00:00 2001 | ||||
| From: Stephen Gallagher <sgallagh@redhat.com> | ||||
| Date: Wed, 28 Nov 2018 08:00:08 -0500 | ||||
| Subject: [PATCH 03/11] Adjust hash defaults based on system security level | ||||
| 
 | ||||
| Unlike the key-strength, this does not set a minimum level because | ||||
| it's not a simple calculation. We will have to rely on libcrypto | ||||
| rejecting any explicitly-set algorithms as a violation of policy. | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| ---
 | ||||
|  include/sscg.h |  1 + | ||||
|  src/sscg.c     | 40 +++++++++++++++++++++------------------- | ||||
|  2 files changed, 22 insertions(+), 19 deletions(-) | ||||
| 
 | ||||
| diff --git a/include/sscg.h b/include/sscg.h
 | ||||
| index 3e97cfe49a5cd8fc734ecf43a94156e376227eb7..fc90b81a0060af28529f3be6922b1b1501559300 100644
 | ||||
| --- a/include/sscg.h
 | ||||
| +++ b/include/sscg.h
 | ||||
| @@ -140,6 +140,7 @@ struct sscg_options
 | ||||
|    /* Encryption requirements */ | ||||
|    int key_strength; | ||||
|    int minimum_key_strength; | ||||
| +  char *hash_alg;
 | ||||
|    const EVP_MD *hash_fn; | ||||
|   | ||||
|    /* Output Files */ | ||||
| diff --git a/src/sscg.c b/src/sscg.c
 | ||||
| index 85a42404aa94524b560755d506b893300a4414cd..58855f764480d24d6c0f57460b22a3a83281e37e 100644
 | ||||
| --- a/src/sscg.c
 | ||||
| +++ b/src/sscg.c
 | ||||
| @@ -66,14 +66,21 @@ set_default_options (struct sscg_options *opts)
 | ||||
|      case 1: | ||||
|      case 2: | ||||
|        /* Security level 2 and below permits lower key-strengths, but SSCG | ||||
| -       * will set a minimum of 2048 bits
 | ||||
| +       * will set a minimum of 2048 bits and the sha256 hash algorithm.
 | ||||
|         */ | ||||
| +      opts->hash_alg = talloc_strdup (opts, "sha256");
 | ||||
|        opts->key_strength = 2048; | ||||
|        break; | ||||
|   | ||||
| -    case 3: opts->key_strength = 3072; break;
 | ||||
| +    case 3:
 | ||||
| +      opts->hash_alg = talloc_strdup (opts, "sha256");
 | ||||
| +      opts->key_strength = 3072;
 | ||||
| +      break;
 | ||||
|   | ||||
| -    case 4: opts->key_strength = 7680; break;
 | ||||
| +    case 4:
 | ||||
| +      opts->hash_alg = talloc_strdup (opts, "sha384");
 | ||||
| +      opts->key_strength = 7680;
 | ||||
| +      break;
 | ||||
|   | ||||
|      default: | ||||
|        /* Unknown security level. Default to the highest we know about */ | ||||
| @@ -83,7 +90,10 @@ set_default_options (struct sscg_options *opts)
 | ||||
|                 security_level); | ||||
|        /* Fall through */ | ||||
|   | ||||
| -    case 5: opts->key_strength = 15360; break;
 | ||||
| +    case 5:
 | ||||
| +      opts->hash_alg = talloc_strdup (opts, "sha512");
 | ||||
| +      opts->key_strength = 15360;
 | ||||
| +      break;
 | ||||
|      } | ||||
|   | ||||
|    opts->minimum_key_strength = opts->key_strength; | ||||
| @@ -177,7 +187,6 @@ main (int argc, const char **argv)
 | ||||
|    char *email = NULL; | ||||
|    char *hostname = NULL; | ||||
|    char *packagename; | ||||
| -  char *hash_alg = NULL;
 | ||||
|    char **alternative_names = NULL; | ||||
|   | ||||
|    char *ca_file = NULL; | ||||
| @@ -351,10 +360,10 @@ main (int argc, const char **argv)
 | ||||
|      { | ||||
|        "hash-alg", | ||||
|        '\0', | ||||
| -      POPT_ARG_STRING,
 | ||||
| -      &hash_alg,
 | ||||
| +      POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT,
 | ||||
| +      &options->hash_alg,
 | ||||
|        0, | ||||
| -      _ ("Hashing algorithm to use for signing. (default: sha256)"),
 | ||||
| +      _ ("Hashing algorithm to use for signing."),
 | ||||
|        _ ("{sha256,sha384,sha512}"), | ||||
|      }, | ||||
|      { | ||||
| @@ -592,17 +601,10 @@ main (int argc, const char **argv)
 | ||||
|        goto done; | ||||
|      } | ||||
|   | ||||
| -  if (!hash_alg)
 | ||||
| -    {
 | ||||
| -      /* Default to SHA256 */
 | ||||
| -      options->hash_fn = EVP_sha256 ();
 | ||||
| -    }
 | ||||
| -  else
 | ||||
| -    {
 | ||||
| -      /* TODO: restrict this to approved hashes.
 | ||||
| -         * For now, we'll only list SHA[256|384|512] in the help */
 | ||||
| -      options->hash_fn = EVP_get_digestbyname (hash_alg);
 | ||||
| -    }
 | ||||
| +  /* TODO: restrict this to approved hashes.
 | ||||
| +   * For now, we'll only list SHA[256|384|512] in the help */
 | ||||
| +  options->hash_fn = EVP_get_digestbyname (options->hash_alg);
 | ||||
| +
 | ||||
|    if (!options->hash_fn) | ||||
|      { | ||||
|        fprintf (stderr, "Unsupported hashing algorithm."); | ||||
| -- 
 | ||||
| 2.35.1 | ||||
| 
 | ||||
							
								
								
									
										68
									
								
								0003-Truncate-IP-address-in-SAN.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								0003-Truncate-IP-address-in-SAN.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| From 0875cd6169e876c4296a307631d49b801fc686dc Mon Sep 17 00:00:00 2001 | ||||
| From: Stephen Gallagher <sgallagh@redhat.com> | ||||
| Date: Tue, 8 Mar 2022 16:33:35 -0500 | ||||
| Subject: [PATCH] Truncate IP address in SAN | ||||
| 
 | ||||
| In OpenSSL 1.1, this was done automatically when addind a SAN extension, | ||||
| but in OpenSSL 3.0 it is rejected as an invalid input. | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| ---
 | ||||
|  src/x509.c | 15 ++++++++++++++- | ||||
|  1 file changed, 14 insertions(+), 1 deletion(-) | ||||
| 
 | ||||
| diff --git a/src/x509.c b/src/x509.c
 | ||||
| index 7c7e4dfe56d5756862f3e0f851941e846ce96f31..e828ec725b23d7ea79393151e7bb436e2f61bdb8 100644
 | ||||
| --- a/src/x509.c
 | ||||
| +++ b/src/x509.c
 | ||||
| @@ -131,10 +131,11 @@ sscg_x509v3_csr_new (TALLOC_CTX *mem_ctx,
 | ||||
|    size_t i; | ||||
|    X509_NAME *subject; | ||||
|    char *alt_name = NULL; | ||||
|    char *tmp = NULL; | ||||
|    char *san = NULL; | ||||
| +  char *slash = NULL;
 | ||||
|    TALLOC_CTX *tmp_ctx; | ||||
|    X509_EXTENSION *ex = NULL; | ||||
|    struct sscg_x509_req *csr; | ||||
|   | ||||
|    /* Make sure we have a key available */ | ||||
| @@ -265,10 +266,16 @@ sscg_x509v3_csr_new (TALLOC_CTX *mem_ctx,
 | ||||
|                  tmp_ctx, "DNS:%s", certinfo->subject_alt_names[i]); | ||||
|              } | ||||
|            else | ||||
|              { | ||||
|                san = talloc_strdup (tmp_ctx, certinfo->subject_alt_names[i]); | ||||
| +              /* SAN IP addresses cannot include the subnet mask */
 | ||||
| +              if ((slash = strchr (san, '/')))
 | ||||
| +                {
 | ||||
| +                  /* Truncate at the slash */
 | ||||
| +                  *slash = '\0';
 | ||||
| +                }
 | ||||
|              } | ||||
|            CHECK_MEM (san); | ||||
|   | ||||
|            if (strnlen (san, MAXHOSTNAMELEN + 5) > MAXHOSTNAMELEN + 4) | ||||
|              { | ||||
| @@ -287,11 +294,17 @@ sscg_x509v3_csr_new (TALLOC_CTX *mem_ctx,
 | ||||
|            alt_name = tmp; | ||||
|          } | ||||
|      } | ||||
|   | ||||
|    ex = X509V3_EXT_conf_nid (NULL, NULL, NID_subject_alt_name, alt_name); | ||||
| -  CHECK_MEM (ex);
 | ||||
| +  if (!ex)
 | ||||
| +    {
 | ||||
| +      ret = EINVAL;
 | ||||
| +      fprintf (stderr, "Invalid subjectAlternativeName: %s\n", alt_name);
 | ||||
| +      goto done;
 | ||||
| +    }
 | ||||
| +
 | ||||
|    sk_X509_EXTENSION_push (certinfo->extensions, ex); | ||||
|   | ||||
|    /* Set the public key for the certificate */ | ||||
|    sslret = X509_REQ_set_pubkey (csr->x509_req, spkey->evp_pkey); | ||||
|    CHECK_SSL (sslret, X509_REQ_set_pubkey (OU)); | ||||
| -- 
 | ||||
| 2.35.1 | ||||
| 
 | ||||
| @ -1,51 +0,0 @@ | ||||
| From 6c9ae621c41e1df30dead272aaee30a231c82cef Mon Sep 17 00:00:00 2001 | ||||
| From: Stephen Gallagher <sgallagh@redhat.com> | ||||
| Date: Wed, 28 Nov 2018 09:16:29 -0500 | ||||
| Subject: [PATCH 04/11] Properly check all return values | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| ---
 | ||||
|  src/authority.c | 1 + | ||||
|  src/service.c   | 1 + | ||||
|  src/x509.c      | 1 + | ||||
|  3 files changed, 3 insertions(+) | ||||
| 
 | ||||
| diff --git a/src/authority.c b/src/authority.c
 | ||||
| index b735868416b7fb5d016f0854baf0f27cd5f98b26..4e0dccc6c1210beffb38acd9f7dfb6108ca4a4ad 100644
 | ||||
| --- a/src/authority.c
 | ||||
| +++ b/src/authority.c
 | ||||
| @@ -180,6 +180,7 @@ create_private_CA (TALLOC_CTX *mem_ctx,
 | ||||
|   | ||||
|    /* Finalize the CSR */ | ||||
|    ret = sscg_x509v3_csr_finalize (ca_certinfo, pkey, csr); | ||||
| +  CHECK_OK (ret);
 | ||||
|   | ||||
|    if (options->verbosity >= SSCG_DEBUG) | ||||
|      { | ||||
| diff --git a/src/service.c b/src/service.c
 | ||||
| index b292e94063f032fd3c34a8134702063ea46bfa0c..34c976dbe905528000b181c24d1fa95da3cd1377 100644
 | ||||
| --- a/src/service.c
 | ||||
| +++ b/src/service.c
 | ||||
| @@ -126,6 +126,7 @@ create_service_cert (TALLOC_CTX *mem_ctx,
 | ||||
|   | ||||
|    /* Finalize the CSR */ | ||||
|    ret = sscg_x509v3_csr_finalize (svc_certinfo, pkey, csr); | ||||
| +  CHECK_OK (ret);
 | ||||
|   | ||||
|    if (options->verbosity >= SSCG_DEBUG) | ||||
|      { | ||||
| diff --git a/src/x509.c b/src/x509.c
 | ||||
| index 6d152fc969d745cc5cf085116c8688866f9d6ab4..18f0627bc64e7cb503a9e81c36dbe726186d1144 100644
 | ||||
| --- a/src/x509.c
 | ||||
| +++ b/src/x509.c
 | ||||
| @@ -41,6 +41,7 @@ sscg_generate_serial (TALLOC_CTX *mem_ctx, struct sscg_bignum **serial)
 | ||||
|      } | ||||
|   | ||||
|    ret = sscg_init_bignum (tmp_ctx, 0, &bn); | ||||
| +  CHECK_OK (ret);
 | ||||
|   | ||||
|    /* We'll create a random number of sizeof(unsigned long) - 1 bits | ||||
|         to use as the serial. We use unsigned long to ensure that it | ||||
| -- 
 | ||||
| 2.35.1 | ||||
| 
 | ||||
| @ -1,273 +0,0 @@ | ||||
| From 9166f6ceaa925584bcf30a132b8f560ff61b6bb3 Mon Sep 17 00:00:00 2001 | ||||
| From: Stephen Gallagher <sgallagh@redhat.com> | ||||
| Date: Wed, 5 Jun 2019 17:08:23 -0400 | ||||
| Subject: [PATCH 05/11] Add password support for private keys | ||||
| 
 | ||||
| Fixes: https://github.com/sgallagher/sscg/issues/14 | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| ---
 | ||||
|  include/sscg.h |   7 +++ | ||||
|  src/sscg.c     | 152 ++++++++++++++++++++++++++++++++++++++++++++++++- | ||||
|  2 files changed, 157 insertions(+), 2 deletions(-) | ||||
| 
 | ||||
| diff --git a/include/sscg.h b/include/sscg.h
 | ||||
| index fc90b81a0060af28529f3be6922b1b1501559300..ce9a7916e9432d0843d82af61d56ea7238ded682 100644
 | ||||
| --- a/include/sscg.h
 | ||||
| +++ b/include/sscg.h
 | ||||
| @@ -141,8 +141,15 @@ struct sscg_options
 | ||||
|    int key_strength; | ||||
|    int minimum_key_strength; | ||||
|    char *hash_alg; | ||||
| +  char *cipher_alg;
 | ||||
| +  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;
 | ||||
| +
 | ||||
|    /* Output Files */ | ||||
|    char *ca_file; | ||||
|    char *ca_key_file; | ||||
| diff --git a/src/sscg.c b/src/sscg.c
 | ||||
| index 58855f764480d24d6c0f57460b22a3a83281e37e..9dc926c77038105ca881a612cccd1913bc2d42f1 100644
 | ||||
| --- a/src/sscg.c
 | ||||
| +++ b/src/sscg.c
 | ||||
| @@ -97,6 +97,9 @@ set_default_options (struct sscg_options *opts)
 | ||||
|      } | ||||
|   | ||||
|    opts->minimum_key_strength = opts->key_strength; | ||||
| +
 | ||||
| +  opts->cipher_alg = talloc_strdup (opts, "aes-256-cbc");
 | ||||
| +
 | ||||
|    return 0; | ||||
|  } | ||||
|   | ||||
| @@ -170,6 +173,42 @@ done:
 | ||||
|    return ret; | ||||
|  } | ||||
|   | ||||
| +
 | ||||
| +/* 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;
 | ||||
| +}
 | ||||
| +
 | ||||
| +
 | ||||
|  int | ||||
|  main (int argc, const char **argv) | ||||
|  { | ||||
| @@ -196,8 +235,11 @@ main (int argc, const char **argv)
 | ||||
|   | ||||
|    int ca_mode = 0644; | ||||
|    int ca_key_mode = 0600; | ||||
| +  char *ca_key_password = NULL;
 | ||||
| +
 | ||||
|    int cert_mode = 0644; | ||||
|    int cert_key_mode = 0600; | ||||
| +  char *cert_key_password = NULL;
 | ||||
|   | ||||
|    char *create_mode = NULL; | ||||
|   | ||||
| @@ -227,6 +269,7 @@ 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);
 | ||||
|   | ||||
|    ret = set_default_options (options); | ||||
|    if (ret != EOK) | ||||
| @@ -366,6 +409,16 @@ main (int argc, const char **argv)
 | ||||
|        _ ("Hashing algorithm to use for signing."), | ||||
|        _ ("{sha256,sha384,sha512}"), | ||||
|      }, | ||||
| +    {
 | ||||
| +      "cipher-alg",
 | ||||
| +      '\0',
 | ||||
| +      POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT,
 | ||||
| +      &options->cipher_alg,
 | ||||
| +      0,
 | ||||
| +      _ ("Cipher to use for encrypting key files."),
 | ||||
| +      _ ("{des-ede3-cbc,aes-256-cbc}"),
 | ||||
| +    },
 | ||||
| +
 | ||||
|      { | ||||
|        "ca-file", | ||||
|        '\0', | ||||
| @@ -404,6 +457,29 @@ main (int argc, const char **argv)
 | ||||
|        _ ("File mode of the created CA key. (default: 0600)"), | ||||
|        _ ("0600"), | ||||
|      }, | ||||
| +    {
 | ||||
| +      "ca-key-password",
 | ||||
| +      '\0',
 | ||||
| +      POPT_ARG_STRING,
 | ||||
| +      &ca_key_password,
 | ||||
| +      0,
 | ||||
| +      _ ("Provide a password for the CA key file. Note that this will be "
 | ||||
| +         "visible in the process table for all users, so it should be used "
 | ||||
| +         "for testing purposes only. Use --ca-keypassfile or "
 | ||||
| +         "--ca-key-password-prompt for secure password entry."),
 | ||||
| +      NULL
 | ||||
| +    },
 | ||||
| +
 | ||||
| +    {
 | ||||
| +      "ca-key-password-prompt",
 | ||||
| +      'C',
 | ||||
| +      POPT_ARG_NONE,
 | ||||
| +      &options->ca_key_pass_prompt,
 | ||||
| +      0,
 | ||||
| +      _ ("Prompt to enter a password for the CA key file."),
 | ||||
| +      NULL
 | ||||
| +    },
 | ||||
| +
 | ||||
|      { | ||||
|        "cert-file", | ||||
|        '\0', | ||||
| @@ -442,6 +518,29 @@ main (int argc, const char **argv)
 | ||||
|        _ ("File mode of the created certificate key. (default: 0600)"), | ||||
|        _ ("0600"), | ||||
|      }, | ||||
| +    {
 | ||||
| +      "cert-key-password",
 | ||||
| +      'p',
 | ||||
| +      POPT_ARG_STRING,
 | ||||
| +      &cert_key_password,
 | ||||
| +      0,
 | ||||
| +      _ ("Provide a password for the service key file. Note that this will be "
 | ||||
| +         "visible in the process table for all users, so this flag should be "
 | ||||
| +         "used for testing purposes only. Use --cert-keypassfile or "
 | ||||
| +         "--cert-key-password-prompt for secure password entry."),
 | ||||
| +      NULL
 | ||||
| +    },
 | ||||
| +
 | ||||
| +    {
 | ||||
| +      "cert-key-password-prompt",
 | ||||
| +      'P',
 | ||||
| +      POPT_ARG_NONE,
 | ||||
| +      &options->cert_key_pass_prompt,
 | ||||
| +      0,
 | ||||
| +      _ ("Prompt to enter a password for the service key file."),
 | ||||
| +      NULL
 | ||||
| +    },
 | ||||
| +
 | ||||
|      POPT_TABLEEND | ||||
|    }; | ||||
|   | ||||
| @@ -592,6 +691,20 @@ main (int argc, const char **argv)
 | ||||
|          } | ||||
|      } | ||||
|   | ||||
| +  /* Password handling */
 | ||||
| +  if (ca_key_password)
 | ||||
| +    {
 | ||||
| +      options->ca_key_pass =
 | ||||
| +        sscg_secure_string_steal (options, ca_key_password);
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  if (cert_key_password)
 | ||||
| +    {
 | ||||
| +      options->cert_key_pass =
 | ||||
| +        sscg_secure_string_steal (options, cert_key_password);
 | ||||
| +    }
 | ||||
| +
 | ||||
| +
 | ||||
|    if (options->key_strength < options->minimum_key_strength) | ||||
|      { | ||||
|        fprintf (stderr, | ||||
| @@ -601,6 +714,15 @@ main (int argc, const char **argv)
 | ||||
|        goto done; | ||||
|      } | ||||
|   | ||||
| +  /* Make sure we have a valid cipher */
 | ||||
| +  options->cipher = EVP_get_cipherbyname (options->cipher_alg);
 | ||||
| +  if (!options->cipher)
 | ||||
| +    {
 | ||||
| +      fprintf (stderr, "Invalid cipher specified: %s\n", options->cipher_alg);
 | ||||
| +      ret = EINVAL;
 | ||||
| +      goto done;
 | ||||
| +    }
 | ||||
| +
 | ||||
|    /* TODO: restrict this to approved hashes. | ||||
|     * For now, we'll only list SHA[256|384|512] in the help */ | ||||
|    options->hash_fn = EVP_get_digestbyname (options->hash_alg); | ||||
| @@ -696,8 +818,21 @@ main (int argc, const char **argv)
 | ||||
|    cert_key_out = BIO_new_file (options->cert_key_file, create_mode); | ||||
|    CHECK_BIO (cert_key_out, options->cert_key_file); | ||||
|   | ||||
| +  /* 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 ( | ||||
| -    cert_key_out, svc_key->evp_pkey, NULL, NULL, 0, NULL, NULL);
 | ||||
| +    cert_key_out,
 | ||||
| +    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)); | ||||
|    BIO_get_fp (cert_key_out, &fp); | ||||
|   | ||||
| @@ -776,8 +911,21 @@ main (int argc, const char **argv)
 | ||||
|          } | ||||
|        CHECK_BIO (ca_key_out, options->ca_key_file); | ||||
|   | ||||
| +      /* 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 ( | ||||
| -        ca_key_out, cakey->evp_pkey, NULL, NULL, 0, NULL, NULL);
 | ||||
| +        ca_key_out,
 | ||||
| +        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)); | ||||
|        BIO_get_fp (ca_key_out, &fp); | ||||
|        if (options->verbosity >= SSCG_DEBUG) | ||||
| -- 
 | ||||
| 2.35.1 | ||||
| 
 | ||||
| @ -1,153 +0,0 @@ | ||||
| From bfb35ad835e6fcbe97c2d70b3ca8f724b4dc2a5f Mon Sep 17 00:00:00 2001 | ||||
| From: Stephen Gallagher <sgallagh@redhat.com> | ||||
| Date: Mon, 10 Jun 2019 10:15:42 -0400 | ||||
| Subject: [PATCH 06/11] Allow specifying keyfile password by file | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| ---
 | ||||
|  src/sscg.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||
|  1 file changed, 84 insertions(+) | ||||
| 
 | ||||
| diff --git a/src/sscg.c b/src/sscg.c
 | ||||
| index 9dc926c77038105ca881a612cccd1913bc2d42f1..a02e4df66c6cf9ec1865f425b4a15da82fbfdc72 100644
 | ||||
| --- a/src/sscg.c
 | ||||
| +++ b/src/sscg.c
 | ||||
| @@ -34,6 +34,10 @@
 | ||||
|  #include "include/authority.h" | ||||
|  #include "include/service.h" | ||||
|   | ||||
| +
 | ||||
| +/* Same as OpenSSL CLI */
 | ||||
| +#define MAX_PW_LEN 1024
 | ||||
| +
 | ||||
|  static int | ||||
|  get_security_level (void) | ||||
|  { | ||||
| @@ -209,6 +213,44 @@ sscg_options_destructor (TALLOC_CTX *opts)
 | ||||
|  } | ||||
|   | ||||
|   | ||||
| +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;
 | ||||
| +}
 | ||||
| +
 | ||||
| +
 | ||||
|  int | ||||
|  main (int argc, const char **argv) | ||||
|  { | ||||
| @@ -236,10 +278,12 @@ main (int argc, const char **argv)
 | ||||
|    int ca_mode = 0644; | ||||
|    int ca_key_mode = 0600; | ||||
|    char *ca_key_password = NULL; | ||||
| +  char *ca_key_passfile = NULL;
 | ||||
|   | ||||
|    int cert_mode = 0644; | ||||
|    int cert_key_mode = 0600; | ||||
|    char *cert_key_password = NULL; | ||||
| +  char *cert_key_passfile = NULL;
 | ||||
|   | ||||
|    char *create_mode = NULL; | ||||
|   | ||||
| @@ -470,6 +514,16 @@ main (int argc, const char **argv)
 | ||||
|        NULL | ||||
|      }, | ||||
|   | ||||
| +    {
 | ||||
| +      "ca-key-passfile",
 | ||||
| +      '\0',
 | ||||
| +      POPT_ARG_STRING,
 | ||||
| +      &ca_key_passfile,
 | ||||
| +      0,
 | ||||
| +      _ ("A file containing the password to encrypt the CA key file."),
 | ||||
| +      NULL
 | ||||
| +    },
 | ||||
| +
 | ||||
|      { | ||||
|        "ca-key-password-prompt", | ||||
|        'C', | ||||
| @@ -531,6 +585,16 @@ main (int argc, const char **argv)
 | ||||
|        NULL | ||||
|      }, | ||||
|   | ||||
| +    {
 | ||||
| +      "cert-key-passfile",
 | ||||
| +      '\0',
 | ||||
| +      POPT_ARG_STRING,
 | ||||
| +      &cert_key_passfile,
 | ||||
| +      0,
 | ||||
| +      _ ("A file containing the password to encrypt the service key file."),
 | ||||
| +      NULL
 | ||||
| +    },
 | ||||
| +
 | ||||
|      { | ||||
|        "cert-key-password-prompt", | ||||
|        'P', | ||||
| @@ -697,12 +761,32 @@ main (int argc, const char **argv)
 | ||||
|        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 (options->key_strength < options->minimum_key_strength) | ||||
| -- 
 | ||||
| 2.35.1 | ||||
| 
 | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,98 +0,0 @@ | ||||
| From 846ea9642360184afb38cf2d8fed01e4fbc84410 Mon Sep 17 00:00:00 2001 | ||||
| From: Stephen Gallagher <sgallagh@redhat.com> | ||||
| Date: Fri, 13 Dec 2019 08:25:01 -0500 | ||||
| Subject: [PATCH 08/11] Fix client-cert issues found by CI tests | ||||
| 
 | ||||
| Resolves: rhbz#1720667 | ||||
| 
 | ||||
| Better error message for client certs without public key file | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| 
 | ||||
| Fix memory leak in sscg_sign_x509_csr() | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| 
 | ||||
| Address clang-analyzer warning | ||||
| 
 | ||||
| clang-analyzer determined that it was possible for the GET_BIO() | ||||
| return value to have changed between conditional creation of the | ||||
| client certificate and writing it out. This patch stores the result | ||||
| of the lookup so it's certain to be consistent. | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| ---
 | ||||
|  src/io_utils.c | 4 ++-- | ||||
|  src/sscg.c     | 8 +++++--- | ||||
|  src/x509.c     | 1 + | ||||
|  3 files changed, 8 insertions(+), 5 deletions(-) | ||||
| 
 | ||||
| diff --git a/src/io_utils.c b/src/io_utils.c
 | ||||
| index 809a1da0e455afa0dba0796a5f7ac406742328a1..a2502afb20f4bcb536428f3528900c2bb06997f5 100644
 | ||||
| --- a/src/io_utils.c
 | ||||
| +++ b/src/io_utils.c
 | ||||
| @@ -363,8 +363,8 @@ sscg_io_utils_open_output_files (struct sscg_stream **streams, bool overwrite)
 | ||||
|   | ||||
|      case IO_UTILS_CLIENT_UNMATCHED: | ||||
|        SSCG_ERROR ( | ||||
| -        "The client certificate must have both public and private key "
 | ||||
| -        "locations specified.\n");
 | ||||
| +        "The client certificate must have the public key location "
 | ||||
| +        "specified.\n");
 | ||||
|        ret = EINVAL; | ||||
|        goto done; | ||||
|   | ||||
| diff --git a/src/sscg.c b/src/sscg.c
 | ||||
| index 470af815d91f5170a1e8fe00006dbaee4d07b209..f34a43b83e562d0bd7da9a77e25911762db83693 100644
 | ||||
| --- a/src/sscg.c
 | ||||
| +++ b/src/sscg.c
 | ||||
| @@ -300,6 +300,7 @@ main (int argc, const char **argv)
 | ||||
|    char *cert_key_password = NULL; | ||||
|    char *cert_key_passfile = NULL; | ||||
|   | ||||
| +  bool build_client_cert = false;
 | ||||
|    int client_mode = SSCG_CERT_DEFAULT_MODE; | ||||
|    int client_key_mode = SSCG_KEY_DEFAULT_MODE; | ||||
|    char *client_key_password = NULL; | ||||
| @@ -1118,7 +1119,8 @@ main (int argc, const char **argv)
 | ||||
|    /* If requested, generate the client auth certificate and sign it with the | ||||
|     * private CA. | ||||
|     */ | ||||
| -  if (GET_BIO (SSCG_FILE_TYPE_CLIENT))
 | ||||
| +  build_client_cert = !!(GET_BIO (SSCG_FILE_TYPE_CLIENT));
 | ||||
| +  if (build_client_cert)
 | ||||
|      { | ||||
|        ret = create_cert (main_ctx, | ||||
|                           options, | ||||
| @@ -1136,7 +1138,7 @@ main (int argc, const char **argv)
 | ||||
|   | ||||
|    /* Write private keys first */ | ||||
|   | ||||
| -  if (GET_BIO (SSCG_FILE_TYPE_CLIENT_KEY))
 | ||||
| +  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. | ||||
| @@ -1201,7 +1203,7 @@ main (int argc, const char **argv)
 | ||||
|    /* Public keys come next, in chain order */ | ||||
|   | ||||
|    /* Start with the client certificate */ | ||||
| -  if (GET_BIO (SSCG_FILE_TYPE_CLIENT))
 | ||||
| +  if (build_client_cert)
 | ||||
|      { | ||||
|        sret = PEM_write_bio_X509 (GET_BIO (SSCG_FILE_TYPE_CLIENT), | ||||
|                                   client_cert->certificate); | ||||
| diff --git a/src/x509.c b/src/x509.c
 | ||||
| index 18f0627bc64e7cb503a9e81c36dbe726186d1144..c173f539791fbbc51e52e6b121e587dca43924d4 100644
 | ||||
| --- a/src/x509.c
 | ||||
| +++ b/src/x509.c
 | ||||
| @@ -482,5 +482,6 @@ done:
 | ||||
|        *_cert = talloc_steal (mem_ctx, scert); | ||||
|      } | ||||
|    X509_NAME_free (subject); | ||||
| +  talloc_free(tmp_ctx);
 | ||||
|    return ret; | ||||
|  } | ||||
| -- 
 | ||||
| 2.35.1 | ||||
| 
 | ||||
| @ -1,36 +0,0 @@ | ||||
| From 80f1965776d1213aeb4bee71e615ec8717249700 Mon Sep 17 00:00:00 2001 | ||||
| From: Stephen Gallagher <sgallagh@redhat.com> | ||||
| Date: Fri, 13 Dec 2019 11:51:43 -0500 | ||||
| Subject: [PATCH 09/11] Fix help message for --client-key-file | ||||
| 
 | ||||
| Resolves: rhbz#1720667 | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| 
 | ||||
| Further clarify --client-key-file help message | ||||
| 
 | ||||
| Resolves: rhbz#1720667 | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| ---
 | ||||
|  src/sscg.c | 4 +--- | ||||
|  1 file changed, 1 insertion(+), 3 deletions(-) | ||||
| 
 | ||||
| diff --git a/src/sscg.c b/src/sscg.c
 | ||||
| index f34a43b83e562d0bd7da9a77e25911762db83693..4d009a67488e83c4332f58ee52f7d6ea72a8ddbd 100644
 | ||||
| --- a/src/sscg.c
 | ||||
| +++ b/src/sscg.c
 | ||||
| @@ -734,9 +734,7 @@ main (int argc, const char **argv)
 | ||||
|        &client_key_file, | ||||
|        0, | ||||
|        _ ("Path where the client's private key will be stored. " | ||||
| -         "(default is client-file with a .key suffix, if "
 | ||||
| -         "--client-file was passed, otherwise this file will not "
 | ||||
| -         "be generated.)"),
 | ||||
| +         "(default is the client-file)"),
 | ||||
|        NULL, | ||||
|      }, | ||||
|   | ||||
| -- 
 | ||||
| 2.35.1 | ||||
| 
 | ||||
| @ -1,920 +0,0 @@ | ||||
| From 870f8338b73f3300d4030eb31df8416fa7208f89 Mon Sep 17 00:00:00 2001 | ||||
| From: Stephen Gallagher <sgallagh@redhat.com> | ||||
| Date: Tue, 7 Jan 2020 14:32:01 -0500 | ||||
| Subject: [PATCH 10/11] 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 <sgallagh@redhat.com> | ||||
| 
 | ||||
| Output private keys with 2048 iteration count | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| 
 | ||||
| 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 <sgallagh@redhat.com> | ||||
| 
 | ||||
| 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 <sgallagh@redhat.com> | ||||
| 
 | ||||
| Fix memory leaks | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| 
 | ||||
| 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 <sgallagh@redhat.com> | ||||
| 
 | ||||
| Prevent uninitialized read error | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| 
 | ||||
| Add missing newline for error message | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| 
 | ||||
| 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 <sgallagh@redhat.com> | ||||
| 
 | ||||
| Fix formatting | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| 
 | ||||
| Fix missing error check | ||||
| 
 | ||||
| Signed-off-by: Stephen Gallagher <sgallagh@redhat.com> | ||||
| 
 | ||||
| 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 <sgallagh@redhat.com> | ||||
| ---
 | ||||
|  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 <stdbool.h> | ||||
|  #include <talloc.h> | ||||
|   | ||||
| +#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 <sgallagh@redhat.com> | ||||
|  */ | ||||
|   | ||||
| +#ifndef _SSCG_KEY_H
 | ||||
| +#define _SSCG_KEY_H
 | ||||
| +
 | ||||
|  #include <openssl/rsa.h> | ||||
|  #include <openssl/evp.h> | ||||
|   | ||||
|  #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 <errno.h> | ||||
|  #include <openssl/ssl.h> | ||||
|  #include <openssl/err.h> | ||||
| +#include <openssl/ui.h>
 | ||||
|  #include <stdbool.h> | ||||
|  #include <talloc.h> | ||||
|  #include <stdint.h> | ||||
|   | ||||
| -#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 <sgallagh@redhat.com> | ||||
|  */ | ||||
|   | ||||
| +#ifndef _SSCG_X509_H
 | ||||
| +#define _SSCG_X509_H
 | ||||
| +
 | ||||
|  #include <openssl/x509.h> | ||||
|  #include <openssl/x509v3.h> | ||||
|   | ||||
| @@ -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 <talloc.h> | ||||
|   | ||||
|  #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 <assert.h>
 | ||||
|  #include <popt.h> | ||||
|  #include <stdlib.h> | ||||
|  #include <stdio.h> | ||||
| @@ -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.35.1 | ||||
| 
 | ||||
							
								
								
									
										2
									
								
								sources
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								sources
									
									
									
									
									
								
							| @ -1 +1 @@ | ||||
| SHA512 (sscg-2.3.3-stripped.tar.xz) = b39ebf7f22b8419442ff8832ff302bcc2cb0cd02e66ca631f44536eacb644cf7549ac9ad15872021519dc5f951ec7cedf566c170f49e75b0b6a8e83c21b7253c | ||||
| SHA512 (sscg-3.0.0.tar.xz) = d5bbd14c102bb11b387b6018dced09b23b053498c60befd916aa142ece8240f443e364d9a578b6b5aa15c68cb943725ed96ef44cce77eb01013e464a6d4dc0f1 | ||||
|  | ||||
							
								
								
									
										40
									
								
								sscg.spec
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								sscg.spec
									
									
									
									
									
								
							| @ -8,16 +8,13 @@ | ||||
| 
 | ||||
| 
 | ||||
| Name:           sscg | ||||
| Version:        2.3.3 | ||||
| Release:        15%{?dist} | ||||
| Version:        3.0.0 | ||||
| Release:        5%{?dist} | ||||
| Summary:        Simple SSL certificate generator | ||||
| 
 | ||||
| License:        BSD | ||||
| License:        GPLv3+ with exceptions | ||||
| URL:            https://%{provider_prefix} | ||||
| 
 | ||||
| # Run ./sscg-strip.sh to produce a tarball with the bundled popt library | ||||
| # stripped out to reduce license issues. | ||||
| Source0:        https://%{provider_prefix}/releases/download/%{repo}-%{version}/%{repo}-%{version}-stripped.tar.xz | ||||
| Source0:        https://%{provider_prefix}/releases/download/%{repo}-%{version}/%{repo}-%{version}.tar.xz | ||||
| 
 | ||||
| BuildRequires:  gcc | ||||
| BuildRequires:  libtalloc-devel | ||||
| @ -28,23 +25,11 @@ BuildRequires:  meson | ||||
| BuildRequires:  ninja-build | ||||
| BuildRequires:  help2man | ||||
| 
 | ||||
| # Patches | ||||
| Patch0001: 0001-Generate-manpage.patch | ||||
| Patch0002: 0002-Adjust-defaults-based-on-system-security-level.patch | ||||
| Patch0003: 0003-Adjust-hash-defaults-based-on-system-security-level.patch | ||||
| Patch0004: 0004-Properly-check-all-return-values.patch | ||||
| 
 | ||||
| # RHBZ #1717880 | ||||
| Patch0005: 0005-Add-password-support-for-private-keys.patch | ||||
| Patch0006: 0006-Allow-specifying-keyfile-password-by-file.patch | ||||
| Patch0001: 0001-Drop-usage-of-ERR_GET_FUNC.patch | ||||
| Patch0002: 0002-Correct-certificate-lifetime-calculation.patch | ||||
| Patch0003: 0003-Truncate-IP-address-in-SAN.patch | ||||
| 
 | ||||
| # RHBZ #1720667 | ||||
| Patch0007: 0007-Add-support-for-client-certificates-and-dhparams.patch | ||||
| Patch0008: 0008-Fix-client-cert-issues-found-by-CI-tests.patch | ||||
| Patch0009: 0009-Fix-help-message-for-client-key-file.patch | ||||
| 
 | ||||
| # RHBZ #1784441 and 1784443 | ||||
| Patch0010: 0010-Better-validation-of-command-line-arguments.patch | ||||
| 
 | ||||
| %description | ||||
| A utility to aid in the creation of more secure "self-signed" | ||||
| @ -54,7 +39,6 @@ client machine to trust the service certificate without needing to set | ||||
| up a full PKI environment and without exposing the machine to a risk of | ||||
| false signatures from the service certificate. | ||||
| 
 | ||||
| 
 | ||||
| %prep | ||||
| %autosetup -p1 | ||||
| 
 | ||||
| @ -67,10 +51,7 @@ false signatures from the service certificate. | ||||
| %meson_install | ||||
| 
 | ||||
| %check | ||||
| 
 | ||||
| %ifnarch %{arm} | ||||
| %meson_test | ||||
| %endif | ||||
| %meson_test -t 10 | ||||
| 
 | ||||
| %files | ||||
| %license COPYING | ||||
| @ -79,6 +60,11 @@ false signatures from the service certificate. | ||||
| %{_mandir}/man8/%{name}.8* | ||||
| 
 | ||||
| %changelog | ||||
| * Thu Jul 14 2022 Stephen Gallagher <sgallagh@redhat.com> - 3.0.0-5 | ||||
| - Rebase to sscg 3.0.0 | ||||
| - Resolves: rhbz#2107369 | ||||
| - Resolves: rhbz#2091525 | ||||
| 
 | ||||
| * Thu Jun 02 2022 Stephen Gallagher <sgallagh@redhat.com> - 2.3.3-15 | ||||
| - Fix certificate lifetime calculation | ||||
| - Resolves: rhbz#2091525 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user