cheddar
·
2025-02-22
client.go
1package client
2
3import (
4 "bytes"
5 "context"
6 "crypto"
7 "crypto/ecdsa"
8 "crypto/ed25519"
9 "crypto/rsa"
10 "fmt"
11 "net/http"
12 "net/url"
13 "reflect"
14
15 "github.com/common-fate/httpsig"
16 "github.com/common-fate/httpsig/alg_ecdsa"
17 "github.com/common-fate/httpsig/alg_ed25519"
18 "github.com/common-fate/httpsig/alg_rsa"
19 "github.com/common-fate/httpsig/signer"
20)
21
22func Post(baseUrl *url.URL, key crypto.PrivateKey, keyId string, data []byte) (*http.Response, error) {
23 client, err := getSigningClient(key, keyId)
24
25 if err != nil {
26 return nil, err
27 }
28
29 var req *http.Request
30
31 req, err = http.NewRequest("POST", baseUrl.String(), bytes.NewBuffer(data))
32
33 if err != nil {
34 return nil, err
35 }
36
37 req.Header.Add("Content-Type", "application/json")
38
39 resp, err := client.Do(req)
40
41 return resp, err
42}
43
44func getSigningClient(key crypto.PrivateKey, keyId string) (*http.Client, error) {
45 var alg signer.Algorithm
46
47 switch p := key.(type) {
48 case *rsa.PrivateKey:
49 alg = alg_rsa.NewRSAPKCS256Signer(p)
50 case *ed25519.PrivateKey:
51 alg = alg_ed25519.Ed25519{PrivateKey: *p}
52 case *ecdsa.PrivateKey:
53 alg = alg_ecdsa.NewP256Signer(p)
54 default:
55 return nil, fmt.Errorf("type is unknown: %s", reflect.TypeOf(key))
56 }
57
58 coveredComponents := []string{"@method", "@target-uri", "content-type", "content-length"}
59
60 client := httpsig.NewClient(httpsig.ClientOpts{
61 Tag: "auth",
62 KeyID: keyId,
63 Alg: alg,
64 CoveredComponents: coveredComponents,
65
66 OnDeriveSigningString: func(ctx context.Context, stringToSign string) {
67 fmt.Printf("string to sign:\n%s\n", stringToSign)
68 },
69 })
70
71 return client, nil
72}