diff --git a/ledger/ledger-api-test-tool/BUILD.bazel b/ledger/ledger-api-test-tool/BUILD.bazel index 1d3a2a2573a..c296a395869 100644 --- a/ledger/ledger-api-test-tool/BUILD.bazel +++ b/ledger/ledger-api-test-tool/BUILD.bazel @@ -264,6 +264,36 @@ conformance_test( ], ) +conformance_test( + name = "conformance-test-tls1.2-or-newer", + extra_data = [ + "//ledger/test-common/test-certificates:client.crt", + "//ledger/test-common/test-certificates:client.pem", + "//ledger/test-common/test-certificates:server.crt", + "//ledger/test-common/test-certificates:server.pem", + "//ledger/test-common/test-certificates:server.pem.enc", + "//ledger/test-common/test-certificates:ca.crt", + ], + lf_versions = lf_version_configuration_versions, + ports = [6865], + server = "//ledger/ledger-on-memory:app", + server_args = [ + "--contract-id-seeding=testing-weak", + "--participant=participant-id=example,port=6865", + "--crt $$(rlocation $$TEST_WORKSPACE/$(rootpath //ledger/test-common/test-certificates:server.crt))", + "--cacrt $$(rlocation $$TEST_WORKSPACE/$(rootpath //ledger/test-common/test-certificates:ca.crt))", + "--pem $$(rlocation $$TEST_WORKSPACE/$(rootpath //ledger/test-common/test-certificates:server.pem.enc))", + "--tls-secrets-url https://raw.githubusercontent.com/digital-asset/daml/main/ledger/test-common/files/server-pem-decryption-parameters.json", + ], + test_tool_args = [ + "--verbose", + "--crt $$(rlocation $$TEST_WORKSPACE/$(rootpath //ledger/test-common/test-certificates:client.crt))", + "--cacrt $$(rlocation $$TEST_WORKSPACE/$(rootpath //ledger/test-common/test-certificates:ca.crt))", + "--pem $$(rlocation $$TEST_WORKSPACE/$(rootpath //ledger/test-common/test-certificates:client.pem))", + "--include=TLSAtLeastOnePointTwoIT", + ], +) + # This deliberately uses the deploy.jar since that’s what we ship # and we want to test that the extract option works there. # Given subleties in classpaths, it could potentially work diff --git a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/suites/TLSOnePointThreeIT.scala b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/suites/TLSOnePointThreeIT.scala index b6319ccff1a..b511ee98c96 100644 --- a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/suites/TLSOnePointThreeIT.scala +++ b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/suites/TLSOnePointThreeIT.scala @@ -21,29 +21,60 @@ import scala.concurrent.Future import scala.concurrent.duration._ import scala.util.{Failure, Success, Try} -/** Verifies that the given participant server correctly handles TLSv1.3 only mode. - * - * It works by creating and exercising a series of client service stubs, each over different TLS version. - * Only TLSv1.3 connection is expected to succeed. - * Connections over lower TLS versions are expected to fail. +/** Verifies that a participant server correctly handles TLSv1.3 only mode, i.e.: + * - accepts TLSv1.3 connections, + * - rejects TLSv1.2 (or lower) connections. */ -final class TLSOnePointThreeIT extends LedgerTestSuite { - +final class TLSOnePointThreeIT + extends TlsIT(shortIdentifierPrefix = "ServerOnTLSv13ConnectionFromClientOn") { testTlsConnection(clientTlsVersion = TlsVersion.V1_3, assertConnectionOk = true) testTlsConnection(clientTlsVersion = TlsVersion.V1_2, assertConnectionOk = false) testTlsConnection(clientTlsVersion = TlsVersion.V1_1, assertConnectionOk = false) testTlsConnection(clientTlsVersion = TlsVersion.V1, assertConnectionOk = false) +} + +/** Verifies that a participant server disallows TLSv1.1 or older, i.e.: + * - accepts either TLSv1.2 or TLSv1.3 connections, + * - rejects TLSv1.1 (or lower) connections. + */ +final class TLSAtLeastOnePointTwoIT + extends TlsIT(shortIdentifierPrefix = "ServerOnTLSConnectionFromClientOn") { + testTlsConnection( + clientTlsVersions = Seq[TlsVersion](TlsVersion.V1_2, TlsVersion.V1_3), + assertConnectionOk = true, + ) + testTlsConnection(clientTlsVersion = TlsVersion.V1_1, assertConnectionOk = false) + testTlsConnection(clientTlsVersion = TlsVersion.V1, assertConnectionOk = false) +} + +/** Verifies that the given participant server correctly handles client connections over selected TLS versions. + * + * It works by creating and exercising a series of client service stubs, each over different TLS version. + */ +abstract class TlsIT(shortIdentifierPrefix: String) extends LedgerTestSuite { def testTlsConnection(clientTlsVersion: TlsVersion, assertConnectionOk: Boolean): Unit = { + testTlsConnection( + clientTlsVersions = Seq(clientTlsVersion), + assertConnectionOk = assertConnectionOk, + ) + } + + def testTlsConnection(clientTlsVersions: Seq[TlsVersion], assertConnectionOk: Boolean): Unit = { + val (what, assertionOnServerResponse) = if (assertConnectionOk) ("accept", assertSuccessfulConnection) else ("reject", assertFailedConnection) + val clientTlsVersionsText = clientTlsVersions + .map(_.version.replace(".", "")) + .mkString("and") + testGivenAllParticipants( - s"ConnectionOnTLSv13FromClientOn${clientTlsVersion.version.replace(".", "")}", - s"A ledger API server should ${what} a ${clientTlsVersion} connection", + s"$shortIdentifierPrefix$clientTlsVersionsText", + s"A ledger API server should ${what} a ${clientTlsVersions} connection", allocate(NoParties), ) { implicit ec => (testContexts: Seq[ParticipantTestContext]) => { case _ => @@ -68,7 +99,7 @@ final class TLSOnePointThreeIT extends LedgerTestSuite { // given val sslContext = tlsConfiguration - .client(enabledProtocols = Seq(clientTlsVersion)) + .client(enabledProtocols = clientTlsVersions) .getOrElse(throw new IllegalStateException("Missing SslContext!")) val serviceStubOwner: ResourceOwner[LedgerIdentityServiceBlockingStub] = for { channel <- ResourceOwner.forChannel( diff --git a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/tests/Tests.scala b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/tests/Tests.scala index c360cc22eb0..535237d1475 100644 --- a/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/tests/Tests.scala +++ b/ledger/ledger-api-test-tool/src/main/scala/com/daml/ledger/api/testtool/tests/Tests.scala @@ -76,6 +76,7 @@ object Tests { new ParticipantPruningIT, new MonotonicRecordTimeIT, new TLSOnePointThreeIT, + new TLSAtLeastOnePointTwoIT, ) val retired: Vector[LedgerTestSuite] =