Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 16 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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

Expand All @@ -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
Expand All @@ -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
Expand Down
12 changes: 4 additions & 8 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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"))
Original file line number Diff line number Diff line change
Expand Up @@ -130,79 +130,76 @@ 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
}

@deprecated("Uses internal sun.security.x509 classes. Java 17 requires add-exports flags; Java 21 fails.", "0.7.0")
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
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}