refactor: signature-paramsの順番指定

に対応
This commit is contained in:
usbharu 2024-09-23 21:15:28 +09:00
parent e85e5d10f9
commit ebe864fd10
Signed by: usbharu
GPG Key ID: 95CBCF7046307B77
7 changed files with 74 additions and 39 deletions

View File

@ -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<SignatureParameter>, 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)

View File

@ -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()
}

View File

@ -11,24 +11,25 @@ class SignatureBase() {
list[component.componentIdentifier] = component
}
fun generateSignatureBase(signatureParameter: SignatureParameter): String {
fun generateSignatureBase(signatureParameters: List<SignatureParameter>): 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<SignatureParameter>): String {
return (listOf(
list.keys.joinToString(
" ",
"(",
")"
)
) + signatureParameters.map { "${it.name}=${it.value}" }).joinToString(";")
}
}

View File

@ -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
}

View File

@ -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<SignatureParameter> {
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) },
)
}
}

View File

@ -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\""
}

View File

@ -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)