From 698f32168dea6a0e02e2471de252028c28539317 Mon Sep 17 00:00:00 2001
From: Daniel Bevenius <daniel.bevenius@gmail.com>
Date: Tue, 28 Mar 2017 08:56:39 +0200
Subject: [PATCH] src: add --use-bundled-ca --use-openssl-ca check

The --use-bundled-ca and --use-openssl-ca command line arguments are
mutually exclusive but can both be used on the same command line.

This commit adds a check if both options are used.

Fixes: https://github.com/nodejs/node/issues/12083
---
 src/node.cc                              | 14 +++++++++++
 test/parallel/test-openssl-ca-options.js | 31 ++++++++++++++++++++++++
 2 files changed, 45 insertions(+)
 create mode 100644 test/parallel/test-openssl-ca-options.js

diff --git a/src/node.cc b/src/node.cc
index 52bf719852d891..77e6a5826ee957 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -3637,6 +3637,8 @@ static void ParseArgs(int* argc,
   const char** new_v8_argv = new const char*[nargs];
   const char** new_argv = new const char*[nargs];
   const char** local_preload_modules = new const char*[nargs];
+  bool use_bundled_ca = false;
+  bool use_openssl_ca = false;
 
   for (unsigned int i = 0; i < nargs; ++i) {
     new_exec_argv[i] = nullptr;
@@ -3751,7 +3753,9 @@ static void ParseArgs(int* argc,
       default_cipher_list = arg + 18;
     } else if (strncmp(arg, "--use-openssl-ca", 16) == 0) {
       ssl_openssl_cert_store = true;
+      use_openssl_ca = true;
     } else if (strncmp(arg, "--use-bundled-ca", 16) == 0) {
+      use_bundled_ca = true;
       ssl_openssl_cert_store = false;
 #if NODE_FIPS_MODE
     } else if (strcmp(arg, "--enable-fips") == 0) {
@@ -3786,6 +3790,16 @@ static void ParseArgs(int* argc,
     index += args_consumed;
   }
 
+#if HAVE_OPENSSL
+  if (use_openssl_ca && use_bundled_ca) {
+    fprintf(stderr,
+            "%s: either --use-openssl-ca or --use-bundled-ca can be used, "
+            "not both\n",
+            argv[0]);
+    exit(9);
+  }
+#endif
+
   // Copy remaining arguments.
   const unsigned int args_left = nargs - index;
   memcpy(new_argv + new_argc, argv + index, args_left * sizeof(*argv));
diff --git a/test/parallel/test-openssl-ca-options.js b/test/parallel/test-openssl-ca-options.js
new file mode 100644
index 00000000000000..f27976fab7c16c
--- /dev/null
+++ b/test/parallel/test-openssl-ca-options.js
@@ -0,0 +1,31 @@
+'use strict';
+// This test checks the usage of --use-bundled-ca and --use-openssl-ca arguments
+// to verify that both are not used at the same time.
+const common = require('../common');
+if (!common.hasCrypto) {
+  common.skip('missing crypto');
+  return;
+}
+const assert = require('assert');
+const os = require('os');
+const childProcess = require('child_process');
+const result = childProcess.spawnSync(process.execPath, [
+                                      '--use-bundled-ca',
+                                      '--use-openssl-ca',
+                                      '-p', 'process.version'],
+                                      {encoding: 'utf8'});
+
+assert.strictEqual(result.stderr,
+                   process.execPath + ': either --use-openssl-ca or ' +
+                   '--use-bundled-ca can be used, not both' + os.EOL);
+assert.strictEqual(result.status, 9);
+
+const useBundledCA = childProcess.spawnSync(process.execPath, [
+                                            '--use-bundled-ca',
+                                            '-p', 'process.version']);
+assert.strictEqual(useBundledCA.status, 0);
+
+const useOpenSSLCA = childProcess.spawnSync(process.execPath, [
+                                            '--use-openssl-ca',
+                                            '-p', 'process.version']);
+assert.strictEqual(useOpenSSLCA.status, 0);