From 281a96ee9806f200020f4716d17e5d4c7880f213 Mon Sep 17 00:00:00 2001 From: Gus Narea Date: Tue, 11 Jun 2024 15:49:24 +0100 Subject: [PATCH] fix: Tolerate clock drift when creating VeraId signatures (#275) --- .../utils/veraid/VeraidSignatureProcessor.kt | 8 +++-- .../veraid/VeraidSignatureProcessorTest.kt | 33 ++++++++++++++++++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/tech/relaycorp/letro/utils/veraid/VeraidSignatureProcessor.kt b/app/src/main/java/tech/relaycorp/letro/utils/veraid/VeraidSignatureProcessor.kt index 6ce4261b..c2bce39c 100644 --- a/app/src/main/java/tech/relaycorp/letro/utils/veraid/VeraidSignatureProcessor.kt +++ b/app/src/main/java/tech/relaycorp/letro/utils/veraid/VeraidSignatureProcessor.kt @@ -8,6 +8,7 @@ import tech.relaycorp.veraid.pki.MemberIdBundle import java.security.PrivateKey import java.time.ZonedDateTime import kotlin.time.Duration.Companion.days +import kotlin.time.Duration.Companion.minutes import kotlin.time.toJavaDuration typealias BundleGenerator = ( @@ -26,6 +27,7 @@ class VeraidSignatureProcessor( private val bundleGenerator: BundleGenerator = SignatureBundle.Companion::generate, private val bundleDeserialiser: BundleDeserialiser = SignatureBundle.Companion::deserialise, ) { + private val bundleClockDriftTolerance = 5.minutes.toJavaDuration() private val bundleTtl = 90.days.toJavaDuration() @Throws(VeraidSignatureException::class) @@ -34,15 +36,15 @@ class VeraidSignatureProcessor( memberIdBundle: MemberIdBundle, memberPrivateKey: PrivateKey, ): ByteArray { - val creationDate = ZonedDateTime.now() + val now = ZonedDateTime.now() val signatureBundle = try { bundleGenerator( plaintext, LetroOids.LETRO_VERAID_OID, memberIdBundle, memberPrivateKey, - creationDate.plus(bundleTtl), - creationDate, + now.plus(bundleTtl), + now.minus(bundleClockDriftTolerance), true, ) } catch (exc: SignatureException) { diff --git a/app/src/test/java/tech/relaycorp/letro/utils/veraid/VeraidSignatureProcessorTest.kt b/app/src/test/java/tech/relaycorp/letro/utils/veraid/VeraidSignatureProcessorTest.kt index ebf1ca73..0077f7a6 100644 --- a/app/src/test/java/tech/relaycorp/letro/utils/veraid/VeraidSignatureProcessorTest.kt +++ b/app/src/test/java/tech/relaycorp/letro/utils/veraid/VeraidSignatureProcessorTest.kt @@ -22,11 +22,13 @@ import tech.relaycorp.veraid.SignatureException import tech.relaycorp.veraid.pki.MemberIdBundle import java.time.ZonedDateTime import kotlin.time.Duration.Companion.days +import kotlin.time.Duration.Companion.minutes import kotlin.time.toJavaDuration class VeraidSignatureProcessorTest { private val stubPlaintext = "plaintext".toByteArray() + val clockDriftTolerance = 5.minutes.toJavaDuration() val ninetyDays = 90.days.toJavaDuration() @Nested @@ -96,6 +98,35 @@ class VeraidSignatureProcessorTest { } } + @Test + fun `Signature creation date should be within a few minutes in the past`() { + val generator = mockSignatureBundleGenerator(Result.success(stubSignatureBundle)) + val processor = VeraidSignatureProcessor(generator) + val timeBefore = ZonedDateTime.now() + + processor.produce( + stubPlaintext, + mockMemberIdBundle, + VERAID_MEMBER_KEY_PAIR.private, + ) + + val timeAfter = ZonedDateTime.now() + verify { + generator( + any(), + any(), + any(), + any(), + any(), + match { + timeBefore.minus(clockDriftTolerance) <= it && + it <= timeAfter.minus(clockDriftTolerance) + }, + any(), + ) + } + } + @Test fun `Signature should expire in 90 days`() { val generator = mockSignatureBundleGenerator(Result.success(stubSignatureBundle)) @@ -118,7 +149,7 @@ class VeraidSignatureProcessorTest { match { timeBefore.plus(ninetyDays) <= it && it <= timeAfter.plus(ninetyDays) }, - match { timeBefore <= it && it <= timeAfter }, + any(), any(), ) }