From c099930cf3e65813c967fa8f56ab20ea3999fd6a Mon Sep 17 00:00:00 2001 From: cheddar Date: Mon, 10 Feb 2025 23:07:41 -0500 Subject: [PATCH] Initial commit - test client --- README.md | 3 +++ client/client.go | 39 +++++++++++++++++++++++++++++++++ go.mod | 13 +++++++++++ go.sum | 12 +++++++++++ main.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ shell.nix | 6 ++++++ testkey | 7 ++++++ testkey.pub | 1 + 8 files changed, 137 insertions(+) create mode 100644 README.md create mode 100644 client/client.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 shell.nix create mode 100644 testkey create mode 100644 testkey.pub diff --git a/README.md b/README.md new file mode 100644 index 0000000..fb8f743 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# sig-auth + +Signature authentication service designed to be used as middleware for a reverse proxy diff --git a/client/client.go b/client/client.go new file mode 100644 index 0000000..ba33d12 --- /dev/null +++ b/client/client.go @@ -0,0 +1,39 @@ +package client + +import ( + "crypto" + "crypto/ecdsa" + "crypto/ed25519" + "crypto/rsa" + "fmt" + "net/http" + "reflect" + + "github.com/common-fate/httpsig" + "github.com/common-fate/httpsig/alg_ecdsa" + "github.com/common-fate/httpsig/alg_ed25519" + "github.com/common-fate/httpsig/alg_rsa" + "github.com/common-fate/httpsig/signer" +) + +func GetSigningClient(key crypto.PrivateKey, keyId string) (*http.Client, error) { + var alg signer.Algorithm + + switch p := key.(type) { + case *rsa.PrivateKey: + alg = alg_rsa.NewRSAPKCS256Signer(p) + case *ed25519.PrivateKey: + alg = alg_ed25519.Ed25519{PrivateKey: *p} + case *ecdsa.PrivateKey: + alg = alg_ecdsa.NewP256Signer(p) + default: + return nil, fmt.Errorf("type is unknown: %s", reflect.TypeOf(key)) + } + + client := httpsig.NewClient(httpsig.ClientOpts{ + KeyID: keyId, + Alg: alg, + }) + + return client, nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..600f557 --- /dev/null +++ b/go.mod @@ -0,0 +1,13 @@ +module crispbyte.dev/sig-auth + +go 1.23.4 + +require ( + github.com/common-fate/httpsig v0.2.1 + golang.org/x/crypto v0.33.0 +) + +require ( + github.com/dunglas/httpsfv v1.0.2 // indirect + golang.org/x/sys v0.30.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..cf96422 --- /dev/null +++ b/go.sum @@ -0,0 +1,12 @@ +github.com/common-fate/httpsig v0.2.1 h1:3frYlirzDCbynvp4OleEIm7JdgvWfeNVW8KUmQHZ04w= +github.com/common-fate/httpsig v0.2.1/go.mod h1:nMk4aBS8GDo8tiUMLqB60W6I3+BiNH5Uj437pV61Jl8= +github.com/dunglas/httpsfv v1.0.2 h1:iERDp/YAfnojSDJ7PW3dj1AReJz4MrwbECSSE59JWL0= +github.com/dunglas/httpsfv v1.0.2/go.mod h1:zID2mqw9mFsnt7YC3vYQ9/cjq30q41W+1AnDwH8TiMg= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= diff --git a/main.go b/main.go new file mode 100644 index 0000000..5cd4658 --- /dev/null +++ b/main.go @@ -0,0 +1,56 @@ +package main + +import ( + "bytes" + "crypto" + "encoding/json" + "fmt" + "log" + "os" + + "crispbyte.dev/sig-auth/client" + "golang.org/x/crypto/ssh" +) + +func main() { + testData := map[string]string{"hello": "world"} + json_data, _ := json.Marshal(testData) + + keyFile := "testkey" + + key, err := loadPrivateKey(keyFile) + + if err != nil { + log.Fatal(err) + } + + client, err := client.GetSigningClient(key, "test-id") + + if err != nil { + log.Fatal(err) + } + + resp, err := client.Post("http://localhost:8080/post", "application/json", bytes.NewBuffer(json_data)) + + if err != nil { + log.Fatal(err) + } + + defer resp.Body.Close() + + var res map[string]interface{} + + json.NewDecoder(resp.Body).Decode(&res) + + fmt.Println(res) +} + +func loadPrivateKey(keyFile string) (crypto.PrivateKey, error) { + keyBytes, err := os.ReadFile(keyFile) + + if err != nil { + return nil, err + } + + return ssh.ParseRawPrivateKey(keyBytes) +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..d0d57c1 --- /dev/null +++ b/shell.nix @@ -0,0 +1,6 @@ +{ pkgs ? import {} }: + pkgs.mkShell { + nativeBuildInputs = with pkgs.buildPackages; [ + go + ]; +} diff --git a/testkey b/testkey new file mode 100644 index 0000000..c3fbbbd --- /dev/null +++ b/testkey @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACClBMnrOEzDPIDNzMdasPn+BI6FRixvQxNTXDX7HOWOXgAAAJCI3nP3iN5z +9wAAAAtzc2gtZWQyNTUxOQAAACClBMnrOEzDPIDNzMdasPn+BI6FRixvQxNTXDX7HOWOXg +AAAEBpWmg8wb9vnPh9P38pGBHMqq2myayLWEY8I+8EMAIcq6UEyes4TMM8gM3Mx1qw+f4E +joVGLG9DE1NcNfsc5Y5eAAAADGphbWllQGF0aGVuYQE= +-----END OPENSSH PRIVATE KEY----- diff --git a/testkey.pub b/testkey.pub new file mode 100644 index 0000000..fb64d39 --- /dev/null +++ b/testkey.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKUEyes4TMM8gM3Mx1qw+f4EjoVGLG9DE1NcNfsc5Y5e test@key