This is an automated email from the ASF dual-hosted git repository.

lordgamez pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git

commit 14e2586aac2977f76b49c4c458908008edc9f211
Author: Ferenc Gerlits <fgerl...@gmail.com>
AuthorDate: Tue Jul 25 11:53:04 2023 +0200

    MINIFICPP-2170 Fix system certificate store usage in SSLContextService on 
Linux
    
    Use utils::getDefaultCAFile() in the SSLContextService to find the system CA
    certificate store file, as the compiled-in default value is usually wrong.
    If the system CA certificate store file is still not found, you can set the
    SSL_CERT_DIR or SSL_CERT_FILE environment variables to tell OpenSSL where
    the certificates are.
    
    Also: fix the incorrect handling of InvokeHTTP::DisablePeerVerification.
    Signed-off-by: Gabor Gyimesi <gamezb...@gmail.com>
    
    This closes #1620
---
 docker/requirements.txt                            |   2 +-
 .../cluster/DockerTestDirectoryBindings.py         |   2 +
 .../features/MiNiFi_integration_test_driver.py     |  24 +++-
 docker/test/integration/features/https.feature     | 155 +++++++++++++++++++--
 docker/test/integration/features/kafka.feature     |   8 +-
 docker/test/integration/features/steps/steps.py    |  43 +++---
 .../minifi/controllers/SSLContextService.py        |   5 +-
 .../test/integration/ssl_utils/SSL_cert_utils.py   |   2 +-
 extensions/aws/processors/S3Processor.cpp          |   6 +-
 extensions/http-curl/client/HTTPClient.cpp         |  24 ++--
 extensions/http-curl/client/HTTPClient.h           |   2 +-
 extensions/http-curl/processors/InvokeHTTP.cpp     |   2 +-
 .../http-curl/tests/VerifyInvokeHTTPGetTest.cpp    |   2 -
 libminifi/include/utils/HTTPUtils.h                |   4 +-
 libminifi/src/controllers/SSLContextService.cpp    |  13 +-
 libminifi/src/utils/HTTPUtils.cpp                  |   9 +-
 16 files changed, 228 insertions(+), 75 deletions(-)

diff --git a/docker/requirements.txt b/docker/requirements.txt
index 715077678..9272e430d 100644
--- a/docker/requirements.txt
+++ b/docker/requirements.txt
@@ -4,7 +4,7 @@ behavex==2.0.1
 docker==5.0.0
 kafka-python==2.0.2
 confluent-kafka==1.7.0
-PyYAML==5.4.1
+PyYAML==6.0.1
 m2crypto==0.38.0
 watchdog==2.1.2
 pyopenssl==23.0.0
diff --git a/docker/test/integration/cluster/DockerTestDirectoryBindings.py 
b/docker/test/integration/cluster/DockerTestDirectoryBindings.py
index a27163e69..fec53dfb1 100644
--- a/docker/test/integration/cluster/DockerTestDirectoryBindings.py
+++ b/docker/test/integration/cluster/DockerTestDirectoryBindings.py
@@ -42,6 +42,7 @@ class DockerTestDirectoryBindings:
             "input_dir": "/tmp/.nifi-test-input." + self.feature_id,
             "output_dir": "/tmp/.nifi-test-output." + self.feature_id,
             "resources_dir": "/tmp/.nifi-test-resources." + self.feature_id,
+            "system_certs_dir": "/tmp/.nifi-test-resources." + self.feature_id 
+ "/system_certs_dir",
             "minifi_config_dir": "/tmp/.nifi-test-minifi-config-dir." + 
self.feature_id,
             "nifi_config_dir": "/tmp/.nifi-test-nifi-config-dir." + 
self.feature_id,
             "kubernetes_temp_dir": "/tmp/.nifi-test-kubernetes-temp-dir." + 
self.feature_id,
@@ -87,6 +88,7 @@ class DockerTestDirectoryBindings:
         vols[self.data_directories[feature_id]["input_dir"]] = {"bind": 
"/tmp/input", "mode": "rw"}
         vols[self.data_directories[feature_id]["output_dir"]] = {"bind": 
"/tmp/output", "mode": "rw"}
         vols[self.data_directories[feature_id]["resources_dir"]] = {"bind": 
"/tmp/resources", "mode": "rw"}
+        vols[self.data_directories[feature_id]["system_certs_dir"]] = {"bind": 
"/usr/local/share/certs", "mode": "rw"}
         vols[self.data_directories[feature_id]["minifi_config_dir"]] = 
{"bind": "/tmp/minifi_config", "mode": "rw"}
         vols[self.data_directories[feature_id]["nifi_config_dir"]] = {"bind": 
"/tmp/nifi_config", "mode": "rw"}
         vols[self.data_directories[feature_id]["kubernetes_config_dir"]] = 
{"bind": "/tmp/kubernetes_config", "mode": "rw"}
diff --git a/docker/test/integration/features/MiNiFi_integration_test_driver.py 
b/docker/test/integration/features/MiNiFi_integration_test_driver.py
index cc774c1c2..ea0b2370d 100644
--- a/docker/test/integration/features/MiNiFi_integration_test_driver.py
+++ b/docker/test/integration/features/MiNiFi_integration_test_driver.py
@@ -22,7 +22,7 @@ import OpenSSL.crypto
 
 from pydoc import locate
 
-from ssl_utils.SSL_cert_utils import make_ca, make_cert_without_extended_usage
+from ssl_utils.SSL_cert_utils import make_self_signed_cert, 
make_cert_without_extended_usage, make_server_cert
 from minifi.core.InputPort import InputPort
 
 from cluster.DockerTestCluster import DockerTestCluster
@@ -52,22 +52,38 @@ class MiNiFi_integration_test:
 
         self.docker_directory_bindings = context.directory_bindings
         
self.cluster.set_directory_bindings(self.docker_directory_bindings.get_directory_bindings(self.feature_id),
 self.docker_directory_bindings.get_data_directories(self.feature_id))
-        self.root_ca_cert, self.root_ca_key = make_ca("root CA")
+        self.root_ca_cert, self.root_ca_key = make_self_signed_cert("root CA")
 
         minifi_client_cert, minifi_client_key = 
make_cert_without_extended_usage(common_name=f"minifi-cpp-flow-{self.feature_id}",
                                                                                
  ca_cert=self.root_ca_cert,
                                                                                
  ca_key=self.root_ca_key)
+        minifi_server_cert, minifi_server_key = 
make_server_cert(common_name=f"server-{self.feature_id}",
+                                                                 
ca_cert=self.root_ca_cert,
+                                                                 
ca_key=self.root_ca_key)
+        self_signed_server_cert, self_signed_server_key = 
make_self_signed_cert(f"server-{self.feature_id}")
+
         self.put_test_resource('root_ca.crt',
                                
OpenSSL.crypto.dump_certificate(type=OpenSSL.crypto.FILETYPE_PEM,
                                                                
cert=self.root_ca_cert))
-
+        self.put_test_resource("system_certs_dir/ca-root-nss.crt",
+                               
OpenSSL.crypto.dump_certificate(type=OpenSSL.crypto.FILETYPE_PEM,
+                                                               
cert=self.root_ca_cert))
         self.put_test_resource('minifi_client.crt',
                                
OpenSSL.crypto.dump_certificate(type=OpenSSL.crypto.FILETYPE_PEM,
                                                                
cert=minifi_client_cert))
         self.put_test_resource('minifi_client.key',
                                
OpenSSL.crypto.dump_privatekey(type=OpenSSL.crypto.FILETYPE_PEM,
                                                               
pkey=minifi_client_key))
-
+        self.put_test_resource('minifi_server.crt',
+                               
OpenSSL.crypto.dump_certificate(type=OpenSSL.crypto.FILETYPE_PEM,
+                                                               
cert=minifi_server_cert)
+                               + 
OpenSSL.crypto.dump_privatekey(type=OpenSSL.crypto.FILETYPE_PEM,
+                                                                
pkey=minifi_server_key))
+        self.put_test_resource('self_signed_server.crt',
+                               
OpenSSL.crypto.dump_certificate(type=OpenSSL.crypto.FILETYPE_PEM,
+                                                               
cert=self_signed_server_cert)
+                               + 
OpenSSL.crypto.dump_privatekey(type=OpenSSL.crypto.FILETYPE_PEM,
+                                                                
pkey=self_signed_server_key))
         self.put_test_resource('minifi_merged_cert.crt',
                                
OpenSSL.crypto.dump_certificate(type=OpenSSL.crypto.FILETYPE_PEM,
                                                                
cert=minifi_client_cert)
diff --git a/docker/test/integration/features/https.feature 
b/docker/test/integration/features/https.feature
index f7f3cae4f..f19e339d1 100644
--- a/docker/test/integration/features/https.feature
+++ b/docker/test/integration/features/https.feature
@@ -14,26 +14,155 @@
 # limitations under the License.
 
 @CORE
-Feature: Using SSL context service to send data with TLS
-  In order to send data via HTTPS
-  As a user of MiNiFi
-  I need to have access to the SSLContextService
+Feature: Transfer data from and to MiNiFi using HTTPS
 
   Background:
     Given the content of "/tmp/output" is monitored
 
-  Scenario: A MiNiFi instance sends data using InvokeHTTP to a receiver using 
ListenHTTP with TLS
-    Given a GetFile processor with the "Input Directory" property set to 
"/tmp/input"
-    And 200 files with the content "test" are present in "/tmp/input"
-    And a InvokeHTTP processor with the "Remote URL" property set to 
"https://secondary-${feature_id}:4430/contentListener";
+
+  Scenario: InvokeHTTP to ListenHTTP without an SSLContextService works (no 
mutual TLS in this case)
+    Given a GenerateFlowFile processor with the "Data Format" property set to 
"Text"
+    And the "Unique FlowFiles" property of the GenerateFlowFile processor is 
set to "false"
+    And the "Custom Text" property of the GenerateFlowFile processor is set to 
"Lorem ipsum dolor sit amet"
+    And a InvokeHTTP processor with the "Remote URL" property set to 
"https://server-${feature_id}:4430/contentListener";
     And the "HTTP Method" property of the InvokeHTTP processor is set to "POST"
+    And the "success" relationship of the GenerateFlowFile processor is 
connected to the InvokeHTTP
+
+    And a ListenHTTP processor with the "Listening Port" property set to 
"4430" in a "server" flow
+    And the "SSL Certificate" property of the ListenHTTP processor is set to 
"/tmp/resources/minifi_server.crt"
+    And a PutFile processor with the "Directory" property set to "/tmp/output" 
in the "server" flow
+    And the "success" relationship of the ListenHTTP processor is connected to 
the PutFile
+
+    When both instances start up
+    Then a flowfile with the content "Lorem ipsum dolor sit amet" is placed in 
the monitored directory in less than 10s
+
+
+  Scenario: InvokeHTTP to ListenHTTP without an SSLContextService requires a 
server cert signed by a CA
+    Given a GenerateFlowFile processor with the "Data Format" property set to 
"Text"
+    And the "Unique FlowFiles" property of the GenerateFlowFile processor is 
set to "false"
+    And the "Custom Text" property of the GenerateFlowFile processor is set to 
"consectetur adipiscing elit"
+    And a InvokeHTTP processor with the "Remote URL" property set to 
"https://server-${feature_id}:4430/contentListener";
+    And the "HTTP Method" property of the InvokeHTTP processor is set to "POST"
+    And the "success" relationship of the GenerateFlowFile processor is 
connected to the InvokeHTTP
+
+    And a ListenHTTP processor with the "Listening Port" property set to 
"4430" in a "server" flow
+    And the "SSL Certificate" property of the ListenHTTP processor is set to 
"/tmp/resources/self_signed_server.crt"
+    And a PutFile processor with the "Directory" property set to "/tmp/output" 
in the "server" flow
+    And the "success" relationship of the ListenHTTP processor is connected to 
the PutFile
+
+    When both instances start up
+    Then no files are placed in the monitored directory in 10s of running time
+
 
-    And the "success" relationship of the GetFile processor is connected to 
the InvokeHTTP
+  Scenario: InvokeHTTP to ListenHTTP without an SSLContextService works 
without a proper server cert if peer verification is disabled
+    Given a GenerateFlowFile processor with the "Data Format" property set to 
"Text"
+    And the "Unique FlowFiles" property of the GenerateFlowFile processor is 
set to "false"
+    And the "Custom Text" property of the GenerateFlowFile processor is set to 
"sed do eiusmod tempor incididunt"
+    And a InvokeHTTP processor with the "Remote URL" property set to 
"https://server-${feature_id}:4430/contentListener";
+    And the "HTTP Method" property of the InvokeHTTP processor is set to "POST"
+    And the "Disable Peer Verification" property of the InvokeHTTP processor 
is set to "true"
+    And the "success" relationship of the GenerateFlowFile processor is 
connected to the InvokeHTTP
+
+    And a ListenHTTP processor with the "Listening Port" property set to 
"4430" in a "server" flow
+    And the "SSL Certificate" property of the ListenHTTP processor is set to 
"/tmp/resources/self_signed_server.crt"
+    And a PutFile processor with the "Directory" property set to "/tmp/output" 
in the "server" flow
+    And the "success" relationship of the ListenHTTP processor is connected to 
the PutFile
+
+    When both instances start up
+    Then a flowfile with the content "sed do eiusmod tempor incididunt" is 
placed in the monitored directory in less than 10s
+
+
+  Scenario: InvokeHTTP to ListenHTTP with mutual TLS, using certificate files
+    Given a GenerateFlowFile processor with the "Data Format" property set to 
"Text"
+    And the "Unique FlowFiles" property of the GenerateFlowFile processor is 
set to "false"
+    And the "Custom Text" property of the GenerateFlowFile processor is set to 
"ut labore et dolore magna aliqua"
+    And a InvokeHTTP processor with the "Remote URL" property set to 
"https://server-${feature_id}:4430/contentListener";
+    And the "HTTP Method" property of the InvokeHTTP processor is set to "POST"
+    And an ssl context service with a manual CA cert file is set up for 
InvokeHTTP
+    And the "success" relationship of the GenerateFlowFile processor is 
connected to the InvokeHTTP
+
+    And a ListenHTTP processor with the "Listening Port" property set to 
"4430" in a "server" flow
+    And the "SSL Certificate" property of the ListenHTTP processor is set to 
"/tmp/resources/minifi_server.crt"
+    And the "SSL Certificate Authority" property of the ListenHTTP processor 
is set to "/usr/local/share/certs/ca-root-nss.crt"
+    And the "SSL Verify Peer" property of the ListenHTTP processor is set to 
"yes"
+    And a PutFile processor with the "Directory" property set to "/tmp/output" 
in the "server" flow
+    And the "success" relationship of the ListenHTTP processor is connected to 
the PutFile
+
+    When both instances start up
+    Then a flowfile with the content "ut labore et dolore magna aliqua" is 
placed in the monitored directory in less than 10s
+
+
+  Scenario: InvokeHTTP to ListenHTTP without mutual TLS, using the system 
certificate store
+    Given a GenerateFlowFile processor with the "Data Format" property set to 
"Text"
+    And the "Unique FlowFiles" property of the GenerateFlowFile processor is 
set to "false"
+    And the "Custom Text" property of the GenerateFlowFile processor is set to 
"Ut enim ad minim veniam"
+    And a InvokeHTTP processor with the "Remote URL" property set to 
"https://server-${feature_id}:4430/contentListener";
+    And the "HTTP Method" property of the InvokeHTTP processor is set to "POST"
+    And an ssl context service using the system CA cert store is set up for 
InvokeHTTP
+    And the "success" relationship of the GenerateFlowFile processor is 
connected to the InvokeHTTP
+
+    And a ListenHTTP processor with the "Listening Port" property set to 
"4430" in a "server" flow
+    And the "SSL Certificate" property of the ListenHTTP processor is set to 
"/tmp/resources/minifi_server.crt"
+    And a PutFile processor with the "Directory" property set to "/tmp/output" 
in the "server" flow
+    And the "success" relationship of the ListenHTTP processor is connected to 
the PutFile
+
+    When both instances start up
+    Then a flowfile with the content "Ut enim ad minim veniam" is placed in 
the monitored directory in less than 10s
+
+
+  Scenario: InvokeHTTP to ListenHTTP with mutual TLS, using the system 
certificate store
+    Given a GenerateFlowFile processor with the "Data Format" property set to 
"Text"
+    And the "Unique FlowFiles" property of the GenerateFlowFile processor is 
set to "false"
+    And the "Custom Text" property of the GenerateFlowFile processor is set to 
"quis nostrud exercitation ullamco laboris nisi"
+    And a InvokeHTTP processor with the "Remote URL" property set to 
"https://server-${feature_id}:4430/contentListener";
+    And the "HTTP Method" property of the InvokeHTTP processor is set to "POST"
+    And an ssl context service using the system CA cert store is set up for 
InvokeHTTP
+    And the "success" relationship of the GenerateFlowFile processor is 
connected to the InvokeHTTP
+
+    And a ListenHTTP processor with the "Listening Port" property set to 
"4430" in a "server" flow
+    And the "SSL Certificate" property of the ListenHTTP processor is set to 
"/tmp/resources/minifi_server.crt"
+    And the "SSL Certificate Authority" property of the ListenHTTP processor 
is set to "/usr/local/share/certs/ca-root-nss.crt"
+    And the "SSL Verify Peer" property of the ListenHTTP processor is set to 
"yes"
+    And a PutFile processor with the "Directory" property set to "/tmp/output" 
in the "server" flow
+    And the "success" relationship of the ListenHTTP processor is connected to 
the PutFile
+
+    When both instances start up
+    Then a flowfile with the content "quis nostrud exercitation ullamco 
laboris nisi" is placed in the monitored directory in less than 10s
+
+
+  Scenario: InvokeHTTP to ListenHTTP without mutual TLS, using the system 
certificate store, requires a server cert signed by a CA
+    Given a GenerateFlowFile processor with the "Data Format" property set to 
"Text"
+    And the "Unique FlowFiles" property of the GenerateFlowFile processor is 
set to "false"
+    And the "Custom Text" property of the GenerateFlowFile processor is set to 
"ut aliquip ex ea commodo consequat"
+    And a InvokeHTTP processor with the "Remote URL" property set to 
"https://server-${feature_id}:4430/contentListener";
+    And the "HTTP Method" property of the InvokeHTTP processor is set to "POST"
+    And an ssl context service using the system CA cert store is set up for 
InvokeHTTP
+    And the "success" relationship of the GenerateFlowFile processor is 
connected to the InvokeHTTP
+
+    And a ListenHTTP processor with the "Listening Port" property set to 
"4430" in a "server" flow
+    And the "SSL Certificate" property of the ListenHTTP processor is set to 
"/tmp/resources/self_signed_server.crt"
+    And a PutFile processor with the "Directory" property set to "/tmp/output" 
in the "server" flow
+    And the "success" relationship of the ListenHTTP processor is connected to 
the PutFile
+
+    When both instances start up
+    Then no files are placed in the monitored directory in 10s of running time
+
+
+  Scenario: InvokeHTTP to ListenHTTP with mutual TLS, using the system 
certificate store, requires a server cert signed by a CA
+    Given a GenerateFlowFile processor with the "Data Format" property set to 
"Text"
+    And the "Unique FlowFiles" property of the GenerateFlowFile processor is 
set to "false"
+    And the "Custom Text" property of the GenerateFlowFile processor is set to 
"Duis aute irure dolor in reprehenderit in voluptate"
+    And a InvokeHTTP processor with the "Remote URL" property set to 
"https://server-${feature_id}:4430/contentListener";
+    And the "HTTP Method" property of the InvokeHTTP processor is set to "POST"
+    And an ssl context service using the system CA cert store is set up for 
InvokeHTTP
+    And the "success" relationship of the GenerateFlowFile processor is 
connected to the InvokeHTTP
 
-    And a ListenHTTP processor with the "Listening Port" property set to 
"4430" in a "secondary" flow
-    And a PutFile processor with the "Directory" property set to "/tmp/output" 
in the "secondary" flow
+    And a ListenHTTP processor with the "Listening Port" property set to 
"4430" in a "server" flow
+    And the "SSL Certificate" property of the ListenHTTP processor is set to 
"/tmp/resources/self_signed_server.crt"
+    And the "SSL Certificate Authority" property of the ListenHTTP processor 
is set to "/usr/local/share/certs/ca-root-nss.crt"
+    And the "SSL Verify Peer" property of the ListenHTTP processor is set to 
"yes"
+    And a PutFile processor with the "Directory" property set to "/tmp/output" 
in the "server" flow
     And the "success" relationship of the ListenHTTP processor is connected to 
the PutFile
 
-    And an ssl context service set up for InvokeHTTP and ListenHTTP
     When both instances start up
-    Then 200 flowfiles with the content "test" are placed in the monitored 
directory in less than 60 seconds
+    Then no files are placed in the monitored directory in 10s of running time
diff --git a/docker/test/integration/features/kafka.feature 
b/docker/test/integration/features/kafka.feature
index 0a48b550d..7fcae658f 100644
--- a/docker/test/integration/features/kafka.feature
+++ b/docker/test/integration/features/kafka.feature
@@ -175,7 +175,7 @@ Feature: Sending data to using Kafka streaming platform 
using PublishKafka
       | PublishKafka   | Username               | alice                        
              |
       | PublishKafka   | Password               | alice-secret                 
              |
     And a PutFile processor with the "Directory" property set to "/tmp/output"
-    And an ssl context service set up for PublishKafka
+    And an ssl context service is set up for PublishKafka
     And the "success" relationship of the GetFile processor is connected to 
the PublishKafka
     And the "success" relationship of the PublishKafka processor is connected 
to the PutFile
 
@@ -200,7 +200,7 @@ Feature: Sending data to using Kafka streaming platform 
using PublishKafka
       | PublishKafka   | Message Timeout        | 12 sec                       
              |
       | PublishKafka   | Security Protocol      | ssl                          
              |
     And a PutFile processor with the "Directory" property set to "/tmp/output"
-    And an ssl context service set up for PublishKafka
+    And an ssl context service is set up for PublishKafka
     And the "success" relationship of the GetFile processor is connected to 
the PublishKafka
     And the "success" relationship of the PublishKafka processor is connected 
to the PutFile
 
@@ -414,7 +414,7 @@ Feature: Sending data to using Kafka streaming platform 
using PublishKafka
       | ConsumeKafka   | Kafka Brokers        | 
kafka-broker-${feature_id}:9093            |
       | ConsumeKafka   | Security Protocol    | ssl                            
            |
     And a PutFile processor with the "Directory" property set to "/tmp/output" 
in the "kafka-consumer-flow" flow
-    And an ssl context service set up for ConsumeKafka
+    And an ssl context service is set up for ConsumeKafka
     And the "success" relationship of the ConsumeKafka processor is connected 
to the PutFile
 
     And a kafka broker is set up in correspondence with the publisher flow
@@ -435,7 +435,7 @@ Feature: Sending data to using Kafka streaming platform 
using PublishKafka
       | ConsumeKafka   | Username             | alice                          
            |
       | ConsumeKafka   | Password             | alice-secret                   
            |
     And a PutFile processor with the "Directory" property set to "/tmp/output" 
in the "kafka-consumer-flow" flow
-    And an ssl context service set up for ConsumeKafka
+    And an ssl context service is set up for ConsumeKafka
     And the "success" relationship of the ConsumeKafka processor is connected 
to the PutFile
 
     And a kafka broker is set up in correspondence with the publisher flow
diff --git a/docker/test/integration/features/steps/steps.py 
b/docker/test/integration/features/steps/steps.py
index d4cbfb15a..b52862ffa 100644
--- a/docker/test/integration/features/steps/steps.py
+++ b/docker/test/integration/features/steps/steps.py
@@ -371,34 +371,27 @@ def step_impl(context):
 
 
 # TLS
-@given("an ssl context service set up for {producer_name} and {consumer_name}")
-def step_impl(context, producer_name, consumer_name):
-    minifi_crt_file = '/tmp/resources/minifi_client.crt'
-    minifi_key_file = '/tmp/resources/minifi_client.key'
-    root_ca_crt_file = '/tmp/resources/root_ca.crt'
-    ssl_context_service = SSLContextService(cert=minifi_crt_file, 
ca_cert=root_ca_crt_file, key=minifi_key_file)
+@given("an ssl context service is set up for {processor_name}")
+@given("an ssl context service with a manual CA cert file is set up for 
{processor_name}")
+def step_impl(context, processor_name):
+    ssl_context_service = 
SSLContextService(cert='/tmp/resources/minifi_client.crt',
+                                            
key='/tmp/resources/minifi_client.key',
+                                            
ca_cert='/tmp/resources/root_ca.crt')
 
-    secondary_cert, secondary_key = 
make_server_cert(context.test.get_container_name_with_postfix("secondary"), 
context.test.root_ca_cert, context.test.root_ca_key)
-    secondary_pem_file = '/tmp/resources/secondary.crt'
-    context.test.put_test_resource('secondary.crt', 
OpenSSL.crypto.dump_certificate(type=OpenSSL.crypto.FILETYPE_PEM, 
cert=secondary_cert) + 
OpenSSL.crypto.dump_privatekey(type=OpenSSL.crypto.FILETYPE_PEM, 
pkey=secondary_key))
-    producer = context.test.get_node_by_name(producer_name)
-    producer.controller_services.append(ssl_context_service)
-    producer.set_property("SSL Context Service", ssl_context_service.name)
-    consumer = context.test.get_node_by_name(consumer_name)
-    consumer.set_property("SSL Certificate Authority", root_ca_crt_file)
-    consumer.set_property("SSL Certificate", secondary_pem_file)
-    consumer.set_property("SSL Verify Peer", "yes")
+    processor = context.test.get_node_by_name(processor_name)
+    processor.controller_services.append(ssl_context_service)
+    processor.set_property('SSL Context Service', ssl_context_service.name)
 
 
-@given("an ssl context service set up for {producer_name}")
-def step_impl(context, producer_name):
-    minifi_crt_file = '/tmp/resources/minifi_client.crt'
-    minifi_key_file = '/tmp/resources/minifi_client.key'
-    root_ca_crt_file = '/tmp/resources/root_ca.crt'
-    ssl_context_service = SSLContextService(cert=minifi_crt_file, 
ca_cert=root_ca_crt_file, key=minifi_key_file)
-    producer = context.test.get_node_by_name(producer_name)
-    producer.controller_services.append(ssl_context_service)
-    producer.set_property("SSL Context Service", ssl_context_service.name)
+@given("an ssl context service using the system CA cert store is set up for 
{processor_name}")
+def step_impl(context, processor_name):
+    ssl_context_service = 
SSLContextService(cert='/tmp/resources/minifi_client.crt',
+                                            
key='/tmp/resources/minifi_client.key',
+                                            use_system_cert_store='true')
+
+    processor = context.test.get_node_by_name(processor_name)
+    processor.controller_services.append(ssl_context_service)
+    processor.set_property('SSL Context Service', ssl_context_service.name)
 
 
 # Kubernetes
diff --git a/docker/test/integration/minifi/controllers/SSLContextService.py 
b/docker/test/integration/minifi/controllers/SSLContextService.py
index 01ff7b5ac..af16368f3 100644
--- a/docker/test/integration/minifi/controllers/SSLContextService.py
+++ b/docker/test/integration/minifi/controllers/SSLContextService.py
@@ -18,7 +18,7 @@ from ..core.ControllerService import ControllerService
 
 
 class SSLContextService(ControllerService):
-    def __init__(self, name=None, cert=None, key=None, ca_cert=None, 
passphrase=None):
+    def __init__(self, name=None, cert=None, key=None, ca_cert=None, 
passphrase=None, use_system_cert_store=None):
         super(SSLContextService, self).__init__(name=name)
 
         self.service_class = 'SSLContextService'
@@ -34,3 +34,6 @@ class SSLContextService(ControllerService):
 
         if passphrase is not None:
             self.properties['Passphrase'] = passphrase
+
+        if use_system_cert_store is not None:
+            self.properties['Use System Cert Store'] = use_system_cert_store
diff --git a/docker/test/integration/ssl_utils/SSL_cert_utils.py 
b/docker/test/integration/ssl_utils/SSL_cert_utils.py
index 113071e48..d39cf9646 100644
--- a/docker/test/integration/ssl_utils/SSL_cert_utils.py
+++ b/docker/test/integration/ssl_utils/SSL_cert_utils.py
@@ -75,7 +75,7 @@ def gen_req():
     return req, key
 
 
-def make_ca(common_name):
+def make_self_signed_cert(common_name):
     ca_key = crypto.PKey()
     ca_key.generate_key(crypto.TYPE_RSA, 2048)
 
diff --git a/extensions/aws/processors/S3Processor.cpp 
b/extensions/aws/processors/S3Processor.cpp
index bf0b9d184..0d6e983e5 100644
--- a/extensions/aws/processors/S3Processor.cpp
+++ b/extensions/aws/processors/S3Processor.cpp
@@ -126,9 +126,9 @@ void S3Processor::onSchedule(const 
std::shared_ptr<core::ProcessContext>& contex
     throw Exception(PROCESS_SCHEDULE_EXCEPTION, "Communications Timeout 
missing or invalid");
   }
 
-  static const auto default_ca_path = minifi::utils::getDefaultCAPath();
-  if (default_ca_path) {
-    client_config_->caFile = default_ca_path->string();
+  static const auto default_ca_file = minifi::utils::getDefaultCAFile();
+  if (default_ca_file) {
+    client_config_->caFile = *default_ca_file;
   }
 }
 
diff --git a/extensions/http-curl/client/HTTPClient.cpp 
b/extensions/http-curl/client/HTTPClient.cpp
index f375dc772..af131f3d6 100644
--- a/extensions/http-curl/client/HTTPClient.cpp
+++ b/extensions/http-curl/client/HTTPClient.cpp
@@ -44,8 +44,8 @@ HTTPClient::HTTPClient(std::string url, 
std::shared_ptr<minifi::controllers::SSL
   http_session_.reset(curl_easy_init());
 }
 
-HTTPClient::HTTPClient(std::string name, const utils::Identifier& uuid)
-    : core::Connectable(std::move(name), uuid) {
+HTTPClient::HTTPClient(std::string_view name, const utils::Identifier& uuid)
+    : core::Connectable(name, uuid) {
   http_session_.reset(curl_easy_init());
 }
 
@@ -125,7 +125,11 @@ void HTTPClient::initialize(std::string method, 
std::string url, std::shared_ptr
 }
 
 void HTTPClient::setPeerVerification(bool peer_verification) {
-  logger_->log_debug("%s peer verification", peer_verification ? "Enabling" : 
"Disabling");
+  if (peer_verification) {
+    logger_->log_debug("Enabling peer verification");
+  } else {
+    logger_->log_warn("Disabling peer verification: the authenticity of https 
servers will not be verified!");
+  }
   curl_easy_setopt(http_session_.get(), CURLOPT_SSL_VERIFYPEER, 
peer_verification);
 }
 
@@ -458,26 +462,22 @@ int HTTPClient::onProgress(void *clientp, curl_off_t 
/*dltotal*/, curl_off_t dln
 void HTTPClient::configure_secure_connection() {
 #ifdef OPENSSL_SUPPORT
   if (ssl_context_service_) {
-    logger_->log_debug("Using certificate file \"%s\"", 
ssl_context_service_->getCertificateFile().string());
-    logger_->log_debug("Using private key file \"%s\"", 
ssl_context_service_->getPrivateKeyFile().string());
-    logger_->log_debug("Using CA certificate file \"%s\"", 
ssl_context_service_->getCACertificate().string());
-
     curl_easy_setopt(http_session_.get(), CURLOPT_SSL_CTX_FUNCTION, 
&configure_ssl_context);
     curl_easy_setopt(http_session_.get(), CURLOPT_SSL_CTX_DATA, 
static_cast<void *>(ssl_context_service_.get()));
     curl_easy_setopt(http_session_.get(), CURLOPT_CAINFO, nullptr);
     curl_easy_setopt(http_session_.get(), CURLOPT_CAPATH, nullptr);
   } else {
-    static const auto default_ca_path = utils::getDefaultCAPath();
+    static const auto default_ca_file = utils::getDefaultCAFile();
 
-    if (default_ca_path)
-      logger_->log_debug("Using CA certificate file \"%s\"", 
default_ca_path->string());
+    if (default_ca_file)
+      logger_->log_debug("Using CA certificate file \"%s\"", 
std::string(*default_ca_file));
     else
       logger_->log_error("Could not find valid CA certificate file");
 
     curl_easy_setopt(http_session_.get(), CURLOPT_SSL_CTX_FUNCTION, nullptr);
     curl_easy_setopt(http_session_.get(), CURLOPT_SSL_CTX_DATA, nullptr);
-    if (default_ca_path)
-      curl_easy_setopt(http_session_.get(), CURLOPT_CAINFO, 
default_ca_path->string().c_str());
+    if (default_ca_file)
+      curl_easy_setopt(http_session_.get(), CURLOPT_CAINFO, 
std::string(*default_ca_file).c_str());
     else
       curl_easy_setopt(http_session_.get(), CURLOPT_CAINFO, nullptr);
     curl_easy_setopt(http_session_.get(), CURLOPT_CAPATH, nullptr);
diff --git a/extensions/http-curl/client/HTTPClient.h 
b/extensions/http-curl/client/HTTPClient.h
index 30c10f486..2e98bab67 100644
--- a/extensions/http-curl/client/HTTPClient.h
+++ b/extensions/http-curl/client/HTTPClient.h
@@ -68,7 +68,7 @@ class HTTPClient : public utils::BaseHTTPClient, public 
core::Connectable {
  public:
   HTTPClient();
 
-  HTTPClient(std::string name, const utils::Identifier& uuid);
+  HTTPClient(std::string_view name, const utils::Identifier& uuid);
 
   HTTPClient(const HTTPClient&) = delete;
   HTTPClient& operator=(const HTTPClient&) = delete;
diff --git a/extensions/http-curl/processors/InvokeHTTP.cpp 
b/extensions/http-curl/processors/InvokeHTTP.cpp
index b9f1799c4..eab6d0804 100644
--- a/extensions/http-curl/processors/InvokeHTTP.cpp
+++ b/extensions/http-curl/processors/InvokeHTTP.cpp
@@ -72,7 +72,7 @@ void setupClientProxy(extensions::curl::HTTPClient& client, 
const core::ProcessC
 
 void setupClientPeerVerification(extensions::curl::HTTPClient& client, const 
core::ProcessContext& context) {
   if (auto disable_peer_verification = 
context.getProperty(InvokeHTTP::DisablePeerVerification) | 
utils::flatMap(&utils::StringUtils::toBool)) {
-    client.setPeerVerification(*disable_peer_verification);
+    client.setPeerVerification(!*disable_peer_verification);
   }
 }
 
diff --git a/extensions/http-curl/tests/VerifyInvokeHTTPGetTest.cpp 
b/extensions/http-curl/tests/VerifyInvokeHTTPGetTest.cpp
index 9b923fba1..c509877d2 100644
--- a/extensions/http-curl/tests/VerifyInvokeHTTPGetTest.cpp
+++ b/extensions/http-curl/tests/VerifyInvokeHTTPGetTest.cpp
@@ -20,8 +20,6 @@
 #include "HTTPHandlers.h"
 #include "utils/IntegrationTestUtils.h"
 
-#define CURLOPT_SSL_VERIFYPEER_DISABLE 1
-
 class VerifyHTTPGet : public VerifyInvokeHTTP {
  public:
   void runAssertions() override {
diff --git a/libminifi/include/utils/HTTPUtils.h 
b/libminifi/include/utils/HTTPUtils.h
index f748b1d54..3aa5bd3df 100644
--- a/libminifi/include/utils/HTTPUtils.h
+++ b/libminifi/include/utils/HTTPUtils.h
@@ -19,8 +19,8 @@
 #pragma once
 
 #include <string>
+#include <string_view>
 #include <optional>
-#include <filesystem>
 
 #include "io/ClientSocket.h"
 #include "utils/RegexUtils.h"
@@ -52,6 +52,6 @@ inline bool parse_http_components(const std::string &url, 
std::string &port, std
   return false;
 }
 
-std::optional<std::filesystem::path> getDefaultCAPath();
+std::optional<std::string_view> getDefaultCAFile();
 
 }  // namespace org::apache::nifi::minifi::utils
diff --git a/libminifi/src/controllers/SSLContextService.cpp 
b/libminifi/src/controllers/SSLContextService.cpp
index 32a697ead..1631fcaed 100644
--- a/libminifi/src/controllers/SSLContextService.cpp
+++ b/libminifi/src/controllers/SSLContextService.cpp
@@ -36,6 +36,7 @@
 #include "core/Resource.h"
 #include "io/validation.h"
 #include "properties/Configure.h"
+#include "utils/HTTPUtils.h"
 #include "utils/tls/CertificateUtils.h"
 #include "utils/tls/TLSUtils.h"
 #include "utils/tls/DistinguishedName.h"
@@ -313,7 +314,12 @@ bool 
SSLContextService::addServerCertificatesFromSystemStoreToSSLContext(SSL_CTX
 
   return true;
 #else
-  SSL_CTX_set_default_verify_paths(ctx);
+  static const auto default_ca_file = utils::getDefaultCAFile();
+  if (default_ca_file) {
+    SSL_CTX_load_verify_file(ctx, std::string(*default_ca_file).c_str());
+  } else {
+    SSL_CTX_set_default_verify_paths(ctx);
+  }
   return true;
 #endif  // WIN32
 }
@@ -498,6 +504,11 @@ void SSLContextService::onEnable() {
   client_cert_key_usage_ = utils::tls::ExtendedKeyUsage{client_cert_key_usage};
 #endif  // WIN32
 
+  logger_->log_debug("Using certificate file \"%s\"", certificate_.string());
+  logger_->log_debug("Using private key file \"%s\"", private_key_.string());
+  logger_->log_debug("Using CA certificate file \"%s\"", 
ca_certificate_.string());
+  logger_->log_debug("Using the system cert store: %s", use_system_cert_store_ 
? "yes" : "no");
+
   verifyCertificateExpiration();
 }
 
diff --git a/libminifi/src/utils/HTTPUtils.cpp 
b/libminifi/src/utils/HTTPUtils.cpp
index 30b84150f..96219e7cd 100644
--- a/libminifi/src/utils/HTTPUtils.cpp
+++ b/libminifi/src/utils/HTTPUtils.cpp
@@ -17,17 +17,18 @@
  */
 #include "utils/HTTPUtils.h"
 
-#include <vector>
+#include <array>
+#include <filesystem>
 
 namespace org::apache::nifi::minifi::utils {
 
-std::optional<std::filesystem::path> getDefaultCAPath() {
+std::optional<std::string_view> getDefaultCAFile() {
 #ifndef WIN32
-  const std::vector<std::filesystem::path> possible_ca_paths = {
+  static constexpr std::array<std::string_view, 5> possible_ca_paths = {
+      "/usr/local/share/certs/ca-root-nss.crt",
       "/etc/ssl/certs/ca-certificates.crt",
       "/etc/pki/tls/certs/ca-bundle.crt",
       "/usr/share/ssl/certs/ca-bundle.crt",
-      "/usr/local/share/certs/ca-root-nss.crt",
       "/etc/ssl/cert.pem"
   };
 


Reply via email to