diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7429225a..c37a6f78 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,10 +24,7 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] scala: [2.13.17, 2.12.20, 3.3.7] - java: [temurin@8, temurin@11] - exclude: - - java: temurin@8 - os: macos-latest + java: [temurin@21, temurin@25] runs-on: ${{ matrix.os }} steps: - name: Ignore line ending differences in git @@ -48,20 +45,20 @@ jobs: with: fetch-depth: 0 - - name: Setup Java (temurin@8) - if: matrix.java == 'temurin@8' + - name: Setup Java (temurin@21) + if: matrix.java == 'temurin@21' uses: actions/setup-java@v5 with: distribution: temurin - java-version: 8 + java-version: 21 cache: sbt - - name: Setup Java (temurin@11) - if: matrix.java == 'temurin@11' + - name: Setup Java (temurin@25) + if: matrix.java == 'temurin@25' uses: actions/setup-java@v5 with: distribution: temurin - java-version: 11 + java-version: 25 cache: sbt - name: Setup sbt @@ -72,6 +69,8 @@ jobs: run: sbt '++ ${{ matrix.scala }}' githubWorkflowCheck - if: github.repository == 'lightbend/ssl-config' + env: + JAVA_TOOL_OPTIONS: '--add-exports=java.base/sun.security.x509=ALL-UNNAMED' shell: bash run: sbt '++ ${{ matrix.scala }}' validateCode test doc mimaReportBinaryIssues @@ -97,7 +96,7 @@ jobs: matrix: os: [ubuntu-latest] scala: [2.12.20] - java: [temurin@8] + java: [temurin@21] runs-on: ${{ matrix.os }} steps: - name: Ignore line ending differences in git @@ -117,20 +116,20 @@ jobs: with: fetch-depth: 0 - - name: Setup Java (temurin@8) - if: matrix.java == 'temurin@8' + - name: Setup Java (temurin@21) + if: matrix.java == 'temurin@21' uses: actions/setup-java@v5 with: distribution: temurin - java-version: 8 + java-version: 21 cache: sbt - - name: Setup Java (temurin@11) - if: matrix.java == 'temurin@11' + - name: Setup Java (temurin@25) + if: matrix.java == 'temurin@25' uses: actions/setup-java@v5 with: distribution: temurin - java-version: 11 + java-version: 25 cache: sbt - name: Setup sbt diff --git a/build.sbt b/build.sbt index b414c612..b7c24951 100644 --- a/build.sbt +++ b/build.sbt @@ -16,7 +16,7 @@ lazy val sslConfigCore = project .settings(AutomaticModuleName.settings("ssl.config.core")) .settings(osgiSettings: _*) .settings( - javacOptions ++= Seq("-source", "1.8", "-target", "1.8"), + javacOptions ++= Seq("-target", "21"), name := "ssl-config-core", mimaReportSignatureProblems := true, mimaPreviousArtifacts := Set("com.typesafe" %% "ssl-config-core" % "0.7.0"), @@ -66,6 +66,7 @@ addCommandAlias("validateCode", "headerCheckAll ; scalafmtSbtCheck ; scalafmtChe ThisBuild / githubWorkflowBuild := Seq( WorkflowStep.Sbt( List("validateCode", "test", "doc", "mimaReportBinaryIssues"), + env = Map("JAVA_TOOL_OPTIONS" -> "--add-exports=java.base/sun.security.x509=ALL-UNNAMED"), cond = Some(s"github.repository == '${githubOrg}/${githubRepo}'") ), WorkflowStep.Run( @@ -97,11 +98,6 @@ ThisBuild / githubWorkflowPublish := Seq( ThisBuild / githubWorkflowOSes := Seq("ubuntu-latest", "macos-latest", "windows-latest") ThisBuild / githubWorkflowJavaVersions := Seq( - JavaSpec.temurin("8"), - JavaSpec.temurin("11"), - // JavaSpec.temurin("17"), // can't test currently because until we drop usage of sun.security.x509.* - // JavaSpec.temurin("21"), - // JavaSpec.temurin("25"), + JavaSpec.temurin("21"), + JavaSpec.temurin("25"), ) - -ThisBuild / githubWorkflowBuildMatrixExclusions += MatrixExclude(Map("java" -> "temurin@8", "os" -> "macos-latest")) diff --git a/ssl-config-core/src/main/scala/com/typesafe/sslconfig/ssl/FakeChainedKeyStore.scala b/ssl-config-core/src/main/scala/com/typesafe/sslconfig/ssl/FakeChainedKeyStore.scala index b60a3655..aced72fa 100644 --- a/ssl-config-core/src/main/scala/com/typesafe/sslconfig/ssl/FakeChainedKeyStore.scala +++ b/ssl-config-core/src/main/scala/com/typesafe/sslconfig/ssl/FakeChainedKeyStore.scala @@ -130,36 +130,35 @@ object FakeChainedKeyStore { val certInfo = new X509CertInfo() // Serial number and version - certInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(new BigInteger(64, new SecureRandom()))) - certInfo.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)) + certInfo.setSerialNumber(new CertificateSerialNumber(new BigInteger(64, new SecureRandom()))) + certInfo.setVersion(new CertificateVersion(CertificateVersion.V3)) // Validity val validFrom = new Date() val validTo = new Date(validFrom.getTime + 50L * 365L * 24L * 60L * 60L * 1000L) val validity = new CertificateValidity(validFrom, validTo) - certInfo.set(X509CertInfo.VALIDITY, validity) + certInfo.setValidity(validity) // Subject and issuer val certificateAuthorityName = new X500Name(CA.DistinguishedName) - certInfo.set(X509CertInfo.ISSUER, certificateAuthorityName) + certInfo.setIssuer(certificateAuthorityName) val owner = new X500Name(User.DistinguishedName) - certInfo.set(X509CertInfo.SUBJECT, owner) + certInfo.setSubject(owner) // Key and algorithm - certInfo.set(X509CertInfo.KEY, new CertificateX509Key(userKeyPair.getPublic)) + certInfo.setKey(new CertificateX509Key(userKeyPair.getPublic)) val algorithm = AlgorithmId.get("SHA256WithRSA") - certInfo.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algorithm)) + certInfo.setAlgorithmId(new CertificateAlgorithmId(algorithm)) // Create a new certificate and sign it - val cert = new X509CertImpl(certInfo) - cert.sign(userKeyPair.getPrivate, KeystoreSettings.SignatureAlgorithmName) + val cert = X509CertImpl.newSigned(certInfo, userKeyPair.getPrivate, KeystoreSettings.SignatureAlgorithmName) // Since the signature provider may have a different algorithm ID to what we think it should be, // we need to reset the algorithm ID, and resign the certificate - val actualAlgorithm = cert.get(X509CertImpl.SIG_ALG).asInstanceOf[AlgorithmId] - certInfo.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, actualAlgorithm) - val newCert = new X509CertImpl(certInfo) - newCert.sign(certificateAuthorityKeyPair.getPrivate, KeystoreSettings.SignatureAlgorithmName) + val actualAlgorithm = cert.getSigAlg + certInfo.setAlgorithmId(new CertificateAlgorithmId(actualAlgorithm)) + val newCert = + X509CertImpl.newSigned(certInfo, certificateAuthorityKeyPair.getPrivate, KeystoreSettings.SignatureAlgorithmName) newCert } @@ -167,42 +166,40 @@ object FakeChainedKeyStore { private def createCertificateAuthority(keyPair: KeyPair): X509Certificate = { val certInfo = new X509CertInfo() // Serial number and version - certInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(new BigInteger(64, new SecureRandom()))) - certInfo.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)) + certInfo.setSerialNumber(new CertificateSerialNumber(new BigInteger(64, new SecureRandom()))) + certInfo.setVersion(new CertificateVersion(CertificateVersion.V3)) // Validity val validFrom = new Date() val validTo = new Date(validFrom.getTime + 50L * 365L * 24L * 60L * 60L * 1000L) // 50 years val validity = new CertificateValidity(validFrom, validTo) - certInfo.set(X509CertInfo.VALIDITY, validity) + certInfo.setValidity(validity) // Subject and issuer val owner = new X500Name(CA.DistinguishedName) - certInfo.set(X509CertInfo.SUBJECT, owner) - certInfo.set(X509CertInfo.ISSUER, owner) + certInfo.setSubject(owner) + certInfo.setIssuer(owner) // Key and algorithm - certInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic)) + certInfo.setKey(new CertificateX509Key(keyPair.getPublic)) val algorithm = AlgorithmId.get("SHA256WithRSA") - certInfo.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algorithm)) + certInfo.setAlgorithmId(new CertificateAlgorithmId(algorithm)) val caExtension = new CertificateExtensions - caExtension.set( + caExtension.setExtension( BasicConstraintsExtension.NAME, new BasicConstraintsExtension( /* isCritical */ true, /* isCA */ true, 0) ) - certInfo.set(X509CertInfo.EXTENSIONS, caExtension) + certInfo.setExtensions(caExtension) // Create a new certificate and sign it - val cert = new X509CertImpl(certInfo) - cert.sign(keyPair.getPrivate, KeystoreSettings.SignatureAlgorithmName) + val cert = X509CertImpl.newSigned(certInfo, keyPair.getPrivate, KeystoreSettings.SignatureAlgorithmName) // Since the signature provider may have a different algorithm ID to what we think it should be, // we need to reset the algorithm ID, and resign the certificate - val actualAlgorithm = cert.get(X509CertImpl.SIG_ALG).asInstanceOf[AlgorithmId] - certInfo.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, actualAlgorithm) - val newCert = new X509CertImpl(certInfo) - newCert.sign(keyPair.getPrivate, KeystoreSettings.SignatureAlgorithmName) + val actualAlgorithm = cert.getSigAlg + certInfo.setAlgorithmId(new CertificateAlgorithmId(actualAlgorithm)) + val newCert = X509CertImpl.newSigned(certInfo, keyPair.getPrivate, KeystoreSettings.SignatureAlgorithmName) newCert } diff --git a/ssl-config-core/src/main/scala/com/typesafe/sslconfig/ssl/FakeKeyStore.scala b/ssl-config-core/src/main/scala/com/typesafe/sslconfig/ssl/FakeKeyStore.scala index 9e7f36fc..48d1cfd2 100644 --- a/ssl-config-core/src/main/scala/com/typesafe/sslconfig/ssl/FakeKeyStore.scala +++ b/ssl-config-core/src/main/scala/com/typesafe/sslconfig/ssl/FakeKeyStore.scala @@ -105,35 +105,33 @@ object FakeKeyStore { val certInfo = new X509CertInfo() // Serial number and version - certInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(new BigInteger(64, new SecureRandom()))) - certInfo.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)) + certInfo.setSerialNumber(new CertificateSerialNumber(new BigInteger(64, new SecureRandom()))) + certInfo.setVersion(new CertificateVersion(CertificateVersion.V3)) // Validity val validFrom = new Date() val validTo = new Date(validFrom.getTime + 50L * 365L * 24L * 60L * 60L * 1000L) val validity = new CertificateValidity(validFrom, validTo) - certInfo.set(X509CertInfo.VALIDITY, validity) + certInfo.setValidity(validity) // Subject and issuer val owner = new X500Name(SelfSigned.DistinguishedName) - certInfo.set(X509CertInfo.SUBJECT, owner) - certInfo.set(X509CertInfo.ISSUER, owner) + certInfo.setSubject(owner) + certInfo.setIssuer(owner) // Key and algorithm - certInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic)) + certInfo.setKey(new CertificateX509Key(keyPair.getPublic)) val algorithm = AlgorithmId.get("SHA256WithRSA") - certInfo.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algorithm)) + certInfo.setAlgorithmId(new CertificateAlgorithmId(algorithm)) // Create a new certificate and sign it - val cert = new X509CertImpl(certInfo) - cert.sign(keyPair.getPrivate, KeystoreSettings.SignatureAlgorithmName) + val cert = X509CertImpl.newSigned(certInfo, keyPair.getPrivate, KeystoreSettings.SignatureAlgorithmName) // Since the signature provider may have a different algorithm ID to what we think it should be, // we need to reset the algorithm ID, and resign the certificate - val actualAlgorithm = cert.get(X509CertImpl.SIG_ALG).asInstanceOf[AlgorithmId] - certInfo.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, actualAlgorithm) - val newCert = new X509CertImpl(certInfo) - newCert.sign(keyPair.getPrivate, KeystoreSettings.SignatureAlgorithmName) + val actualAlgorithm = cert.getSigAlg + certInfo.setAlgorithmId(new CertificateAlgorithmId(actualAlgorithm)) + val newCert = X509CertImpl.newSigned(certInfo, keyPair.getPrivate, KeystoreSettings.SignatureAlgorithmName) newCert } diff --git a/ssl-config-core/src/test/scala/com/typesafe/sslconfig/ssl/CertificateGenerator.scala b/ssl-config-core/src/test/scala/com/typesafe/sslconfig/ssl/CertificateGenerator.scala index a34de352..89a9c494 100644 --- a/ssl-config-core/src/test/scala/com/typesafe/sslconfig/ssl/CertificateGenerator.scala +++ b/ssl-config-core/src/test/scala/com/typesafe/sslconfig/ssl/CertificateGenerator.scala @@ -105,21 +105,19 @@ object CertificateGenerator { val sn: BigInteger = new BigInteger(64, new SecureRandom) val owner: X500Name = new X500Name(dn) - info.set(X509CertInfo.VALIDITY, interval) - info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn)) - info.set(X509CertInfo.SUBJECT, owner) - info.set(X509CertInfo.ISSUER, owner) - info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic)) - info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)) - - info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(AlgorithmId.get(algorithm))) - var cert: X509CertImpl = new X509CertImpl(info) + info.setValidity(interval) + info.setSerialNumber(new CertificateSerialNumber(sn)) + info.setSubject(owner) + info.setIssuer(owner) + info.setKey(new CertificateX509Key(pair.getPublic)) + info.setVersion(new CertificateVersion(CertificateVersion.V3)) + + info.setAlgorithmId(new CertificateAlgorithmId(AlgorithmId.get(algorithm))) val privkey: PrivateKey = pair.getPrivate - cert.sign(privkey, algorithm) - val algos = cert.get(X509CertImpl.SIG_ALG).asInstanceOf[AlgorithmId] - info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algos) - cert = new X509CertImpl(info) - cert.sign(privkey, algorithm) + var cert: X509CertImpl = X509CertImpl.newSigned(info, privkey, algorithm) + val algos = cert.getSigAlg + info.setAlgorithmId(new CertificateAlgorithmId(algos)) + X509CertImpl.newSigned(info, privkey, algorithm) cert } }