forked from cloudfoundry/java-buildpack
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This change adds a framework that provides a Java trust store containing the certificates trusted by the container's operating system. This feature is disabled by default, as it requires around 45 seconds to process the 173 default certificates. [#76531562]
- Loading branch information
Showing
9 changed files
with
343 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Cloud Foundry Java Buildpack | ||
# Copyright 2014-2015 the original author or authors. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
# Container certificate truststore configuration | ||
--- | ||
enabled: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Container Certificate Trust Store Framework | ||
The Container Certificate Trust Store Framework contributes a Java `KeyStore` containing the certificates trusted by the operating system in the container to the application at rutime. | ||
|
||
<table> | ||
<tr> | ||
<td><strong>Detection Criterion</strong></td> | ||
<td>Existence of a <tt>/etc/ssl/certs/ca-certificates.crt</tt> file and <tt>enabled</tt> set in the <tt>config/container_certificate_trust_store.yml</tt> file</td> | ||
</tr> | ||
<tr> | ||
<td><strong>Tags</strong></td> | ||
<td><tt>container-certificate-trust-store=<number-of-certificates></tt></td> | ||
</tr> | ||
</table> | ||
Tags are printed to standard output by the buildpack detect script | ||
|
||
## Configuration | ||
For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. | ||
|
||
The framework can be configured by creating or modifying the [`config/container_certificate_trust_store.yml`][] file in the buildpack fork. | ||
|
||
| Name | Description | ||
| ---- | ----------- | ||
| `enabled` | Whether to enable the trust store | ||
|
||
[`config/container_certificate_trust_store.yml`]: ../config/container_certificate_trust_store.yml | ||
[Configuration and Extension]: ../README.md#configuration-and-extension |
137 changes: 137 additions & 0 deletions
137
lib/java_buildpack/framework/container_certificate_trust_store.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
# Encoding: utf-8 | ||
# Cloud Foundry Java Buildpack | ||
# Copyright 2013-2016 the original author or authors. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
require 'java_buildpack/component/base_component' | ||
require 'java_buildpack/framework' | ||
require 'java_buildpack/util/dash_case' | ||
require 'java_buildpack/util/format_duration' | ||
require 'fileutils' | ||
require 'shellwords' | ||
require 'tempfile' | ||
|
||
module JavaBuildpack | ||
module Framework | ||
|
||
# Encapsulates the functionality for contributing container-based certificates to an application. | ||
class ContainerCertificateTrustStore < JavaBuildpack::Component::BaseComponent | ||
|
||
# Creates an instance | ||
# | ||
# @param [Hash] context a collection of utilities used the component | ||
def initialize(context) | ||
@logger = JavaBuildpack::Logging::LoggerFactory.instance.get_logger ContainerCertificateTrustStore | ||
super(context) | ||
end | ||
|
||
# (see JavaBuildpack::Component::BaseComponent#detect) | ||
def detect | ||
(supports_configuration? && supports_file?) ? id(certificates.length) : nil | ||
end | ||
|
||
# (see JavaBuildpack::Component::BaseComponent#compile) | ||
def compile | ||
puts '-----> Creating TrustStore with container certificates' | ||
|
||
resolved_certificates = certificates | ||
with_timing(caption(resolved_certificates)) do | ||
FileUtils.mkdir_p trust_store.parent | ||
resolved_certificates.each_with_index { |certificate, index| add_certificate certificate, index } | ||
end | ||
end | ||
|
||
# (see JavaBuildpack::Component::BaseComponent#release) | ||
def release | ||
@droplet.java_opts | ||
.add_system_property('javax.net.ssl.trustStore', trust_store) | ||
.add_system_property('javax.net.ssl.trustStorePassword', password) | ||
end | ||
|
||
private | ||
|
||
CA_CERTIFICATES = Pathname.new('/etc/ssl/certs/ca-certificates.crt').freeze | ||
|
||
private_constant :CA_CERTIFICATES | ||
|
||
def add_certificate(certificate, index) | ||
@logger.debug { "Adding certificate\n#{certificate}" } | ||
|
||
file = write_certificate certificate | ||
shell "#{keytool} -importcert -noprompt -keystore #{trust_store} -storepass #{password} " \ | ||
"-file #{file.to_path} -alias certificate-#{index}" | ||
end | ||
|
||
def ca_certificates | ||
CA_CERTIFICATES | ||
end | ||
|
||
def caption(resolved_certificates) | ||
"Adding #{resolved_certificates.count} certificates to #{trust_store.relative_path_from(@droplet.root)}" | ||
end | ||
|
||
def certificates | ||
certificates = [] | ||
|
||
certificate = nil | ||
ca_certificates.each_line do |line| | ||
if line =~ /BEGIN CERTIFICATE/ | ||
certificate = line | ||
elsif line =~ /END CERTIFICATE/ | ||
certificate += line | ||
certificates << certificate | ||
certificate = nil | ||
elsif !certificate.nil? | ||
certificate += line | ||
end | ||
end | ||
|
||
certificates | ||
end | ||
|
||
def id(count) | ||
"#{self.class.to_s.dash_case}=#{count}" | ||
end | ||
|
||
def keytool | ||
@droplet.java_home.root + 'bin/keytool' | ||
end | ||
|
||
def password | ||
'java-buildpack-trust-store-password' | ||
end | ||
|
||
def supports_configuration? | ||
@configuration['enabled'] | ||
end | ||
|
||
def supports_file? | ||
ca_certificates.exist? | ||
end | ||
|
||
def trust_store | ||
@droplet.sandbox + 'truststore.jks' | ||
end | ||
|
||
def write_certificate(certificate) | ||
file = Tempfile.new('certificate-') | ||
file.write(certificate) | ||
file.fsync | ||
file | ||
end | ||
|
||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
## | ||
## Bundle of CA Root Certificates | ||
## | ||
## Certificate data from Mozilla as of: Wed Jan 20 04:12:04 2016 | ||
## | ||
## This is a bundle of X.509 certificates of public Certificate Authorities | ||
## (CA). These were automatically extracted from Mozilla's root certificates | ||
## file (certdata.txt). This file can be found in the mozilla source tree: | ||
## http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt | ||
## | ||
## It contains the certificates in PEM format and therefore | ||
## can be directly used with curl / libcurl / php_curl, or with | ||
## an Apache+mod_ssl webserver for SSL client authentication. | ||
## Just configure this file as the SSLCACertificateFile. | ||
## | ||
## Conversion done with mk-ca-bundle.pl version 1.25. | ||
## SHA1: 0ab47e2f41518f8d223eab517cb799e5b071231e | ||
## | ||
|
||
|
||
GlobalSign Root CA | ||
================== | ||
-----BEGIN CERTIFICATE----- | ||
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx | ||
GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds | ||
b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV | ||
BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD | ||
VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa | ||
DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc | ||
THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb | ||
Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP | ||
c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX | ||
gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV | ||
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF | ||
AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj | ||
Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG | ||
j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH | ||
hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC | ||
X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== | ||
-----END CERTIFICATE----- | ||
|
||
GlobalSign Root CA - R2 | ||
======================= | ||
-----BEGIN CERTIFICATE----- | ||
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv | ||
YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh | ||
bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT | ||
aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln | ||
bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 | ||
ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp | ||
s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN | ||
S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL | ||
TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C | ||
ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E | ||
FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i | ||
YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN | ||
BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp | ||
9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu | ||
01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 | ||
9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 | ||
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== | ||
-----END CERTIFICATE----- | ||
|
||
CA WoSign ECC Root | ||
================== | ||
-----BEGIN CERTIFICATE----- | ||
MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQswCQYDVQQGEwJD | ||
TjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMTEkNBIFdvU2lnbiBFQ0MgUm9v | ||
dDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQK | ||
ExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZI | ||
zj0CAQYFK4EEACIDYgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiU | ||
t5v8KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES1ns2o0Iw | ||
QDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqv3VWqP2h4syhf3R | ||
MluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0 | ||
Daupn75OcsqF1NnstTJFGG+rrQIwfcf3aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYu | ||
a/GRspBl9JrmkO5K | ||
-----END CERTIFICATE----- |
78 changes: 78 additions & 0 deletions
78
spec/java_buildpack/framework/container_certificate_trust_store_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# Encoding: utf-8 | ||
# Cloud Foundry Java Buildpack | ||
# Copyright 2013-2016 the original author or authors. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
require 'spec_helper' | ||
require 'component_helper' | ||
require 'java_buildpack/framework/container_certificate_trust_store' | ||
|
||
describe JavaBuildpack::Framework::ContainerCertificateTrustStore do | ||
include_context 'component_helper' | ||
|
||
let(:ca_certificates) { Pathname.new('spec/fixtures/ca-certificates.crt') } | ||
|
||
let(:configuration) { { 'enabled' => true } } | ||
|
||
it 'detects with ca-certificates file' do | ||
allow(component).to receive(:ca_certificates).and_return(ca_certificates) | ||
|
||
expect(component.detect).to eq('container-certificate-trust-store=3') | ||
end | ||
|
||
it 'does not detect without ca-certificates file' do | ||
allow(component).to receive(:ca_certificates).and_return(Pathname.new('spec/fixtures/ca-certificates-no-exist.crt')) | ||
|
||
expect(component.detect).to be_nil | ||
end | ||
|
||
context do | ||
let(:configuration) { { 'enabled' => false } } | ||
|
||
it 'does not detect when disabled' do | ||
allow(component).to receive(:ca_certificates).and_return(ca_certificates) | ||
|
||
expect(component.detect).to be_nil | ||
end | ||
end | ||
|
||
it 'creates truststore' do | ||
allow(component).to receive(:ca_certificates).and_return(ca_certificates) | ||
allow(component).to receive(:write_certificate).and_return(Pathname.new('/certificate-0'), | ||
Pathname.new('/certificate-1'), | ||
Pathname.new('/certificate-2')) | ||
allow(component).to receive(:shell).with("#{java_home.root}/bin/keytool -importcert -noprompt " \ | ||
"-keystore #{sandbox}/truststore.jks -storepass " \ | ||
'java-buildpack-trust-store-password -file /certificate-0 -alias ' \ | ||
'certificate-0') | ||
allow(component).to receive(:shell).with("#{java_home.root}/bin/keytool -importcert -noprompt " \ | ||
"-keystore #{sandbox}/truststore.jks -storepass " \ | ||
'java-buildpack-trust-store-password -file /certificate-1 -alias ' \ | ||
'certificate-1') | ||
allow(component).to receive(:shell).with("#{java_home.root}/bin/keytool -importcert -noprompt " \ | ||
"-keystore #{sandbox}/truststore.jks -storepass " \ | ||
'java-buildpack-trust-store-password -file /certificate-2 -alias ' \ | ||
'certificate-2') | ||
|
||
component.compile | ||
end | ||
|
||
it 'adds truststore properties' do | ||
component.release | ||
expect(java_opts).to include('-Djavax.net.ssl.trustStore=$PWD/.java-buildpack/container_certificate_trust_store/' \ | ||
'truststore.jks') | ||
expect(java_opts).to include('-Djavax.net.ssl.trustStorePassword=java-buildpack-trust-store-password') | ||
end | ||
|
||
end |