From d802053c6f89371692679b28b4df1c24b7cdf0b9 Mon Sep 17 00:00:00 2001 From: Andrew Barba Date: Thu, 10 Nov 2022 17:36:43 -0500 Subject: [PATCH] TLS Client Fingerprint --- .swift-version | 1 + Makefile | 4 ++++ Package.swift | 3 ++- Sources/Compute/IncomingRequest.swift | 7 +++++++ Sources/Compute/Runtime/Request.swift | 9 +++++++++ Sources/Compute/Runtime/Stubs.swift | 2 ++ Sources/ComputeRuntime/include/ComputeRuntime.h | 3 +++ Sources/Demo/main.swift | 10 ++++++++++ fastly.toml | 2 ++ 9 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 .swift-version create mode 100644 Sources/Demo/main.swift create mode 100644 fastly.toml diff --git a/.swift-version b/.swift-version new file mode 100644 index 00000000..db7e94b8 --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +wasm-5.7.1 diff --git a/Makefile b/Makefile index b5ae79f0..6969fd75 100644 --- a/Makefile +++ b/Makefile @@ -12,3 +12,7 @@ docc: github-pages: echo "compute-runtime.swift.cloud" > docs/CNAME + +demo: + swift build -c debug --triple wasm32-unknown-wasi + fastly compute serve --skip-build --file ./.build/debug/*.wasm diff --git a/Package.swift b/Package.swift index 10102647..189585df 100644 --- a/Package.swift +++ b/Package.swift @@ -15,6 +15,7 @@ let package = Package( ], targets: [ .target(name: "Compute", dependencies: ["ComputeRuntime"]), - .target(name: "ComputeRuntime") + .target(name: "ComputeRuntime"), + .executableTarget(name: "Demo", dependencies: ["Compute"]) ] ) diff --git a/Sources/Compute/IncomingRequest.swift b/Sources/Compute/IncomingRequest.swift index 1e4957c7..dbf9d047 100644 --- a/Sources/Compute/IncomingRequest.swift +++ b/Sources/Compute/IncomingRequest.swift @@ -90,3 +90,10 @@ extension IncomingRequest { } } } + +extension IncomingRequest { + + public func clientFingerprint() -> String? { + return try? request.tlsJa3Md5() + } +} diff --git a/Sources/Compute/Runtime/Request.swift b/Sources/Compute/Runtime/Request.swift index dfcd612f..10624870 100644 --- a/Sources/Compute/Runtime/Request.swift +++ b/Sources/Compute/Runtime/Request.swift @@ -288,3 +288,12 @@ extension Request { return bytes.split { $0 == 0 }.compactMap { String(bytes: $0, encoding: .utf8) } } } + +extension Request { + + public func tlsJa3Md5() throws -> String? { + return try wasiString(maxBufferLength: 16) { buffer, _, written in + fastly_http_req__downstream_tls_ja3_md5(buffer, &written) + } + } +} diff --git a/Sources/Compute/Runtime/Stubs.swift b/Sources/Compute/Runtime/Stubs.swift index 9ca0dade..625b1b9e 100644 --- a/Sources/Compute/Runtime/Stubs.swift +++ b/Sources/Compute/Runtime/Stubs.swift @@ -130,6 +130,8 @@ func fastly_http_req__redirect_to_grip_proxy(_ backend: UnsafePointer!, _ func fastly_http_req__register_dynamic_backend(_ name: UnsafePointer!, _ name_len: Int, _ target: UnsafePointer!, _ target_len: Int, _ backend_config_mask: UInt32, _ backend_configuration: UnsafeMutablePointer!) -> Int32 { fatalError() } +func fastly_http_req__downstream_tls_ja3_md5(_ value: UnsafeMutablePointer!, _ nwritten: UnsafeMutablePointer!) -> Int32 { fatalError() } + /* FASTLY_HTTP_RESP */ func fastly_http_resp__new(_ handle: UnsafeMutablePointer!) -> Int32 { fatalError() } diff --git a/Sources/ComputeRuntime/include/ComputeRuntime.h b/Sources/ComputeRuntime/include/ComputeRuntime.h index eea521f3..d90eee8d 100644 --- a/Sources/ComputeRuntime/include/ComputeRuntime.h +++ b/Sources/ComputeRuntime/include/ComputeRuntime.h @@ -197,6 +197,9 @@ int fastly_http_req__redirect_to_websocket_proxy(const char *backend, size_t bac WASM_IMPORT("fastly_http_req", "redirect_to_grip_proxy") int fastly_http_req__redirect_to_grip_proxy(const char *backend, size_t backend_len); +WASM_IMPORT("fastly_http_req", "downstream_tls_ja3_md5") +int fastly_http_req__downstream_tls_ja3_md5(uint8_t *value, size_t *nwritten); + WASM_IMPORT("fastly_http_req", "register_dynamic_backend") int fastly_http_req__register_dynamic_backend(const char *name, size_t name_len, diff --git a/Sources/Demo/main.swift b/Sources/Demo/main.swift new file mode 100644 index 00000000..08225341 --- /dev/null +++ b/Sources/Demo/main.swift @@ -0,0 +1,10 @@ +import Compute + +let router = Router() + +router.get("/") { req, res in + print("fingerprint:", req.clientFingerprint() ?? "(null)") + try await res.status(200).send("Hello, Swift") +} + +try await router.listen() diff --git a/fastly.toml b/fastly.toml new file mode 100644 index 00000000..7f077f94 --- /dev/null +++ b/fastly.toml @@ -0,0 +1,2 @@ +language = "swift" +manifest_version = 2