mirror of
https://github.com/go-acme/lego
synced 2026-03-14 14:35:48 +01:00
fix: enforce HTTPS to the ACME server (#2608)
This commit is contained in:
parent
b4ddc1e5e2
commit
238454b5f7
16 changed files with 161 additions and 107 deletions
|
|
@ -3,7 +3,6 @@ package api
|
|||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/go-acme/lego/v4/platform/tester"
|
||||
|
|
@ -74,14 +73,14 @@ rzFL1KZfz+HZdnFwFW2T2gVW8L3ii1l9AJDuKzlvjUH3p6bgihVq02sjT8mx+GM2
|
|||
`
|
||||
|
||||
func TestCertificateService_Get_issuerRelUp(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().
|
||||
apiURL, client := tester.MockACMEServer().
|
||||
Route("POST /certificate", servermock.RawStringResponse(certResponseMock)).
|
||||
Build(t)
|
||||
BuildHTTPS(t)
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := New(http.DefaultClient, "lego-test", apiURL+"/dir", "", key)
|
||||
core, err := New(client, "lego-test", apiURL+"/dir", "", key)
|
||||
require.NoError(t, err)
|
||||
|
||||
cert, issuer, err := core.Certificates.Get(apiURL+"/certificate", true)
|
||||
|
|
@ -91,14 +90,14 @@ func TestCertificateService_Get_issuerRelUp(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCertificateService_Get_embeddedIssuer(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().
|
||||
apiURL, client := tester.MockACMEServer().
|
||||
Route("POST /certificate", servermock.RawStringResponse(certResponseMock)).
|
||||
Build(t)
|
||||
BuildHTTPS(t)
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := New(http.DefaultClient, "lego-test", apiURL+"/dir", "", key)
|
||||
core, err := New(client, "lego-test", apiURL+"/dir", "", key)
|
||||
require.NoError(t, err)
|
||||
|
||||
cert, issuer, err := core.Certificates.Get(apiURL+"/certificate", true)
|
||||
|
|
|
|||
|
|
@ -8,35 +8,37 @@ import (
|
|||
|
||||
"github.com/go-acme/lego/v4/acme"
|
||||
"github.com/go-acme/lego/v4/acme/api/internal/sender"
|
||||
"github.com/go-acme/lego/v4/platform/tester"
|
||||
"github.com/go-acme/lego/v4/platform/tester/servermock"
|
||||
)
|
||||
|
||||
func TestNotHoldingLockWhileMakingHTTPRequests(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
w.Header().Set("Replay-Nonce", "12345")
|
||||
w.Header().Set("Retry-After", "0")
|
||||
err := tester.WriteJSONResponse(w, &acme.Challenge{Type: "http-01", Status: "Valid", URL: "http://example.com/", Token: "token"})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}))
|
||||
t.Cleanup(server.Close)
|
||||
manager, _ := servermock.NewBuilder(
|
||||
func(server *httptest.Server) (*Manager, error) {
|
||||
doer := sender.NewDoer(server.Client(), "lego-test")
|
||||
|
||||
return NewManager(doer, server.URL), nil
|
||||
}).
|
||||
Route("HEAD /", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
|
||||
rw.Header().Set("Replay-Nonce", "12345")
|
||||
rw.Header().Set("Retry-After", "0")
|
||||
|
||||
servermock.JSONEncode(&acme.Challenge{Type: "http-01", Status: "Valid", URL: "https://example.com/", Token: "token"}).ServeHTTP(rw, req)
|
||||
})).
|
||||
BuildHTTPS(t)
|
||||
|
||||
doer := sender.NewDoer(http.DefaultClient, "lego-test")
|
||||
j := NewManager(doer, server.URL)
|
||||
ch := make(chan bool)
|
||||
resultCh := make(chan bool)
|
||||
go func() {
|
||||
_, errN := j.Nonce()
|
||||
_, errN := manager.Nonce()
|
||||
if errN != nil {
|
||||
t.Log(errN)
|
||||
}
|
||||
ch <- true
|
||||
}()
|
||||
go func() {
|
||||
_, errN := j.Nonce()
|
||||
_, errN := manager.Nonce()
|
||||
if errN != nil {
|
||||
t.Log(errN)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,35 +9,37 @@ import (
|
|||
"github.com/go-acme/lego/v4/acme"
|
||||
"github.com/go-acme/lego/v4/acme/api/internal/nonces"
|
||||
"github.com/go-acme/lego/v4/acme/api/internal/sender"
|
||||
"github.com/go-acme/lego/v4/platform/tester"
|
||||
"github.com/go-acme/lego/v4/platform/tester/servermock"
|
||||
)
|
||||
|
||||
func TestNotHoldingLockWhileMakingHTTPRequests(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
w.Header().Set("Replay-Nonce", "12345")
|
||||
w.Header().Set("Retry-After", "0")
|
||||
err := tester.WriteJSONResponse(w, &acme.Challenge{Type: "http-01", Status: "Valid", URL: "http://example.com/", Token: "token"})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}))
|
||||
t.Cleanup(server.Close)
|
||||
manager, _ := servermock.NewBuilder(
|
||||
func(server *httptest.Server) (*nonces.Manager, error) {
|
||||
doer := sender.NewDoer(server.Client(), "lego-test")
|
||||
|
||||
return nonces.NewManager(doer, server.URL), nil
|
||||
}).
|
||||
Route("HEAD /", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
|
||||
rw.Header().Set("Replay-Nonce", "12345")
|
||||
rw.Header().Set("Retry-After", "0")
|
||||
|
||||
servermock.JSONEncode(&acme.Challenge{Type: "http-01", Status: "Valid", URL: "https://example.com/", Token: "token"}).ServeHTTP(rw, req)
|
||||
})).
|
||||
BuildHTTPS(t)
|
||||
|
||||
doer := sender.NewDoer(http.DefaultClient, "lego-test")
|
||||
j := nonces.NewManager(doer, server.URL)
|
||||
ch := make(chan bool)
|
||||
resultCh := make(chan bool)
|
||||
go func() {
|
||||
_, errN := j.Nonce()
|
||||
_, errN := manager.Nonce()
|
||||
if errN != nil {
|
||||
t.Log(errN)
|
||||
}
|
||||
ch <- true
|
||||
}()
|
||||
go func() {
|
||||
_, errN := j.Nonce()
|
||||
_, errN := manager.Nonce()
|
||||
if errN != nil {
|
||||
t.Log(errN)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ type Doer struct {
|
|||
|
||||
// NewDoer Creates a new Doer.
|
||||
func NewDoer(client *http.Client, userAgent string) *Doer {
|
||||
client.Transport = newHTTPSOnly(client)
|
||||
|
||||
return &Doer{
|
||||
httpClient: client,
|
||||
userAgent: userAgent,
|
||||
|
|
@ -150,3 +152,28 @@ func checkError(req *http.Request, resp *http.Response) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type httpsOnly struct {
|
||||
rt http.RoundTripper
|
||||
}
|
||||
|
||||
func newHTTPSOnly(client *http.Client) *httpsOnly {
|
||||
if client.Transport == nil {
|
||||
return &httpsOnly{rt: http.DefaultTransport}
|
||||
}
|
||||
|
||||
return &httpsOnly{rt: client.Transport}
|
||||
}
|
||||
|
||||
// RoundTrip ensure HTTPS is used.
|
||||
// Each ACME function is accomplished by the client sending a sequence of HTTPS requests to the server [RFC2818],
|
||||
// carrying JSON messages [RFC8259].
|
||||
// Use of HTTPS is REQUIRED.
|
||||
// https://datatracker.ietf.org/doc/html/rfc8555#section-6.1
|
||||
func (r *httpsOnly) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
if req.URL.Scheme != "https" {
|
||||
return nil, fmt.Errorf("HTTPS is required: %s", req.URL)
|
||||
}
|
||||
|
||||
return r.rt.RoundTrip(req)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ import (
|
|||
|
||||
func TestDo_UserAgentOnAllHTTPMethod(t *testing.T) {
|
||||
var ua, method string
|
||||
server := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) {
|
||||
server := httptest.NewTLSServer(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) {
|
||||
ua = r.Header.Get("User-Agent")
|
||||
method = r.Method
|
||||
}))
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
doer := NewDoer(http.DefaultClient, "")
|
||||
doer := NewDoer(server.Client(), "")
|
||||
|
||||
testCases := []struct {
|
||||
method string
|
||||
|
|
@ -65,3 +65,13 @@ func TestDo_CustomUserAgent(t *testing.T) {
|
|||
}
|
||||
assert.Len(t, strings.Split(ua, " "), 5)
|
||||
}
|
||||
|
||||
func TestDo_failWithHTTP(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {}))
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
sender := NewDoer(server.Client(), "test")
|
||||
|
||||
_, err := sender.Post(server.URL, strings.NewReader("data"), "text/plain", nil)
|
||||
require.ErrorContains(t, err, "HTTPS is required: http://")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ func TestOrderService_NewWithOptions(t *testing.T) {
|
|||
privateKey, errK := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, errK, "Could not generate test key")
|
||||
|
||||
apiURL := tester.MockACMEServer().
|
||||
apiURL, client := tester.MockACMEServer().
|
||||
Route("POST /newOrder",
|
||||
http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
body, err := readSignedBody(req, privateKey)
|
||||
|
|
@ -52,9 +52,9 @@ func TestOrderService_NewWithOptions(t *testing.T) {
|
|||
Replaces: order.Replaces,
|
||||
}).ServeHTTP(rw, req)
|
||||
})).
|
||||
Build(t)
|
||||
BuildHTTPS(t)
|
||||
|
||||
core, err := New(http.DefaultClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
core, err := New(client, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
testCases := []struct {
|
||||
|
|
|
|||
|
|
@ -175,14 +175,14 @@ Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
|
|||
`
|
||||
|
||||
func Test_checkResponse(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().
|
||||
apiURL, client := tester.MockACMEServer().
|
||||
Route("POST /certificate", servermock.RawStringResponse(certResponseMock)).
|
||||
Build(t)
|
||||
BuildHTTPS(t)
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", key)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", key)
|
||||
require.NoError(t, err)
|
||||
|
||||
certifier := NewCertifier(core, &resolverMock{}, CertifierOptions{KeyType: certcrypto.RSA2048})
|
||||
|
|
@ -209,14 +209,14 @@ func Test_checkResponse(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_checkResponse_issuerRelUp(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().
|
||||
apiURL, client := tester.MockACMEServer().
|
||||
Route("POST /certificate", servermock.RawStringResponse(certResponseMock)).
|
||||
Build(t)
|
||||
BuildHTTPS(t)
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", key)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", key)
|
||||
require.NoError(t, err)
|
||||
|
||||
certifier := NewCertifier(core, &resolverMock{}, CertifierOptions{KeyType: certcrypto.RSA2048})
|
||||
|
|
@ -243,14 +243,14 @@ func Test_checkResponse_issuerRelUp(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_checkResponse_no_bundle(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().
|
||||
apiURL, client := tester.MockACMEServer().
|
||||
Route("POST /certificate", servermock.RawStringResponse(certResponseMock)).
|
||||
Build(t)
|
||||
BuildHTTPS(t)
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", key)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", key)
|
||||
require.NoError(t, err)
|
||||
|
||||
certifier := NewCertifier(core, &resolverMock{}, CertifierOptions{KeyType: certcrypto.RSA2048})
|
||||
|
|
@ -277,21 +277,21 @@ func Test_checkResponse_no_bundle(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_checkResponse_alternate(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().
|
||||
apiURL, client := tester.MockACMEServer().
|
||||
Route("POST /certificate",
|
||||
http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Add("Link",
|
||||
fmt.Sprintf(`<http://%s/certificate/1>;title="foo";rel="alternate"`, req.Context().Value(http.LocalAddrContextKey)))
|
||||
fmt.Sprintf(`<https://%s/certificate/1>;title="foo";rel="alternate"`, req.Context().Value(http.LocalAddrContextKey)))
|
||||
|
||||
servermock.RawStringResponse(certResponseMock).ServeHTTP(rw, req)
|
||||
})).
|
||||
Route("/certificate/1", servermock.RawStringResponse(certResponseMock2)).
|
||||
Build(t)
|
||||
BuildHTTPS(t)
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", key)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", key)
|
||||
require.NoError(t, err)
|
||||
|
||||
certifier := NewCertifier(core, &resolverMock{}, CertifierOptions{KeyType: certcrypto.RSA2048})
|
||||
|
|
@ -321,14 +321,14 @@ func Test_checkResponse_alternate(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_Get(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().
|
||||
apiURL, client := tester.MockACMEServer().
|
||||
Route("POST /acme/cert/test-cert", servermock.RawStringResponse(certResponseMock)).
|
||||
Build(t)
|
||||
BuildHTTPS(t)
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", key)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", key)
|
||||
require.NoError(t, err)
|
||||
|
||||
certifier := NewCertifier(core, &resolverMock{}, CertifierOptions{KeyType: certcrypto.RSA2048})
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ func TestCertifier_GetRenewalInfo(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// Test with a fake API.
|
||||
apiURL := tester.MockACMEServer().
|
||||
apiURL, client := tester.MockACMEServer().
|
||||
Route("GET /renewalInfo/"+ariLeafCertID,
|
||||
servermock.RawStringResponse(`{
|
||||
"suggestedWindow": {
|
||||
|
|
@ -55,12 +55,12 @@ func TestCertifier_GetRenewalInfo(t *testing.T) {
|
|||
}`).
|
||||
WithHeader("Content-Type", "application/json").
|
||||
WithHeader("Retry-After", "21600")).
|
||||
Build(t)
|
||||
BuildHTTPS(t)
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", key)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", key)
|
||||
require.NoError(t, err)
|
||||
|
||||
certifier := NewCertifier(core, &resolverMock{}, CertifierOptions{KeyType: certcrypto.RSA2048})
|
||||
|
|
@ -82,24 +82,23 @@ func TestCertifier_GetRenewalInfo_errors(t *testing.T) {
|
|||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
httpClient *http.Client
|
||||
request RenewalInfoRequest
|
||||
handler http.HandlerFunc
|
||||
desc string
|
||||
timeout time.Duration
|
||||
request RenewalInfoRequest
|
||||
handler http.HandlerFunc
|
||||
}{
|
||||
{
|
||||
desc: "API timeout",
|
||||
httpClient: &http.Client{Timeout: 500 * time.Millisecond}, // HTTP client that times out after 500ms.
|
||||
request: RenewalInfoRequest{leaf},
|
||||
desc: "API timeout",
|
||||
timeout: 500 * time.Millisecond, // HTTP client that times out after 500ms.
|
||||
request: RenewalInfoRequest{leaf},
|
||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||
// API that takes 2ms to respond.
|
||||
time.Sleep(2 * time.Millisecond)
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "API error",
|
||||
httpClient: http.DefaultClient,
|
||||
request: RenewalInfoRequest{leaf},
|
||||
desc: "API error",
|
||||
request: RenewalInfoRequest{leaf},
|
||||
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||
// API that responds with error instead of renewal info.
|
||||
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
|
|
@ -111,11 +110,15 @@ func TestCertifier_GetRenewalInfo_errors(t *testing.T) {
|
|||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
apiURL := tester.MockACMEServer().
|
||||
apiURL, client := tester.MockACMEServer().
|
||||
Route("GET /renewalInfo/"+ariLeafCertID, test.handler).
|
||||
Build(t)
|
||||
BuildHTTPS(t)
|
||||
|
||||
core, err := api.New(test.httpClient, "lego-test", apiURL+"/dir", "", key)
|
||||
if test.timeout != 0 {
|
||||
client.Timeout = test.timeout
|
||||
}
|
||||
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", key)
|
||||
require.NoError(t, err)
|
||||
|
||||
certifier := NewCertifier(core, &resolverMock{}, CertifierOptions{KeyType: certcrypto.RSA2048})
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import (
|
|||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -32,12 +31,12 @@ func (p *providerTimeoutMock) CleanUp(domain, token, keyAuth string) error { ret
|
|||
func (p *providerTimeoutMock) Timeout() (time.Duration, time.Duration) { return p.timeout, p.interval }
|
||||
|
||||
func TestChallenge_PreSolve(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().Build(t)
|
||||
apiURL, client := tester.MockACMEServer().BuildHTTPS(t)
|
||||
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, err)
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
testCases := []struct {
|
||||
|
|
@ -114,12 +113,12 @@ func TestChallenge_PreSolve(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestChallenge_Solve(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().Build(t)
|
||||
apiURL, client := tester.MockACMEServer().BuildHTTPS(t)
|
||||
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, err)
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
testCases := []struct {
|
||||
|
|
@ -201,12 +200,12 @@ func TestChallenge_Solve(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestChallenge_CleanUp(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().Build(t)
|
||||
apiURL, client := tester.MockACMEServer().BuildHTTPS(t)
|
||||
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, err)
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
testCases := []struct {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ func TestProviderServer_GetAddress(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestChallenge(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().Build(t)
|
||||
apiURL, client := tester.MockACMEServer().BuildHTTPS(t)
|
||||
|
||||
providerServer := NewProviderServer("", "23457")
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ func TestChallenge(t *testing.T) {
|
|||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
solver := NewChallenge(core, validate, providerServer)
|
||||
|
|
@ -123,7 +123,7 @@ func TestChallengeUnix(t *testing.T) {
|
|||
t.Skip("only for UNIX systems")
|
||||
}
|
||||
|
||||
apiURL := tester.MockACMEServer().Build(t)
|
||||
apiURL, httpsClient := tester.MockACMEServer().BuildHTTPS(t)
|
||||
|
||||
dir := t.TempDir()
|
||||
t.Cleanup(func() { _ = os.RemoveAll(dir) })
|
||||
|
|
@ -169,7 +169,7 @@ func TestChallengeUnix(t *testing.T) {
|
|||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
core, err := api.New(httpsClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
solver := NewChallenge(core, validate, providerServer)
|
||||
|
|
@ -188,12 +188,12 @@ func TestChallengeUnix(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestChallengeInvalidPort(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().Build(t)
|
||||
apiURL, client := tester.MockACMEServer().BuildHTTPS(t)
|
||||
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
validate := func(_ *api.Core, _ string, _ acme.Challenge) error { return nil }
|
||||
|
|
@ -371,7 +371,7 @@ func TestChallengeWithProxy(t *testing.T) {
|
|||
func testServeWithProxy(t *testing.T, header, extra *testProxyHeader, expectError bool) {
|
||||
t.Helper()
|
||||
|
||||
apiURL := tester.MockACMEServer().Build(t)
|
||||
apiURL, client := tester.MockACMEServer().BuildHTTPS(t)
|
||||
|
||||
providerServer := NewProviderServer("localhost", "23457")
|
||||
if header != nil {
|
||||
|
|
@ -414,7 +414,7 @@ func testServeWithProxy(t *testing.T, header, extra *testProxyHeader, expectErro
|
|||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
solver := NewChallenge(core, validate, providerServer)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func TestValidate(t *testing.T) {
|
|||
|
||||
privateKey, _ := rsa.GenerateKey(rand.Reader, 1024)
|
||||
|
||||
apiURL := tester.MockACMEServer().
|
||||
apiURL, client := tester.MockACMEServer().
|
||||
Route("POST /chlg",
|
||||
http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
if err := validateNoBody(privateKey, req); err != nil {
|
||||
|
|
@ -46,7 +46,7 @@ func TestValidate(t *testing.T) {
|
|||
}
|
||||
|
||||
rw.Header().Set("Link",
|
||||
fmt.Sprintf(`<http://%s/my-authz>; rel="up"`, req.Context().Value(http.LocalAddrContextKey)))
|
||||
fmt.Sprintf(`<https://%s/my-authz>; rel="up"`, req.Context().Value(http.LocalAddrContextKey)))
|
||||
|
||||
st := statuses[0]
|
||||
statuses = statuses[1:]
|
||||
|
|
@ -74,9 +74,9 @@ func TestValidate(t *testing.T) {
|
|||
|
||||
servermock.JSONEncode(authorization).ServeHTTP(rw, req)
|
||||
})).
|
||||
Build(t)
|
||||
BuildHTTPS(t)
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
testCases := []struct {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import (
|
|||
"crypto/tls"
|
||||
"encoding/asn1"
|
||||
"net"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/go-acme/lego/v4/acme"
|
||||
|
|
@ -21,7 +20,7 @@ import (
|
|||
)
|
||||
|
||||
func TestChallenge(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().Build(t)
|
||||
apiURL, client := tester.MockACMEServer().BuildHTTPS(t)
|
||||
|
||||
domain := "localhost"
|
||||
port := "24457"
|
||||
|
|
@ -69,7 +68,7 @@ func TestChallenge(t *testing.T) {
|
|||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
solver := NewChallenge(
|
||||
|
|
@ -93,12 +92,12 @@ func TestChallenge(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestChallengeInvalidPort(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().Build(t)
|
||||
apiURL, client := tester.MockACMEServer().BuildHTTPS(t)
|
||||
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
solver := NewChallenge(
|
||||
|
|
@ -123,7 +122,7 @@ func TestChallengeInvalidPort(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestChallengeIPaddress(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().Build(t)
|
||||
apiURL, client := tester.MockACMEServer().BuildHTTPS(t)
|
||||
|
||||
domain := "127.0.0.1"
|
||||
port := "24457"
|
||||
|
|
@ -170,7 +169,7 @@ func TestChallengeIPaddress(t *testing.T) {
|
|||
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", privateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
solver := NewChallenge(
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import (
|
|||
)
|
||||
|
||||
func TestNewClient(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().Build(t)
|
||||
apiURL, httpsClient := tester.MockACMEServer().BuildHTTPS(t)
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
|
@ -26,6 +26,7 @@ func TestNewClient(t *testing.T) {
|
|||
|
||||
config := NewConfig(user)
|
||||
config.CADirURL = apiURL + "/dir"
|
||||
config.HTTPClient = httpsClient
|
||||
|
||||
client, err := NewClient(config)
|
||||
require.NoError(t, err, "Could not create client")
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ func MockACMEServer() *servermock.Builder[string] {
|
|||
return server.URL, nil
|
||||
}).
|
||||
Route("GET /dir", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
serverURL := fmt.Sprintf("http://%s", req.Context().Value(http.LocalAddrContextKey))
|
||||
serverURL := fmt.Sprintf("https://%s", req.Context().Value(http.LocalAddrContextKey))
|
||||
|
||||
servermock.JSONEncode(acme.Directory{
|
||||
NewNonceURL: serverURL + "/nonce",
|
||||
|
|
|
|||
|
|
@ -70,3 +70,15 @@ func (b *Builder[T]) Build(t *testing.T) T {
|
|||
|
||||
return client
|
||||
}
|
||||
|
||||
func (b *Builder[T]) BuildHTTPS(t *testing.T) (T, *http.Client) {
|
||||
t.Helper()
|
||||
|
||||
server := httptest.NewTLSServer(b.mux)
|
||||
t.Cleanup(server.Close)
|
||||
|
||||
client, err := b.clientBuilder(server)
|
||||
require.NoError(t, err)
|
||||
|
||||
return client, server.Client()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import (
|
|||
)
|
||||
|
||||
func TestRegistrar_ResolveAccountByKey(t *testing.T) {
|
||||
apiURL := tester.MockACMEServer().
|
||||
apiURL, client := tester.MockACMEServer().
|
||||
Route("/account",
|
||||
http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("Location",
|
||||
|
|
@ -24,7 +24,7 @@ func TestRegistrar_ResolveAccountByKey(t *testing.T) {
|
|||
|
||||
servermock.JSONEncode(acme.Account{Status: "valid"}).ServeHTTP(rw, req)
|
||||
})).
|
||||
Build(t)
|
||||
BuildHTTPS(t)
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
require.NoError(t, err, "Could not generate test key")
|
||||
|
|
@ -35,7 +35,7 @@ func TestRegistrar_ResolveAccountByKey(t *testing.T) {
|
|||
privatekey: key,
|
||||
}
|
||||
|
||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", key)
|
||||
core, err := api.New(client, "lego-test", apiURL+"/dir", "", key)
|
||||
require.NoError(t, err)
|
||||
|
||||
registrar := NewRegistrar(core, user)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue