75 lines
1.6 KiB
Go
75 lines
1.6 KiB
Go
package client
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto"
|
|
"crypto/ecdsa"
|
|
"crypto/ed25519"
|
|
"crypto/rsa"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"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"
|
|
"github.com/opencontainers/go-digest"
|
|
)
|
|
|
|
func Post(baseUrl *url.URL, key crypto.PrivateKey, keyId string, data []byte, simulateCaddy bool) (*http.Response, error) {
|
|
client, err := getSigningClient(key, keyId)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
id := digest.FromBytes(data)
|
|
|
|
authUrl := baseUrl.JoinPath("auth")
|
|
|
|
var req *http.Request
|
|
|
|
req, err = http.NewRequest("POST", authUrl.String(), bytes.NewBuffer(data))
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req.Header.Add("Content-Digest", string(id.Algorithm())+"="+id.Encoded())
|
|
req.Header.Add("Content-Type", "application/json")
|
|
|
|
if simulateCaddy {
|
|
req.Header.Add("X-Forwarded-Method", req.Method)
|
|
req.Header.Add("X-Forwarded-Uri", req.RequestURI)
|
|
}
|
|
|
|
resp, err := client.Do(req)
|
|
|
|
return resp, err
|
|
}
|
|
|
|
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{
|
|
Tag: "auth",
|
|
KeyID: keyId,
|
|
Alg: alg,
|
|
})
|
|
|
|
return client, nil
|
|
}
|