62 lines
1.5 KiB
Go
62 lines
1.5 KiB
Go
package pin
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"regexp"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func newPinnedServer(t *testing.T) (*httptest.Server, string) {
|
|
t.Helper()
|
|
key, err := GenerateKey()
|
|
require.NoError(t, err)
|
|
cert, err := Certificate(key)
|
|
require.NoError(t, err)
|
|
fp, err := Fingerprint(key.Public())
|
|
require.NoError(t, err)
|
|
|
|
srv := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
_, _ = w.Write([]byte("ok"))
|
|
}))
|
|
srv.TLS = &tls.Config{Certificates: []tls.Certificate{cert}}
|
|
srv.StartTLS()
|
|
t.Cleanup(srv.Close)
|
|
return srv, fp
|
|
}
|
|
|
|
func clientFor(fp string) *http.Client {
|
|
return &http.Client{Transport: &http.Transport{TLSClientConfig: ClientConfig(fp)}}
|
|
}
|
|
|
|
func TestFingerprintFormat(t *testing.T) {
|
|
key, err := GenerateKey()
|
|
require.NoError(t, err)
|
|
fp, err := Fingerprint(key.Public())
|
|
require.NoError(t, err)
|
|
assert.Regexp(t, regexp.MustCompile(`^sha256:[0-9a-f]{64}$`), fp)
|
|
}
|
|
|
|
func TestClientConfigAcceptsPinnedKey(t *testing.T) {
|
|
srv, fp := newPinnedServer(t)
|
|
resp, err := clientFor(fp).Get(srv.URL)
|
|
require.NoError(t, err)
|
|
_ = resp.Body.Close()
|
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
|
}
|
|
|
|
func TestClientConfigRejectsOtherKey(t *testing.T) {
|
|
srv, _ := newPinnedServer(t)
|
|
other, err := GenerateKey()
|
|
require.NoError(t, err)
|
|
otherFP, err := Fingerprint(other.Public())
|
|
require.NoError(t, err)
|
|
|
|
_, err = clientFor(otherFP).Get(srv.URL)
|
|
assert.ErrorContains(t, err, "fingerprint mismatch")
|
|
}
|