MCPcopy Create free account
hub / github.com/davecheney/pub / Sign

Function Sign

internal/httpsig/sign.go:25–79  ·  view source on GitHub ↗

Sign signs the request using the given keyID and privateKey.

(req *http.Request, keyID string, privateKey crypto.PrivateKey, body []byte)

Source from the content-addressed store, hash-verified

23
24// Sign signs the request using the given keyID and privateKey.
25func Sign(req *http.Request, keyID string, privateKey crypto.PrivateKey, body []byte) error {
26 req.Header.Set("Date", time.Now().UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT")) // Date must be in GMT, not UTC 🤯
27 headersToSign := []string{
28 RequestTarget,
29 }
30 switch req.Method {
31 case "GET":
32 headersToSign = append(headersToSign, "host", "date", "accept")
33 case "POST":
34 headersToSign = append(headersToSign, "date", "digest")
35 addDigest(req, body)
36 }
37
38 var sb bytes.Buffer
39 for _, header := range headersToSign {
40 switch header {
41 case httpsig.RequestTarget:
42 sb.WriteString("(request-target): ")
43 sb.WriteString(strings.ToLower(req.Method))
44 sb.WriteString(" ")
45 sb.WriteString(req.URL.Path)
46
47 if req.URL.RawQuery != "" {
48 sb.WriteString("?")
49 sb.WriteString(req.URL.RawQuery)
50 }
51 case "Host", "host":
52 sb.WriteString("host: ")
53 sb.WriteString(req.Host)
54 case "Date", "date":
55 sb.WriteString("date: ")
56 sb.WriteString(req.Header.Get("Date"))
57 case "Accept", "accept":
58 sb.WriteString("accept: ")
59 sb.WriteString(req.Header.Get("Accept"))
60 case "Digest", "digest":
61 sb.WriteString("digest: ")
62 sb.WriteString(req.Header.Get("Digest"))
63 default:
64 return fmt.Errorf("unknown header to sign: %s", header)
65 }
66 sb.WriteString("\n")
67 }
68 hash := sha256.New()
69 hash.Write(bytes.TrimRight(sb.Bytes(), "\n")) // remove trailing newline
70 digest := hash.Sum(nil)
71
72 sig, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), crypto.SHA256, digest)
73 if err != nil {
74 return err
75 }
76 enc := base64.StdEncoding.EncodeToString(sig)
77 req.Header.Set("Signature", fmt.Sprintf(`keyId="%s",algorithm="rsa-sha256",headers="%s",signature="%s"`, keyID, strings.Join(headersToSign, " "), enc))
78 return nil
79}
80
81func addDigest(req *http.Request, body []byte) {
82 hash := sha256.New()

Callers 3

FetchMethod · 0.92
PostMethod · 0.92
TestSignRequestFunction · 0.85

Calls 1

addDigestFunction · 0.85

Tested by 1

TestSignRequestFunction · 0.68