From 5c45ff019eb9e1773533e56518c69e2fd040270f Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Wed, 6 Dec 2023 11:46:31 -0800 Subject: [PATCH 1/9] update build to jvm 19 spring boot 3 requires java 17 --- .travis.yml | 2 +- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index c0cc781..66c5a9a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: java jdk: - - openjdk11 + - openjdk19 # don't run `gradle assemble` https://docs.travis-ci.com/user/customizing-the-build/#Skipping-the-Installation-Step install: true diff --git a/build.gradle b/build.gradle index 269765b..ea588d8 100644 --- a/build.gradle +++ b/build.gradle @@ -90,7 +90,7 @@ test { showStandardStreams = true } // https://junit-pioneer.org/docs/environment-variables/#warnings-for-reflective-access - jvmArgs '--add-opens=java.base/java.util=ALL-UNNAMED' + jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED', '--add-opens=java.base/java.util=ALL-UNNAMED' } //disable javadoc doclint for Java8 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f1bab29..a1b8dc9 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip From ef0aeba1805a3890dc965eddd6795f4ca16df167 Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Wed, 6 Dec 2023 14:04:32 -0800 Subject: [PATCH 2/9] downgrade java to 17 and gradle to 7.4 VS Code wasn't happy running on java 19. installed java17: `brew install openjdk@17` ensured that VS Code setting java.import.gradle.java.home was set to (output from): `/usr/libexec/java_home -v17` --- .travis.yml | 2 +- gradle/wrapper/gradle-wrapper.properties | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 66c5a9a..e799540 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: java jdk: - - openjdk19 + - openjdk17 # don't run `gradle assemble` https://docs.travis-ci.com/user/customizing-the-build/#Skipping-the-Installation-Step install: true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a1b8dc9..bc0906d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Apr 16 12:15:33 PDT 2019 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip +#Wed Dec 06 13:31:11 PST 2023 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists From 55c7be162eca5b2665a58844b2f71e46b21e6ea5 Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Wed, 6 Dec 2023 14:09:02 -0800 Subject: [PATCH 3/9] wip: update to spring boot 3.0 4 failing tests: * FileFormatTests. testECEncryptedPKCS8() * IntegrationTestUsingMockMvc. protectedEndpoint_revoked() * IntegrationTestUsingRealServer. happyCase_updateCertificate() * IntegrationTestUsingRealServer. serverRejectsRevokedClient() --- build.gradle | 21 ++++++++++++------- .../ClientCertificateCheckingFilter.java | 11 +++++----- .../dtreskunov/easyssl/EasySslBeans.java | 3 ++- .../IntegrationTestUsingRealServer.java | 19 ++++++++++++++--- .../dtreskunov/easyssl/server/Security.java | 4 ++-- 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index ea588d8..604846f 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,8 @@ plugins { id 'com.palantir.git-version' version '0.12.2' id 'io.codearte.nexus-staging' version '0.21.2' id 'de.marcphilipp.nexus-publish' version '0.4.0' + id 'org.springframework.boot' version '3.0.13' apply false + id 'io.spring.dependency-management' version '1.1.4' } group = 'com.github.dtreskunov' @@ -39,23 +41,28 @@ println "Project version: ${version}" ext { isSnapshotVersion = version.endsWith('SNAPSHOT') } - -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - +java { + sourceCompatibility = 17 + targetCompatibility = 17 +} repositories { mavenCentral() } +dependencyManagement { + imports { + mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) + } +} + dependencies { - implementation platform('org.springframework.boot:spring-boot-dependencies:2.7.18') implementation platform('software.amazon.awssdk:bom:2.21.33') api('org.springframework.boot:spring-boot') api('org.springframework.boot:spring-boot-autoconfigure') api('org.springframework:spring-web') api('org.slf4j:slf4j-api') api('javax.validation:validation-api:2.0.1.Final') - api('javax.servlet:javax.servlet-api') + api('jakarta.servlet:jakarta.servlet-api') api(project.getProperties().getOrDefault('fips', 'true').toBoolean() ? 'org.bouncycastle:bcpkix-fips:1.0.5' : 'org.bouncycastle:bcpkix-jdk15on:1.69') compileOnly('org.eclipse.jetty:jetty-server') // needed for jetty-specific customizations compileOnly('org.apache.tomcat.embed:tomcat-embed-core') // needed for tomcat-specific customizations @@ -69,7 +76,7 @@ dependencies { testImplementation('org.springframework.boot:spring-boot-starter-security') testImplementation('org.springframework.boot:spring-boot-starter-test') testImplementation('org.springframework.security:spring-security-test') - testImplementation('org.apache.httpcomponents:httpclient') + testImplementation('org.apache.httpcomponents.client5:httpclient5') testImplementation('org.junit-pioneer:junit-pioneer:1.4.2') testImplementation('software.amazon.awssdk:secretsmanager') // needed for AWS Secrets Manager support } diff --git a/src/main/java/com/github/dtreskunov/easyssl/ClientCertificateCheckingFilter.java b/src/main/java/com/github/dtreskunov/easyssl/ClientCertificateCheckingFilter.java index 3f45896..9dd4dea 100644 --- a/src/main/java/com/github/dtreskunov/easyssl/ClientCertificateCheckingFilter.java +++ b/src/main/java/com/github/dtreskunov/easyssl/ClientCertificateCheckingFilter.java @@ -5,11 +5,6 @@ import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,6 +12,12 @@ import org.springframework.http.HttpStatus; import org.springframework.web.filter.GenericFilterBean; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletResponse; + /** * A servlet filter that responds with a {@link HttpStatus#FORBIDDEN 403 Forbidden} when the provided * {@link X509Certificate client certificate} is not trusted according to the provided {@link X509TrustManager} - for example, diff --git a/src/main/java/com/github/dtreskunov/easyssl/EasySslBeans.java b/src/main/java/com/github/dtreskunov/easyssl/EasySslBeans.java index dc8c9c0..bf8bc87 100644 --- a/src/main/java/com/github/dtreskunov/easyssl/EasySslBeans.java +++ b/src/main/java/com/github/dtreskunov/easyssl/EasySslBeans.java @@ -4,7 +4,6 @@ import java.util.Map; import javax.net.ssl.SSLContext; -import javax.servlet.Filter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -26,6 +25,8 @@ import org.springframework.core.env.PropertySource; import org.springframework.web.client.RestTemplate; +import jakarta.servlet.Filter; + /** * Defines Spring beans that are used for mutual SSL. They are: *
    diff --git a/src/test/java/com/github/dtreskunov/easyssl/IntegrationTestUsingRealServer.java b/src/test/java/com/github/dtreskunov/easyssl/IntegrationTestUsingRealServer.java index 6f02f11..1a9d15d 100644 --- a/src/test/java/com/github/dtreskunov/easyssl/IntegrationTestUsingRealServer.java +++ b/src/test/java/com/github/dtreskunov/easyssl/IntegrationTestUsingRealServer.java @@ -14,8 +14,12 @@ import javax.net.ssl.SSLContext; -import org.apache.http.client.HttpClient; -import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.hc.client5.http.classic.HttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.client5.http.io.HttpClientConnectionManager; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -56,7 +60,16 @@ public class IntegrationTestUsingRealServer { private RestTemplate restTemplate; private RestTemplate getRestTemplate(SSLContext sslContext) throws Exception { - HttpClient httpClient = HttpClientBuilder.create().setSSLContext(sslContext).build(); + SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create() + .setSslContext(sslContext) + .build(); + HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create() + .setSSLSocketFactory(sslSocketFactory) + .build(); + HttpClient httpClient = HttpClients.custom() + .setConnectionManager(cm) + .evictExpiredConnections() + .build(); return new RestTemplateBuilder() .rootUri(protocol + "://localhost:" + port) .requestFactory(() -> new HttpComponentsClientHttpRequestFactory(httpClient)) diff --git a/src/test/java/com/github/dtreskunov/easyssl/server/Security.java b/src/test/java/com/github/dtreskunov/easyssl/server/Security.java index 246f4e3..a8452ef 100644 --- a/src/test/java/com/github/dtreskunov/easyssl/server/Security.java +++ b/src/test/java/com/github/dtreskunov/easyssl/server/Security.java @@ -2,7 +2,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.authority.AuthorityUtils; @@ -13,7 +13,7 @@ import org.springframework.security.web.SecurityFilterChain; @Configuration -@EnableGlobalMethodSecurity(prePostEnabled = true) +@EnableMethodSecurity(prePostEnabled = true) public class Security { @Bean From 75e6b8beda8dfb76d72e3ef9572d337d42b5a21e Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Wed, 6 Dec 2023 14:43:27 -0800 Subject: [PATCH 4/9] wip: fix openssl warning `using curve name prime256v1 instead of secp256r1` after updating my macos to sonoma (14.1.1), I needed to ensure that OpenSSL 1.1 is the default: `brew install openssl@1.1` `echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc` there are 2 tests that are failing on my macos: * IntegrationTestUsingMockMvc. protectedEndpoint_revoked() * IntegrationTestUsingRealServer. serverRejectsRevokedClient() --- .travis.yml | 1 + src/test/gen.rb | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index e799540..028ed76 100644 --- a/.travis.yml +++ b/.travis.yml @@ -78,6 +78,7 @@ before_install: - env | grep '^TRAVIS_' | sort - openssl aes-256-cbc -K $encrypted_7a85652b67b9_key -iv $encrypted_7a85652b67b9_iv -in secring.gpg.enc -out secring.gpg -d + - openssl version env: global: diff --git a/src/test/gen.rb b/src/test/gen.rb index a05ba41..c7b7ec1 100644 --- a/src/test/gen.rb +++ b/src/test/gen.rb @@ -82,15 +82,15 @@ def gen # Create private key if key_pkcs8 if key_pass - `openssl ecparam -genkey -name secp256r1 | openssl ec | openssl pkcs8 -out #{key} -topk8 -v1 PBE-SHA1-RC4-128 -passout pass:#{key_pass}` + `openssl ecparam -genkey -name prime256v1 | openssl ec | openssl pkcs8 -out #{key} -topk8 -v1 PBE-SHA1-RC4-128 -passout pass:#{key_pass}` else - `openssl ecparam -genkey -name secp256r1 | openssl ec | openssl pkcs8 -out #{key} -topk8 -nocrypt` + `openssl ecparam -genkey -name prime256v1 | openssl ec | openssl pkcs8 -out #{key} -topk8 -nocrypt` end else if key_pass - `openssl ecparam -genkey -name secp256r1 | openssl ec -out #{key} -aes128 -passout pass:#{key_pass}` + `openssl ecparam -genkey -name prime256v1 | openssl ec -out #{key} -aes128 -passout pass:#{key_pass}` else - `openssl ecparam -genkey -name secp256r1 | openssl ec -out #{key}` + `openssl ecparam -genkey -name prime256v1 | openssl ec -out #{key}` end end From 733c5cf62fa5bb1e7f12e38c9e4a7649a0d145e1 Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Wed, 6 Dec 2023 15:05:48 -0800 Subject: [PATCH 5/9] fix failing tests related to revoked cert checks --- .../dtreskunov/easyssl/ClientCertificateCheckingFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/dtreskunov/easyssl/ClientCertificateCheckingFilter.java b/src/main/java/com/github/dtreskunov/easyssl/ClientCertificateCheckingFilter.java index 9dd4dea..f03d184 100644 --- a/src/main/java/com/github/dtreskunov/easyssl/ClientCertificateCheckingFilter.java +++ b/src/main/java/com/github/dtreskunov/easyssl/ClientCertificateCheckingFilter.java @@ -32,7 +32,7 @@ */ class ClientCertificateCheckingFilter extends GenericFilterBean { - private static final String REQUEST_ATTRIBUTE_X509_CERTIFICATE = "javax.servlet.request.X509Certificate"; + private static final String REQUEST_ATTRIBUTE_X509_CERTIFICATE = "jakarta.servlet.request.X509Certificate"; private final Logger m_log = LoggerFactory.getLogger(getClass()); private final X509TrustManager m_trustManager; From fbd91272d4de2e61e9efb0b5221c4ffe693314a9 Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Wed, 6 Dec 2023 15:11:13 -0800 Subject: [PATCH 6/9] try out using arm64 for unlimited travis build minutes https://docs.travis-ci.com/user/billing-overview/#partner-queue-solution --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 028ed76..d24cb07 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,7 @@ +os: linux +arch: + - arm64 + language: java jdk: From 47358538d91ffe2508f660cd1bcd402f6b044353 Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Wed, 6 Dec 2023 16:01:27 -0800 Subject: [PATCH 7/9] fix failing jetty tests ``` Caused by: java.lang.NoClassDefFoundError: jakarta/servlet/http/HttpSessionContext at org.eclipse.jetty.servlet.ServletContextHandler.newSessionHandler(ServletContextHandler.java:339) ~[jetty-servlet-11.0.18.jar:11.0.18] ``` --- build.gradle | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 604846f..e1903cb 100644 --- a/build.gradle +++ b/build.gradle @@ -40,6 +40,7 @@ println "Project version: ${version}" ext { isSnapshotVersion = version.endsWith('SNAPSHOT') + servletContainer = project.getProperties().getOrDefault('servletContainer', 'tomcat') } java { sourceCompatibility = 17 @@ -72,7 +73,7 @@ dependencies { testRuntimeOnly('org.springframework.boot:spring-boot-starter-web') { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' } - testRuntimeOnly('org.springframework.boot:spring-boot-starter-' + project.getProperties().getOrDefault('servletContainer', 'tomcat')) + testRuntimeOnly('org.springframework.boot:spring-boot-starter-' + servletContainer) testImplementation('org.springframework.boot:spring-boot-starter-security') testImplementation('org.springframework.boot:spring-boot-starter-test') testImplementation('org.springframework.security:spring-security-test') @@ -81,6 +82,15 @@ dependencies { testImplementation('software.amazon.awssdk:secretsmanager') // needed for AWS Secrets Manager support } +if ('jetty'.equals(servletContainer)) { + dependencies { + // this shouldn't be needed for Spring Boot 3.2+ + // https://github.com/spring-projects/spring-boot/issues/33044 + // https://github.com/spring-projects/spring-boot/issues/31720 + testRuntimeOnly('org.eclipse.jetty.toolchain:jetty-jakarta-servlet-api:5.0.2') + } +} + task generateTestCerts(type: Exec) { def dir = new File(project.rootDir, "src/test/resources/ssl") doFirst { From b01181b77abc400e38bb561697a24d154a2b6278 Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Fri, 20 Dec 2024 12:59:42 -0800 Subject: [PATCH 8/9] update versions of spring and logback --- build.gradle | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index e1903cb..83a303d 100644 --- a/build.gradle +++ b/build.gradle @@ -14,8 +14,7 @@ plugins { id 'com.palantir.git-version' version '0.12.2' id 'io.codearte.nexus-staging' version '0.21.2' id 'de.marcphilipp.nexus-publish' version '0.4.0' - id 'org.springframework.boot' version '3.0.13' apply false - id 'io.spring.dependency-management' version '1.1.4' + id 'io.spring.dependency-management' version '1.1.7' } group = 'com.github.dtreskunov' @@ -46,18 +45,25 @@ java { sourceCompatibility = 17 targetCompatibility = 17 } + +// override dependency versions specified in +// https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/2.7.18/spring-boot-dependencies-2.7.18.pom +ext['logback.version'] = '1.4.14' +ext['spring-framework.version'] = '6.0.23' + repositories { mavenCentral() } +// https://www.baeldung.com/spring-boot-override-dependency-versions dependencyManagement { imports { - mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) + mavenBom 'org.springframework.boot:spring-boot-dependencies:3.0.13' + mavenBom 'software.amazon.awssdk:bom:2.21.33' } } dependencies { - implementation platform('software.amazon.awssdk:bom:2.21.33') api('org.springframework.boot:spring-boot') api('org.springframework.boot:spring-boot-autoconfigure') api('org.springframework:spring-web') From 7907ac74325f602e45626ca4d08df32cdeb80b4a Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Fri, 20 Dec 2024 13:34:35 -0800 Subject: [PATCH 9/9] try out using ppc64le for unlimited travis build minutes https://docs.travis-ci.com/user/billing-overview/#partner-queue-solution --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d24cb07..9881629 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ os: linux arch: - - arm64 + - ppc64le language: java