friend/signature.go

31 lines
814 B
Go

package main
import (
"crypto"
"crypto/rand"
"fmt"
"net/http"
"strings"
"time"
)
type Signer struct {
key crypto.Signer
keyID string
}
// Sign modifies the request, computing and setting the Signature header, and setting the Date header to the provided time.
func (s Signer) Sign(r *http.Request, date time.Time) error {
host := r.URL.Host
path := r.URL.Path
method := strings.ToLower(r.Method)
stringToSign := fmt.Sprintf("(request-target): %s %s\nhost: %s\ndate: %s", method, path, host, date.Format(time.RFC1123))
sig, err := s.key.Sign(rand.Reader, []byte(stringToSign), nil)
if err != nil {
return err
}
r.Header.Set("Date", date.Format(time.RFC1123))
r.Header.Set("Signature", fmt.Sprintf(`keyId="%s",headers="(request-target) host date",signature="%s"`, s.keyID, sig))
return nil
}