From 435f876baa61c9e2e3d0b740b23cae348b9c662c Mon Sep 17 00:00:00 2001 From: usbharu Date: Mon, 23 Sep 2024 15:59:15 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20SignatureBaseBuilder=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../httpsignature/v2/DerivedComponent.kt | 7 ++ .../httpsignature/v2/HttpMessageComponent.kt | 12 ++ .../v2/HttpMessageSignatureSigner.kt | 11 +- .../httpsignature/v2/SignatureBaseBuilder.kt | 104 ++++++++++++++++++ .../usbharu/httpsignature/v2/Signatures.kt | 6 + 5 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/dev/usbharu/httpsignature/v2/DerivedComponent.kt create mode 100644 src/main/kotlin/dev/usbharu/httpsignature/v2/HttpMessageComponent.kt create mode 100644 src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureBaseBuilder.kt create mode 100644 src/main/kotlin/dev/usbharu/httpsignature/v2/Signatures.kt diff --git a/src/main/kotlin/dev/usbharu/httpsignature/v2/DerivedComponent.kt b/src/main/kotlin/dev/usbharu/httpsignature/v2/DerivedComponent.kt new file mode 100644 index 0000000..d3a302c --- /dev/null +++ b/src/main/kotlin/dev/usbharu/httpsignature/v2/DerivedComponent.kt @@ -0,0 +1,7 @@ +package dev.usbharu.httpsignature.v2 + +class DerivedComponent( + override val componentName: String, + override val componentParameter: String, + override val componentValue: String +) : Component \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/httpsignature/v2/HttpMessageComponent.kt b/src/main/kotlin/dev/usbharu/httpsignature/v2/HttpMessageComponent.kt new file mode 100644 index 0000000..bb181b8 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/httpsignature/v2/HttpMessageComponent.kt @@ -0,0 +1,12 @@ +package dev.usbharu.httpsignature.v2 + +import com.sun.org.apache.xerces.internal.util.XMLChar.trim + +class HttpMessageComponent(private val headerName: String, private val headerValues: List) : Component { + override val componentName: String + get() = headerName.lowercase() + override val componentParameter: String + get() = "" + override val componentValue: String + get() = headerValues.joinToString(", ") { it.replace("\n", " ").trim() } +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/httpsignature/v2/HttpMessageSignatureSigner.kt b/src/main/kotlin/dev/usbharu/httpsignature/v2/HttpMessageSignatureSigner.kt index d93fd0f..c8b57f8 100644 --- a/src/main/kotlin/dev/usbharu/httpsignature/v2/HttpMessageSignatureSigner.kt +++ b/src/main/kotlin/dev/usbharu/httpsignature/v2/HttpMessageSignatureSigner.kt @@ -4,5 +4,14 @@ import dev.usbharu.httpsignature.common.HttpRequest import java.security.PrivateKey class HttpMessageSignatureSigner { - fun sign(httpRequest: HttpRequest,privateKey: PrivateKey) + fun sign(material: Material, signatureParameter: SignatureParameter, signer: SignatureSigner): Signatures { + + val signatureBase = material.signatureBase.generateSignatureBase(signatureParameter) + val signatureInput = + "${material.label}=" + material.signatureBase.generateSignatureParameterString(signatureParameter) + + val signature = signer.sign(signatureBase.toByteArray(Charsets.UTF_8), material.privateKey) + + return Signatures(signatureInput, signature) + } } \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureBaseBuilder.kt b/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureBaseBuilder.kt new file mode 100644 index 0000000..c446920 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/httpsignature/v2/SignatureBaseBuilder.kt @@ -0,0 +1,104 @@ +package dev.usbharu.httpsignature.v2 + +import java.net.http.HttpRequest +import kotlin.jvm.optionals.getOrNull + +class SignatureBaseBuilder { + private val signatureBase = SignatureBase() + + fun build(): SignatureBase { + return signatureBase + } + + fun method(method: String): SignatureBaseBuilder { + signatureBase.addComponent(DerivedComponent(DerivedComponentConstants.METHOD, "", method)) + return this + } + + fun query(query: String): SignatureBaseBuilder { + require(query[0] == '?') + signatureBase.addComponent(DerivedComponent(DerivedComponentConstants.QUERY, "", query)) + return this + } + + fun targetUri(uri: String): SignatureBaseBuilder { + signatureBase.addComponent(DerivedComponent(DerivedComponentConstants.TARGET_URI, "", uri)) + return this + } + + fun authority(authority: String): SignatureBaseBuilder { + signatureBase.addComponent(DerivedComponent(DerivedComponentConstants.AUTHORITY, "", authority)) + return this + } + + fun scheme(scheme: String): SignatureBaseBuilder { + signatureBase.addComponent(DerivedComponent(DerivedComponentConstants.SCHEME, "", scheme)) + return this + } + + fun requestTarget(requestTarget: String): SignatureBaseBuilder { + signatureBase.addComponent(DerivedComponent(DerivedComponentConstants.REQUEST_TARGET, "", requestTarget)) + return this + } + + fun path(path: String): SignatureBaseBuilder { + signatureBase.addComponent(DerivedComponent(DerivedComponentConstants.PATH, "", path)) + return this + } + + fun queryParameter(key: String, value: String): SignatureBaseBuilder { + signatureBase.addComponent(DerivedComponent(DerivedComponentConstants.QUERY_PARAMETER, "name=\"$key\"", value)) + return this + } + + fun status(code: Int): SignatureBaseBuilder { + signatureBase.addComponent(DerivedComponent(DerivedComponentConstants.STATUS, "", code.toString())) + return this + } + + fun header(headerName:String,headerValues:List): SignatureBaseBuilder { + signatureBase.addComponent(HttpMessageComponent(headerName, headerValues)) + return this + } + + companion object { + fun fromHttpRequest(httpRequest: HttpRequest): SignatureBaseBuilder { + val signatureBaseBuilder = SignatureBaseBuilder() + signatureBaseBuilder.method(httpRequest.method()) + val uri = httpRequest.uri() + + signatureBaseBuilder.query(uri.rawQuery.orEmpty()) + signatureBaseBuilder.targetUri(uri.toString()) + + val headers = httpRequest.headers() + + val authority = headers.firstValue("Host").getOrNull() + if (authority != null) { + signatureBaseBuilder.authority(authority) + } + + signatureBaseBuilder.scheme(uri.scheme) + signatureBaseBuilder.requestTarget( + uri.rawPath + if ((uri.rawQuery == null)) { + "" + } else { + "?${uri.rawQuery}" + } + ) + + return signatureBaseBuilder + } + } +} + +object DerivedComponentConstants { + const val METHOD = "@method" + const val QUERY = "@query" + const val TARGET_URI = "@target-uri" + const val AUTHORITY = "@authority" + const val SCHEME = "@scheme" + const val REQUEST_TARGET = "@request-target" + const val PATH = "@path" + const val QUERY_PARAMETER = "@query-parameter" + const val STATUS = "@stats" +} \ No newline at end of file diff --git a/src/main/kotlin/dev/usbharu/httpsignature/v2/Signatures.kt b/src/main/kotlin/dev/usbharu/httpsignature/v2/Signatures.kt new file mode 100644 index 0000000..0ff510b --- /dev/null +++ b/src/main/kotlin/dev/usbharu/httpsignature/v2/Signatures.kt @@ -0,0 +1,6 @@ +package dev.usbharu.httpsignature.v2 + +data class Signatures( + val signatureInput: String, + val signature: String +)