- commit
- 6bc1ce6
- parent
- b223a25
- author
- cheddar
- date
- 2025-02-15 01:41:22 +0100 CET
Implement test server
6 files changed,
+152,
-6
+1,
-0
1@@ -31,6 +31,7 @@ func GetSigningClient(key crypto.PrivateKey, keyId string) (*http.Client, error)
2 }
3
4 client := httpsig.NewClient(httpsig.ClientOpts{
5+ Tag: "test-tag",
6 KeyID: keyId,
7 Alg: alg,
8 })
M
main.go
+47,
-6
1@@ -4,22 +4,38 @@ import (
2 "bytes"
3 "crypto"
4 "encoding/json"
5+ "flag"
6 "fmt"
7+ "io"
8 "log"
9+ "net/http"
10 "os"
11
12 "crispbyte.dev/sig-auth/client"
13+ "crispbyte.dev/sig-auth/server"
14 "github.com/opencontainers/go-digest"
15 "golang.org/x/crypto/ssh"
16 )
17
18 func main() {
19+ useClient := flag.Bool("c", false, "Run client")
20+
21+ keyPath := flag.String("key", "", "Path to the private (client mode) or public (server mode) to use")
22+
23+ flag.Parse()
24+
25+ if *useClient {
26+ runClient(keyPath)
27+ } else {
28+ runServer(keyPath)
29+ }
30+}
31+
32+func runClient(keyFile *string) {
33 testData := map[string]string{"hello": "world"}
34 json_data, _ := json.Marshal(testData)
35
36- keyFile := "testkey"
37-
38- key, err := loadPrivateKey(keyFile)
39+ key, err := loadPrivateKey(*keyFile)
40
41 if err != nil {
42 log.Fatal(err)
43@@ -50,11 +66,24 @@ func main() {
44
45 defer resp.Body.Close()
46
47- var res map[string]interface{}
48+ out, err := io.ReadAll(resp.Body)
49+
50+ if err != nil {
51+ log.Fatal(err)
52+ }
53+
54+ fmt.Println(resp.StatusCode)
55+ fmt.Println(string(out[:]))
56+}
57+
58+func runServer(keyFile *string) {
59+ key, err := loadPublicKey(*keyFile)
60
61- json.NewDecoder(resp.Body).Decode(&res)
62+ if err != nil {
63+ log.Fatal(err)
64+ }
65
66- fmt.Println(res)
67+ server.Start(key)
68 }
69
70 func loadPrivateKey(keyFile string) (crypto.PrivateKey, error) {
71@@ -66,3 +95,15 @@ func loadPrivateKey(keyFile string) (crypto.PrivateKey, error) {
72
73 return ssh.ParseRawPrivateKey(keyBytes)
74 }
75+
76+func loadPublicKey(keyFile string) (crypto.PublicKey, error) {
77+ keyBytes, err := os.ReadFile(keyFile)
78+
79+ if err != nil {
80+ return nil, err
81+ }
82+
83+ pk, _, _, _, err := ssh.ParseAuthorizedKey(keyBytes)
84+
85+ return pk.(ssh.CryptoPublicKey).CryptoPublicKey(), err
86+}
+40,
-0
1@@ -0,0 +1,40 @@
2+package server
3+
4+import (
5+ "context"
6+ "crypto"
7+ "crypto/ed25519"
8+ "fmt"
9+
10+ "github.com/common-fate/httpsig/alg_ed25519"
11+ "github.com/common-fate/httpsig/verifier"
12+)
13+
14+type KeyEntry struct {
15+ alg string
16+ publicKey crypto.PublicKey
17+ userId string
18+}
19+
20+type InMemoryDirectory struct {
21+ records map[string]KeyEntry
22+}
23+
24+func (dir *InMemoryDirectory) GetKey(ctx context.Context, keyId string, _ string) (verifier.Algorithm, error) {
25+ entry := dir.records[keyId]
26+
27+ var alg verifier.Algorithm
28+ var err error
29+
30+ switch entry.alg {
31+ case "ed25519":
32+ alg = alg_ed25519.Ed25519{
33+ PublicKey: entry.publicKey.(ed25519.PublicKey),
34+ Attrs: entry.userId,
35+ }
36+ default:
37+ err = fmt.Errorf("unknown algoritm: %s", entry.alg)
38+ }
39+
40+ return alg, err
41+}
+56,
-0
1@@ -0,0 +1,56 @@
2+package server
3+
4+import (
5+ "context"
6+ "crypto"
7+ "fmt"
8+ "net/http"
9+
10+ "github.com/common-fate/httpsig"
11+ "github.com/common-fate/httpsig/inmemory"
12+)
13+
14+func Start(publicKey crypto.PublicKey) error {
15+ keyDir := InMemoryDirectory{
16+ records: map[string]KeyEntry{},
17+ }
18+
19+ keyId := "test-id"
20+
21+ keyDir.records[keyId] = KeyEntry{
22+ alg: "ed25519",
23+ publicKey: publicKey,
24+ userId: "test_user",
25+ }
26+
27+ mux := http.NewServeMux()
28+
29+ verifier := httpsig.Middleware(httpsig.MiddlewareOpts{
30+ NonceStorage: inmemory.NewNonceStorage(),
31+ KeyDirectory: &keyDir,
32+ Tag: "test-tag",
33+ Scheme: "http",
34+ Authority: "localhost:8080",
35+
36+ OnValidationError: func(ctx context.Context, err error) {
37+ fmt.Printf("validation error: %s\n", err)
38+ },
39+
40+ OnDeriveSigningString: func(ctx context.Context, stringToSign string) {
41+ fmt.Printf("string to sign:\n%s\n", stringToSign)
42+ },
43+ })
44+
45+ mux.Handle("/", verifier(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
46+ fmt.Printf("Responding...\n")
47+ attr := httpsig.AttributesFromContext(r.Context()).(string)
48+ fmt.Printf("User is %s\n", attr)
49+ msg := fmt.Sprintf("hello, %s!", attr)
50+ w.Write([]byte(msg))
51+ fmt.Printf("Responded...\n")
52+ })))
53+
54+ err := http.ListenAndServe("localhost:8080", mux)
55+
56+ return err
57+}
A
testkey2
+7,
-0
1@@ -0,0 +1,7 @@
2+-----BEGIN OPENSSH PRIVATE KEY-----
3+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
4+QyNTUxOQAAACAVBfVj2Gf8IBbU9G8nYz9Y6UQRcjdocl3CD0GKhIAt5wAAAJA3GdxYNxnc
5+WAAAAAtzc2gtZWQyNTUxOQAAACAVBfVj2Gf8IBbU9G8nYz9Y6UQRcjdocl3CD0GKhIAt5w
6+AAAECcClGiCCayTB0yRGxnn3R26heCf966qN+YAISC4dCMERUF9WPYZ/wgFtT0bydjP1jp
7+RBFyN2hyXcIPQYqEgC3nAAAADGphbWllQGF0aGVuYQE=
8+-----END OPENSSH PRIVATE KEY-----
+1,
-0
1@@ -0,0 +1 @@
2+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBUF9WPYZ/wgFtT0bydjP1jpRBFyN2hyXcIPQYqEgC3n jamie@athena