From ebe864fd105a5e4e354fa230af16e1d4e3d38839 Mon Sep 17 00:00:00 2001 From: usbharu Date: Mon, 23 Sep 2024 21:15:28 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20signature-params=E3=81=AE=E9=A0=86?= =?UTF-8?q?=E7=95=AA=E6=8C=87=E5=AE=9A=20=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v2/HttpMessageSignatureSigner.kt | 9 +++---- .../v2/InstantSignatureParameter.kt | 10 +++++++ .../usbharu/httpsignature/v2/SignatureBase.kt | 27 ++++++++++--------- .../httpsignature/v2/SignatureParameter.kt | 15 +++-------- .../httpsignature/v2/SignatureParameters.kt | 24 +++++++++++++++++ .../v2/StringSignatureParameter.kt | 8 ++++++ .../httpsignature/v2/GenerateSignatureTest.kt | 20 +++++++------- 7 files changed, 74 insertions(+), 39 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/httpsignature/v2/InstantSignatureParameter.kt create mode 100644 src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureParameters.kt create mode 100644 src/main/kotlin/dev/usbharu/httpsignature/v2/StringSignatureParameter.kt diff --git a/src/main/kotlin/dev/usbharu/httpsignature/v2/HttpMessageSignatureSigner.kt b/src/main/kotlin/dev/usbharu/httpsignature/v2/HttpMessageSignatureSigner.kt index c8b57f8..ae36e89 100644 --- a/src/main/kotlin/dev/usbharu/httpsignature/v2/HttpMessageSignatureSigner.kt +++ b/src/main/kotlin/dev/usbharu/httpsignature/v2/HttpMessageSignatureSigner.kt @@ -1,14 +1,11 @@ package dev.usbharu.httpsignature.v2 -import dev.usbharu.httpsignature.common.HttpRequest -import java.security.PrivateKey - class HttpMessageSignatureSigner { - fun sign(material: Material, signatureParameter: SignatureParameter, signer: SignatureSigner): Signatures { + fun sign(material: Material, signatureParameters: List, signer: SignatureSigner): Signatures { - val signatureBase = material.signatureBase.generateSignatureBase(signatureParameter) + val signatureBase = material.signatureBase.generateSignatureBase(signatureParameters) val signatureInput = - "${material.label}=" + material.signatureBase.generateSignatureParameterString(signatureParameter) + "${material.label}=" + material.signatureBase.generateSignatureParameterString(signatureParameters) val signature = signer.sign(signatureBase.toByteArray(Charsets.UTF_8), material.privateKey) diff --git a/src/main/kotlin/dev/usbharu/httpsignature/v2/InstantSignatureParameter.kt b/src/main/kotlin/dev/usbharu/httpsignature/v2/InstantSignatureParameter.kt new file mode 100644 index 0000000..2918dce --- /dev/null +++ b/src/main/kotlin/dev/usbharu/httpsignature/v2/InstantSignatureParameter.kt @@ -0,0 +1,10 @@ +package dev.usbharu.httpsignature.v2 + +import java.time.Instant + +class InstantSignatureParameter(private val instantName: String, val instant: Instant) : SignatureParameter { + override val name: String + get() = instantName + override val value: String + get() = instant.epochSecond.toString() +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureBase.kt b/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureBase.kt index 8d9b313..1e13482 100644 --- a/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureBase.kt +++ b/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureBase.kt @@ -11,24 +11,25 @@ class SignatureBase() { list[component.componentIdentifier] = component } - fun generateSignatureBase(signatureParameter: SignatureParameter): String { + fun generateSignatureBase(signatureParameters: List): String { val signatureBase = - list.values.joinToString(separator = "",postfix = "\n") { component -> "${component.componentIdentifier}: ${component.componentValue}" } + list.values.joinToString( + separator = "", + postfix = "\n" + ) { component -> "${component.componentIdentifier}: ${component.componentValue}" } - val signatureParams = "\"@signature-params\": " + generateSignatureParameterString(signatureParameter) + val signatureParams = "\"@signature-params\": " + generateSignatureParameterString(signatureParameters) return signatureBase + signatureParams } - fun generateSignatureParameterString(signatureParameter: SignatureParameter): String { - return listOfNotNull( - list.keys.joinToString(" ", "(", ")"), - signatureParameter.algorithm?.let { algorithm -> "alg=\"${algorithm}\"" }, - signatureParameter.keyId?.let { keyId -> "keyid=\"$keyId\"" }, - signatureParameter.created?.let { created -> "created=${created.epochSecond}" }, - signatureParameter.expires?.let { expires -> "expires=${expires.epochSecond}" }, - signatureParameter.nonce?.let { nonce -> "nonce=\"$nonce\"" }, - signatureParameter.tag?.let { tag -> "tag=\"$tag\"" }, - ).joinToString(";") + fun generateSignatureParameterString(signatureParameters: List): String { + return (listOf( + list.keys.joinToString( + " ", + "(", + ")" + ) + ) + signatureParameters.map { "${it.name}=${it.value}" }).joinToString(";") } } diff --git a/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureParameter.kt b/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureParameter.kt index 43ec442..bc3c61e 100644 --- a/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureParameter.kt +++ b/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureParameter.kt @@ -1,13 +1,6 @@ package dev.usbharu.httpsignature.v2 -import java.time.Instant - -data class SignatureParameter( - val algorithm: String? = null, - val keyId: String? = null, - val created: Instant? = null, - val expires: Instant? = null, - val nonce: String? = null, - val tag: String? = null, -) - +interface SignatureParameter { + val name: String + val value: String +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureParameters.kt b/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureParameters.kt new file mode 100644 index 0000000..16e68e6 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureParameters.kt @@ -0,0 +1,24 @@ +package dev.usbharu.httpsignature.v2 + +import java.time.Instant + +data class SignatureParameters( + val algorithm: String? = null, + val keyId: String? = null, + val created: Instant? = null, + val expires: Instant? = null, + val nonce: String? = null, + val tag: String? = null, +) { + fun toParameterList(): List { + return listOfNotNull( + this.algorithm?.let { algorithm -> StringSignatureParameter("alg", algorithm) }, + this.keyId?.let { keyId -> StringSignatureParameter("keyid", keyId) }, + this.created?.let { created -> InstantSignatureParameter("created", created) }, + this.expires?.let { expires -> InstantSignatureParameter("expires", expires) }, + this.nonce?.let { nonce -> StringSignatureParameter("nonce", nonce) }, + this.tag?.let { tag -> StringSignatureParameter("tag", tag) }, + ) + } +} + diff --git a/src/main/kotlin/dev/usbharu/httpsignature/v2/StringSignatureParameter.kt b/src/main/kotlin/dev/usbharu/httpsignature/v2/StringSignatureParameter.kt new file mode 100644 index 0000000..3ed05ec --- /dev/null +++ b/src/main/kotlin/dev/usbharu/httpsignature/v2/StringSignatureParameter.kt @@ -0,0 +1,8 @@ +package dev.usbharu.httpsignature.v2 + +class StringSignatureParameter(private val stringName: String, private val stringValue: String) : SignatureParameter { + override val name: String + get() = stringName + override val value: String + get() = "\"$stringValue\"" +} \ No newline at end of file diff --git a/src/test/kotlin/dev/usbharu/httpsignature/v2/GenerateSignatureTest.kt b/src/test/kotlin/dev/usbharu/httpsignature/v2/GenerateSignatureTest.kt index 5934a7b..ee0f0d7 100644 --- a/src/test/kotlin/dev/usbharu/httpsignature/v2/GenerateSignatureTest.kt +++ b/src/test/kotlin/dev/usbharu/httpsignature/v2/GenerateSignatureTest.kt @@ -12,7 +12,6 @@ import java.security.spec.PSSParameterSpec import java.security.spec.X509EncodedKeySpec import java.time.Instant import java.util.* -import kotlin.math.sign class GenerateSignatureTest { @@ -64,7 +63,7 @@ class GenerateSignatureTest { val signer = HttpMessageSignatureSigner() - val sign = signer.sign(material, SignatureParameter(), RsaV1_5Sha256SignatureSigner()) + val sign = signer.sign(material, SignatureParameters().toParameterList(), RsaV1_5Sha256SignatureSigner()) val expectedSignatureBase = "\"host\": example.com\n" + "\"@signature-params\": (\"host\")" @@ -74,11 +73,14 @@ class GenerateSignatureTest { val expectedSignatureInput = "label=(\"host\")" - assertEquals(expectedSignatureBase, signatureBase.generateSignatureBase(SignatureParameter())) + assertEquals( + expectedSignatureBase, + signatureBase.generateSignatureBase(SignatureParameters().toParameterList()) + ) assertEquals(expectedSignatureValue, sign.signature) assertEquals(expectedSignatureInput, sign.signatureInput) - println(signatureBase.generateSignatureBase(SignatureParameter())) + println(signatureBase.generateSignatureBase(SignatureParameters().toParameterList())) println(sign.signature) println(sign.signatureInput) } @@ -129,7 +131,7 @@ class GenerateSignatureTest { "sig" ) - val signatureParameter = SignatureParameter( + val signatureParameters = SignatureParameters( algorithm = "rsa-pss-sha512", keyId = "a", created = Instant.ofEpochSecond(1727076643), @@ -139,7 +141,7 @@ class GenerateSignatureTest { ) val sign = signer.sign( material, - signatureParameter, + signatureParameters.toParameterList(), RsaPssSha512SignatureSigner() ) @@ -148,12 +150,12 @@ class GenerateSignatureTest { val expectedSignatureInput = "sig=(\"host\");alg=\"rsa-pss-sha512\";keyid=\"a\";created=1727076643;nonce=\"a\";tag=\"a\"" - assertEquals(expectedSignatureBase, signatureBase.generateSignatureBase(signatureParameter)) + assertEquals(expectedSignatureBase, signatureBase.generateSignatureBase(signatureParameters.toParameterList())) assertEquals(expectedSignatureInput, sign.signatureInput) println(sign.signature) - println(signatureBase.generateSignatureBase(signatureParameter)) + println(signatureBase.generateSignatureBase(signatureParameters.toParameterList())) @@ -174,7 +176,7 @@ class GenerateSignatureTest { val signature = Signature.getInstance("RSASSA-PSS") signature.setParameter(PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 64, PSSParameterSpec.TRAILER_FIELD_BC)) signature.initVerify(publicKey) - signature.update(signatureBase.generateSignatureBase(signatureParameter).toByteArray()) + signature.update(signatureBase.generateSignatureBase(signatureParameters.toParameterList()).toByteArray()) val verify = signature.verify(Base64.getDecoder().decode(sign.signature)) assertTrue(verify)