Skip to content

Commit 79a6ffa

Browse files
(maint) Merge up 6182816 to main
Generated by CI * commit '6182816977325d83f1a5e88622087884628c3344': (PUP-11471) Allow to trust system CA in a Puppet SSL Context (PUP-11471) Make using default path an option of create_x509_store
2 parents 1b8c8a1 + 6182816 commit 79a6ffa

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

lib/puppet/ssl/ssl_provider.rb

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ def create_root_context(cacerts:, crls: [], revocation: Puppet[:certificate_revo
6868
# @raise (see #create_context)
6969
# @api private
7070
def create_system_context(cacerts:, path: Puppet[:ssl_trust_store])
71-
store = create_x509_store(cacerts, [], false)
72-
store.set_default_paths
71+
store = create_x509_store(cacerts, [], false, include_system_store: true)
7372

7473
if path
7574
stat = Puppet::FileSystem.stat(path)
@@ -111,19 +110,20 @@ def create_system_context(cacerts:, path: Puppet[:ssl_trust_store])
111110
# @param client_cert [OpenSSL::X509::Certificate] client's cert whose public
112111
# key matches the `private_key`
113112
# @param revocation [:chain, :leaf, false] revocation mode
113+
# @param include_system_store [true, false] Also trust system CA
114114
# @return [Puppet::SSL::SSLContext] A context to use to create connections
115115
# @raise [Puppet::SSL::CertVerifyError] There was an issue with
116116
# one of the certs or CRLs.
117117
# @raise [Puppet::SSL::SSLError] There was an issue with the
118118
# `private_key`.
119119
# @api private
120-
def create_context(cacerts:, crls:, private_key:, client_cert:, revocation: Puppet[:certificate_revocation])
120+
def create_context(cacerts:, crls:, private_key:, client_cert:, revocation: Puppet[:certificate_revocation], include_system_store: false)
121121
raise ArgumentError, _("CA certs are missing") unless cacerts
122122
raise ArgumentError, _("CRLs are missing") unless crls
123123
raise ArgumentError, _("Private key is missing") unless private_key
124124
raise ArgumentError, _("Client cert is missing") unless client_cert
125125

126-
store = create_x509_store(cacerts, crls, revocation)
126+
store = create_x509_store(cacerts, crls, revocation, include_system_store: include_system_store)
127127
client_chain = verify_cert_with_store(store, client_cert)
128128

129129
if !private_key.is_a?(OpenSSL::PKey::RSA) && !private_key.is_a?(OpenSSL::PKey::EC)
@@ -151,12 +151,13 @@ def create_context(cacerts:, crls:, private_key:, client_cert:, revocation: Pupp
151151
# @param password [String, nil] If the private key is encrypted, decrypt
152152
# it using the password. If the key is encrypted, but a password is
153153
# not specified, then the key cannot be loaded.
154+
# @param include_system_store [true, false] Also trust system CA
154155
# @return [Puppet::SSL::SSLContext] A context to use to create connections
155156
# @raise [Puppet::SSL::CertVerifyError] There was an issue with
156157
# one of the certs or CRLs.
157158
# @raise [Puppet::Error] There was an issue with one of the required components.
158159
# @api private
159-
def load_context(certname: Puppet[:certname], revocation: Puppet[:certificate_revocation], password: nil)
160+
def load_context(certname: Puppet[:certname], revocation: Puppet[:certificate_revocation], password: nil, include_system_store: false)
160161
cert = Puppet::X509::CertProvider.new
161162
cacerts = cert.load_cacerts(required: true)
162163
crls = case revocation
@@ -168,7 +169,7 @@ def load_context(certname: Puppet[:certname], revocation: Puppet[:certificate_re
168169
private_key = cert.load_private_key(certname, required: true, password: password)
169170
client_cert = cert.load_client_cert(certname, required: true)
170171

171-
create_context(cacerts: cacerts, crls: crls, private_key: private_key, client_cert: client_cert, revocation: revocation)
172+
create_context(cacerts: cacerts, crls: crls, private_key: private_key, client_cert: client_cert, revocation: revocation, include_system_store: include_system_store)
172173
rescue OpenSSL::PKey::PKeyError => e
173174
raise Puppet::SSL::SSLError.new(_("Failed to load private key for host '%{name}': %{message}") % { name: certname, message: e.message }, e)
174175
end
@@ -203,14 +204,16 @@ def default_flags
203204
end
204205
end
205206

206-
def create_x509_store(roots, crls, revocation)
207+
def create_x509_store(roots, crls, revocation, include_system_store: false)
207208
store = OpenSSL::X509::Store.new
208209
store.purpose = OpenSSL::X509::PURPOSE_ANY
209210
store.flags = default_flags | revocation_mode(revocation)
210211

211212
roots.each { |cert| store.add_cert(cert) }
212213
crls.each { |crl| store.add_crl(crl) }
213214

215+
store.set_default_paths if include_system_store
216+
214217
store
215218
end
216219

spec/integration/http/client_spec.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@
7777
}
7878
}
7979

80+
let(:systemstore) do
81+
res = tmpfile('systemstore')
82+
File.write(res, https_server.ca_cert)
83+
res
84+
end
85+
8086
it "mutually authenticates the connection" do
8187
client_context = ssl_provider.create_context(
8288
cacerts: [https_server.ca_cert], crls: [https_server.ca_crl],
@@ -88,6 +94,30 @@
8894
expect(res).to be_success
8995
end
9096
end
97+
98+
it "connects when the server's CA is in the system store and the connection is mutually authenticated using create_context" do
99+
Puppet::Util.withenv("SSL_CERT_FILE" => systemstore) do
100+
client_context = ssl_provider.create_context(
101+
cacerts: [https_server.ca_cert], crls: [https_server.ca_crl],
102+
client_cert: https_server.server_cert, private_key: https_server.server_key,
103+
revocation: false, include_system_store: true
104+
)
105+
https_server.start_server(ctx_proc: ctx_proc) do |port|
106+
res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: client_context})
107+
expect(res).to be_success
108+
end
109+
end
110+
end
111+
112+
it "connects when the server's CA is in the system store and the connection is mutually authenticated uning load_context" do
113+
Puppet::Util.withenv("SSL_CERT_FILE" => systemstore) do
114+
client_context = ssl_provider.load_context(revocation: false, include_system_store: true)
115+
https_server.start_server(ctx_proc: ctx_proc) do |port|
116+
res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: client_context})
117+
expect(res).to be_success
118+
end
119+
end
120+
end
91121
end
92122

93123
context "with a system trust store" do

0 commit comments

Comments
 (0)