This commit is contained in:
Paul Schaub 2024-03-30 21:33:10 +01:00
parent 2656f63942
commit 4a5f53cb90
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
8 changed files with 162 additions and 0 deletions

View file

@ -0,0 +1,28 @@
package pgp.hkp
import pgp.hkp.operation.Get
import java.net.http.HttpClient
open class HKPApi(
val http: HttpClient,
val service: HKPServerInfo,
val openpgp: OpenPgpImplementation
) {
companion object {
const val REQUEST_PATH_PREFIX = "/pks"
const val REQUEST_PATH_LOOKUP = "${Companion.REQUEST_PATH_PREFIX}/lookup"
const val REQUEST_PATH_ADD = "${Companion.REQUEST_PATH_PREFIX}/add"
const val VAR_OP = "op"
const val VAR_SEARCH = "search"
const val OP_GET = "get"
const val OP_INDEX = "index"
const val OP_VINDEX = "vindex"
const val OP_STATS = "stats"
const val OP_HGET = "hget"
}
fun get() = Get(http, service, openpgp)
}

View file

@ -0,0 +1,8 @@
package pgp.hkp
import java.net.URI
data class HKPServerInfo(
val serviceUri: URI,
) {
}

View file

@ -0,0 +1,14 @@
package pgp.hkp
import java.net.http.HttpClient
class HockeypuckApi(
http: HttpClient,
service: HKPServerInfo,
openpgp: OpenPgpImplementation
) : HKPApi(http, service, openpgp) {
companion object {
const val REQUEST_PATH_DELETE = "$REQUEST_PATH_PREFIX/delete"
const val REQUEST_PATH_REPLACE = "$REQUEST_PATH_PREFIX/replace"
}
}

View file

@ -0,0 +1,8 @@
package pgp.hkp
abstract class OpenPgpImplementation {
abstract fun hexKeyId(keyId: Long): CharSequence
abstract fun hexFingerprint(fingerprint: ByteArray): CharSequence
}

View file

@ -0,0 +1,13 @@
package pgp.hkp
import java.net.http.HttpClient
class SKSApi(
http: HttpClient,
service: HKPServerInfo,
openpgp: OpenPgpImplementation
) : HKPApi(http, service, openpgp) {
companion object {
const val REQUEST_PATH_HASHQUERY = "$REQUEST_PATH_PREFIX/hashquery"
}
}

View file

@ -0,0 +1,30 @@
package pgp.hkp.operation
import pgp.hkp.HKPApi.Companion.OP_GET
import pgp.hkp.HKPServerInfo
import pgp.hkp.OpenPgpImplementation
import java.net.http.HttpClient
class Get(val http: HttpClient,
val service: HKPServerInfo,
val openpgp: OpenPgpImplementation) {
fun byKeyId(keyId: Long): LookupRequest {
return LookupRequest(http, service, OP_GET, "0x${openpgp.hexKeyId(keyId)}")
}
fun byFingerprint(fingerprint: ByteArray): LookupRequest {
return byFingerprint(openpgp.hexFingerprint(fingerprint))
}
fun byFingerprint(fingerprint: CharSequence): LookupRequest {
require(fingerprint.length in listOf(32, 40, 64)) {
"Fingerprint strings are either 32 (v3), 40 (v4) or 64 (v6) hexadecimal digits."
}
return LookupRequest(http, service, OP_GET, "0x$fingerprint")
}
fun byUserId(userId: CharSequence): LookupRequest {
return LookupRequest(http, service, OP_GET, userId.toString())
}
}

View file

@ -0,0 +1,34 @@
package pgp.hkp.operation
import pgp.hkp.HKPApi.Companion.REQUEST_PATH_LOOKUP
import pgp.hkp.HKPApi.Companion.VAR_OP
import pgp.hkp.HKPApi.Companion.VAR_SEARCH
import pgp.hkp.HKPServerInfo
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.net.http.HttpResponse.BodySubscribers
class LookupRequest(
val http: HttpClient,
val service: HKPServerInfo,
val op: CharSequence,
val search: CharSequence
) {
val path: CharSequence
get() = "$REQUEST_PATH_LOOKUP?search=$search&op=$op"
fun execute() {
val request = HttpRequest.newBuilder(URIBuilder()URI.create("${service.serviceUri}$REQUEST_PATH_LOOKUP"))
.GET()
.(VAR_SEARCH, search.toString())
.header(VAR_OP, op.toString())
.build()
println(request.toString())
http.send(request, HttpResponse.BodyHandler {it -> BodySubscribers.ofByteArray()})
}
}

View file

@ -0,0 +1,27 @@
package pgp.hkp
import org.junit.jupiter.api.Test
import java.net.URI
import java.net.http.HttpClient
import java.util.HexFormat
class HKPApiTest {
@Test
fun test() {
val api = HKPApi(HttpClient.newHttpClient(),
HKPServerInfo(URI.create("http://keys.example.com:11371")),
object : OpenPgpImplementation() {
override fun hexKeyId(keyId: Long): CharSequence {
return keyId.toString(16)
}
override fun hexFingerprint(fingerprint: ByteArray): CharSequence {
return HexFormat.of().formatHex(fingerprint)
}
}
)
api.get().byUserId("Alice").execute()
}
}