From f1db5e063c8c533c8604ff6ced4d3afa6cfb6d12 Mon Sep 17 00:00:00 2001 From: Tony Clarke <36965832+tony-clarke-amdocs@users.noreply.github.com> Date: Fri, 5 Oct 2018 18:30:21 -0400 Subject: [PATCH] Certificate array in pem (#583) Fix a bug where previous trust manager effectively only read the first certificate in pem file. --- .../main/asciidoc/spring-cloud-gateway.adoc | 1 + .../gateway/config/HttpClientProperties.java | 12 ++-- .../gateway/test/ssl/MultiCertSSLTests.java | 35 +++++++++++ ...{SSLTests.java => SingleCertSSLTests.java} | 4 +- ...ssl.yml => application-multi-cert-ssl.yml} | 2 +- .../resources/application-single-cert-ssl.yml | 38 ++++++++++++ .../src/test/resources/multi-cert.pem | 62 +++++++++++++++++++ .../{scg-cert.pem => single-cert.pem} | 0 8 files changed, 146 insertions(+), 8 deletions(-) create mode 100644 spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/ssl/MultiCertSSLTests.java rename spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/ssl/{SSLTests.java => SingleCertSSLTests.java} (97%) rename spring-cloud-gateway-core/src/test/resources/{application-ssl.yml => application-multi-cert-ssl.yml} (94%) create mode 100644 spring-cloud-gateway-core/src/test/resources/application-single-cert-ssl.yml create mode 100644 spring-cloud-gateway-core/src/test/resources/multi-cert.pem rename spring-cloud-gateway-core/src/test/resources/{scg-cert.pem => single-cert.pem} (100%) diff --git a/docs/src/main/asciidoc/spring-cloud-gateway.adoc b/docs/src/main/asciidoc/spring-cloud-gateway.adoc index 95a8fda0..31c919d0 100644 --- a/docs/src/main/asciidoc/spring-cloud-gateway.adoc +++ b/docs/src/main/asciidoc/spring-cloud-gateway.adoc @@ -950,6 +950,7 @@ spring: - cert2.pem ---- +If the Spring Cloud Gateway is not provisioned with trusted certificates the default trust store is used (which can be overriden with system property javax.net.ssl.trustStore. == Configuration diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java index ca9159ea..62ecd2e3 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java @@ -25,11 +25,13 @@ import reactor.ipc.netty.resources.PoolResources; import java.io.IOException; import java.net.URL; +import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.time.Duration; import java.util.ArrayList; +import java.util.Collection; import java.util.List; /** @@ -231,20 +233,20 @@ public class HttpClientProperties { try { CertificateFactory certificateFactory = CertificateFactory .getInstance("X.509"); - ArrayList certs = new ArrayList<>(); + ArrayList allCerts = new ArrayList<>(); for (String trustedCert : ssl.getTrustedX509Certificates()) { try { URL url = ResourceUtils.getURL(trustedCert); - X509Certificate cert = (X509Certificate) certificateFactory - .generateCertificate(url.openStream()); - certs.add(cert); + Collection certs = certificateFactory + .generateCertificates(url.openStream()); + allCerts.addAll(certs); } catch (IOException e) { throw new WebServerException( "Could not load certificate '" + trustedCert + "'", e); } } - return certs.toArray(new X509Certificate[certs.size()]); + return allCerts.toArray(new X509Certificate[allCerts.size()]); } catch (CertificateException e1) { throw new WebServerException("Could not load CertificateFactory X.509", diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/ssl/MultiCertSSLTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/ssl/MultiCertSSLTests.java new file mode 100644 index 00000000..663e1dc1 --- /dev/null +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/ssl/MultiCertSSLTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2017 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. + * + */ + +package org.springframework.cloud.gateway.test.ssl; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = RANDOM_PORT) +@DirtiesContext +@ActiveProfiles("multi-cert-ssl") +public class MultiCertSSLTests extends SingleCertSSLTests { + + +} diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/ssl/SSLTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/ssl/SingleCertSSLTests.java similarity index 97% rename from spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/ssl/SSLTests.java rename to spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/ssl/SingleCertSSLTests.java index c936eb75..c351a0b5 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/ssl/SSLTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/ssl/SingleCertSSLTests.java @@ -49,8 +49,8 @@ import io.netty.handler.ssl.util.InsecureTrustManagerFactory; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT) @DirtiesContext -@ActiveProfiles("ssl") -public class SSLTests extends BaseWebClientTests { +@ActiveProfiles("single-cert-ssl") +public class SingleCertSSLTests extends BaseWebClientTests { @Before public void setup() { diff --git a/spring-cloud-gateway-core/src/test/resources/application-ssl.yml b/spring-cloud-gateway-core/src/test/resources/application-multi-cert-ssl.yml similarity index 94% rename from spring-cloud-gateway-core/src/test/resources/application-ssl.yml rename to spring-cloud-gateway-core/src/test/resources/application-multi-cert-ssl.yml index 248e6b08..52e21ea8 100644 --- a/spring-cloud-gateway-core/src/test/resources/application-ssl.yml +++ b/spring-cloud-gateway-core/src/test/resources/application-multi-cert-ssl.yml @@ -16,7 +16,7 @@ spring: httpclient: ssl: trustedX509Certificates: - - src/test/resources/scg-cert.pem + - src/test/resources/multi-cert.pem default-filters: - PrefixPath=/httpbin routes: diff --git a/spring-cloud-gateway-core/src/test/resources/application-single-cert-ssl.yml b/spring-cloud-gateway-core/src/test/resources/application-single-cert-ssl.yml new file mode 100644 index 00000000..a1da9aa1 --- /dev/null +++ b/spring-cloud-gateway-core/src/test/resources/application-single-cert-ssl.yml @@ -0,0 +1,38 @@ +test: + hostport: httpbin.org:80 + uri: lb://testservice + +server: + ssl: + enabled: true + key-alias: scg + key-store-password: scg1234 + key-store: classpath:scg-keystore.p12 + key-store-type: PKCS12 + +spring: + cloud: + gateway: + httpclient: + ssl: + trustedX509Certificates: + - src/test/resources/single-cert.pem + default-filters: + - PrefixPath=/httpbin + routes: + - id: default_path_to_httpbin + uri: ${test.uri} + order: 10000 + predicates: + - name: Path + args: + pattern: /** + +logging: + level: + org.springframework.cloud.gateway: TRACE + org.springframework.http.server.reactive: DEBUG + org.springframework.web.reactive: DEBUG + reactor.ipc.netty: DEBUG + redisratelimiter: DEBUG + diff --git a/spring-cloud-gateway-core/src/test/resources/multi-cert.pem b/spring-cloud-gateway-core/src/test/resources/multi-cert.pem new file mode 100644 index 00000000..d90ce1d4 --- /dev/null +++ b/spring-cloud-gateway-core/src/test/resources/multi-cert.pem @@ -0,0 +1,62 @@ +-----BEGIN CERTIFICATE----- +MIIGKzCCBROgAwIBAgIQByMt0ja6e5B8OohEG0rsHzANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E +aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgwMzE2MDAwMDAwWhcN +MTkwMzIxMTIwMDAwWjBtMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p +YTESMBAGA1UEBxMJUGFsbyBBbHRvMR8wHQYDVQQKExZQaXZvdGFsIFNvZnR3YXJl +LCBJbmMuMRQwEgYDVQQDDAsqLnNwcmluZy5pbzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANjtAeOmtB/ZPoX5r2MDWPmLVaLHFBLUViLsUMInkfpakesg +bl6vkWaVZpvarbOxzHuiYjsXEjlgpZTYVguv3UZHoDoD5k/E9k0N6UBdx5edXnsc +Ssty/fuH60MkDAsw89AILN4MAlkG2DIRJfGZGqCfA2k9Z35tz9l0OEavfqxNlUyT +X3AkCDyiEl5bfo2XevNw46O/21TKHwE1uDWszH2AOszv5TxdyICzCZUmjesb0awe +9PB6Mlv83U+MZgWS9SoHlQjfpz+tUVGm3PnHQ6Oqo4nJVb+wbgQ6aXyOpo/W5GQE +5svJcsF3AoDalPIsGU66EMYrooscUnoiDitViOkCAwEAAaOCAuUwggLhMB8GA1Ud +IwQYMBaAFA+AYRyCMWHVLyjnjUY4tCzhxtniMB0GA1UdDgQWBBSDcxmAlUjp2j+3 +9OZAjqL6dY8AqTAhBgNVHREEGjAYggsqLnNwcmluZy5pb4IJc3ByaW5nLmlvMA4G +A1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwawYD +VR0fBGQwYjAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NzY2Etc2hh +Mi1nNi5jcmwwL6AtoCuGKWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2NhLXNo +YTItZzYuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEW +HGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMHwGCCsGAQUF +BwEBBHAwbjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEYG +CCsGAQUFBzAChjpodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRT +SEEyU2VjdXJlU2VydmVyQ0EuY3J0MAwGA1UdEwEB/wQCMAAwggEEBgorBgEEAdZ5 +AgQCBIH1BIHyAPAAdQCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAA +AWIwOqM0AAAEAwBGMEQCIBr9GyZ5+YtlqoKhV/exaukHme/YbpXl/O1+6sG/kOro +AiBEI3IfRziaa9QMlm0fp2wGSbhpArTQ03w5Yq795QAhtgB3AG9Tdqwx8DEZ2JkA +pFEV/3cVHBHZAsEAKQaNsgiaN9kTAAABYjA6pHYAAAQDAEgwRgIhAMyltKcFRCoE +BSoeBUd8OFU7gKlWKsmxAZkVKpLuYbMKAiEAgb7snjGCWpX1qRdg+TlKnyn3bocK +i2pROA/1lzAOqzowDQYJKoZIhvcNAQELBQADggEBACDyzGb8YxHFQBO20l7LYbW8 +rNat/FhB5H8JCEaup7pvdVCNvyUOOR3fm+by+a56QI1cb0vx8N6+j/rVXccniL88 +26FGO2IQeAnNa0Mc8ANJdLrYzwCSiObIFXh2/Cu86oe7SJNjbxJpX3C2OKxmHVVP +AofQsz59V5O1JBkblRAfK9yBOroeBAMRvNxHuolleuip4IKD6URGXQzDyXqNbWs7 +O3zyXtGAoCUAxUtoOcZNZWvXF3eYFxMnEmsuNjO6UHtfvJGB6pqjWp/00j5cioE3 +RLqeByg4E9a9iM5onXdSSGzAYusdZE53IAezV0w8KNJuOKHYLwpO59tvU901OK0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEjTCCAvWgAwIBAgIEIZEBKTANBgkqhkiG9w0BAQwFADBsMRAwDgYDVQQGEwdV +bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD +VQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRAwDgYDVQQDEwdVbmtub3du +MB4XDTE4MDcxODEyNTY0OFoXDTQ1MTIwMzEyNTY0OFowbDEQMA4GA1UEBhMHVW5r +bm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UE +ChMHVW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEQMA4GA1UEAxMHVW5rbm93bjCC +AaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAJhdOwHjozNaUdocb+p/Dn6E +UUXzkNGwmUZwRSQKnEK9IV/PTwrzK+fPJS8vpUzEpj37QIGBTSNuebQ3w5G4cAu6 +xFEk4e56C823Vio5Hae/+fos7goaR+ihKMy2lGPwFGNECqGmUZItE1+4pdjYyia7 +FTWluAVuTgue3VODl9ziDw+2Zrt6Axtnb5heQXP8ElEZldoePpUmbLWa03Xvfatb +4ZKkoCLOKhcgM5F2tyR+VlZnqm2dhvO+J778MsU4ToVAUGrVIkeQi0BHTi5Rzy2c +2kDLHHuJTYqN65sl5LyKDu003KXioelZVUeH3Hgtrj0Tt96oYSixvHSGwDmcXpux +4sbzTS7x/KeQAjLIFj/3rxQP0TSuTCe/XrqiCpFflLntTI9En9CWto6SXFRigval +zCITgImQthSfFMxFDqNtNQo5hTAu8VY2/FurMbkukQ5l2+vU4dKBccNxChj5m7p3 +8C4G7Rh08AEYaNYcNZlaz++c37rW7P6vWX8m6C21CQIDAQABozcwNTAUBgNVHREE +DTALgglsb2NhbGhvc3QwHQYDVR0OBBYEFDOSE31Vw2QdyVviz+H5+tY5HRR4MA0G +CSqGSIb3DQEBDAUAA4IBgQAJljlIubbQvw/2UVymsyF939XKus/7muiJLtQt0J4J +sSuGiSQmkyJajBRj9+qsLLTtdL6F2+BFJtP8S/zZixrEzktuRZ3b40MLtyI4hVDt +fmgj3UMmphVgbmDv71WvRmUXFfBX5Zka7zRW+lFvO5dLytegKi3Vc8zOFRUcvY9w +uBEOipAkUqH6y+lI/lJ72MrXpkxbkAq2fYffZK4e6KNpKG7pP0txEkwNvosKSAjA +yL+Ye5bK6sYbscwsqvXw9nWwjuFpj/0zvD/tM1jMtUtV1+9HKC3vsfAaL9QnwnS6 +qhSaos8j7fw9SYdAoO+yth2w1ETxKXrzcF+LEkhzj2R0zygycLZvWj51lIWDDOvy +m3IUFTY8fX7CBgLIGnHAcdWK6a+FkWIb8WybWkv2n2SxM4AnzXb5epk/K2Uo30hY +mr9wrywvo92xUjXEOmQpAbFx0hcVjYOtvpHdUeZTGLLQ7sWJGQFalRT+GsTy+Lph +10719GizKXQW2Mx/8XOr1Ow= +-----END CERTIFICATE----- diff --git a/spring-cloud-gateway-core/src/test/resources/scg-cert.pem b/spring-cloud-gateway-core/src/test/resources/single-cert.pem similarity index 100% rename from spring-cloud-gateway-core/src/test/resources/scg-cert.pem rename to spring-cloud-gateway-core/src/test/resources/single-cert.pem