Re-organized SimpleHTTPTests and expanded them a bit

This commit is contained in:
xenolf 2015-10-30 13:13:05 +01:00
parent fc08101f79
commit 34fe2a5547
3 changed files with 163 additions and 54 deletions

View file

@ -1,11 +1 @@
package acme package acme
type dvsniChallenge struct{}
func (s *dvsniChallenge) CanSolve(domain string) bool {
return false
}
func (s *dvsniChallenge) Solve(challenge challenge, domain string) error {
return nil
}

View file

@ -1,7 +1,6 @@
package acme package acme
import ( import (
"crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
@ -112,7 +111,7 @@ func (s *simpleHTTPChallenge) startHTTPSServer(domain string, token string) (net
tlsListener, err := tls.Listen("tcp", port, tlsConf) tlsListener, err := tls.Listen("tcp", port, tlsConf)
if err != nil { if err != nil {
return nil, fmt.Errorf("Could not start HTTP listener! -> %v", err) return nil, err
} }
jsonBytes, err := json.Marshal(challenge{Type: "simpleHttp", Token: token, TLS: true}) jsonBytes, err := json.Marshal(challenge{Type: "simpleHttp", Token: token, TLS: true})
@ -121,7 +120,7 @@ func (s *simpleHTTPChallenge) startHTTPSServer(domain string, token string) (net
} }
signed, err := s.jws.signContent(jsonBytes) signed, err := s.jws.signContent(jsonBytes)
if err != nil { if err != nil {
return nil, errors.New("startHTTPSServer: Failed to sign message") return nil, fmt.Errorf("startHTTPSServer: Failed to sign message. %s", err)
} }
signedCompact := signed.FullSerialize() signedCompact := signed.FullSerialize()
if err != nil { if err != nil {
@ -145,13 +144,3 @@ func (s *simpleHTTPChallenge) startHTTPSServer(domain string, token string) (net
return tlsListener, nil return tlsListener, nil
} }
func getRandomString(length int) string {
const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var bytes = make([]byte, length)
rand.Read(bytes)
for i, b := range bytes {
bytes[i] = alphanum[b%byte(len(alphanum))]
}
return string(bytes)
}

View file

@ -12,54 +12,183 @@ import (
"github.com/square/go-jose" "github.com/square/go-jose"
) )
func TestSimpleHTTP(t *testing.T) { func TestSimpleHTTPNonRootBind(t *testing.T) {
privKey, err := generatePrivateKey(rsakey, 512) privKey, _ := generatePrivateKey(rsakey, 128)
if err != nil { jws := &jws{privKey: privKey.(*rsa.PrivateKey)}
t.Errorf("Could not generate public key -> %v", err)
solver := &simpleHTTPChallenge{jws: jws}
clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: "localhost:4000", Token: "1"}
// validate error on non-root bind to 443
if err := solver.Solve(clientChallenge, "test.domain"); err == nil {
t.Error("BIND: Expected Solve to return an error but the error was nil.")
} else {
expectedError := "Could not start HTTPS server for challenge -> listen tcp :443: bind: permission denied"
if err.Error() != expectedError {
t.Errorf("Expected error %s but instead got %s", expectedError, err.Error())
}
} }
}
func TestSimpleHTTPShortRSA(t *testing.T) {
privKey, _ := generatePrivateKey(rsakey, 128)
jws := &jws{privKey: privKey.(*rsa.PrivateKey), nonces: []string{"test1", "test2"}}
solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"}
clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: "http://localhost:4000", Token: "2"}
if err := solver.Solve(clientChallenge, "test.domain"); err == nil {
t.Error("UNEXPECTED: Expected Solve to return an error but the error was nil.")
} else {
expectedError := "Could not start HTTPS server for challenge -> startHTTPSServer: Failed to sign message. crypto/rsa: message too long for RSA public key size"
if err.Error() != expectedError {
t.Errorf("Expected error %s but instead got %s", expectedError, err.Error())
}
}
}
func TestSimpleHTTPConnectionRefusal(t *testing.T) {
privKey, _ := generatePrivateKey(rsakey, 512)
jws := &jws{privKey: privKey.(*rsa.PrivateKey), nonces: []string{"test1", "test2"}}
solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"}
clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: "http://localhost:4000", Token: "3"}
if err := solver.Solve(clientChallenge, "test.domain"); err == nil {
t.Error("UNEXPECTED: Expected Solve to return an error but the error was nil.")
} else {
expectedError := "Failed to post JWS message. -> Post http://localhost:4000: dial tcp 127.0.0.1:4000: getsockopt: connection refused"
if err.Error() != expectedError {
t.Errorf("Expected error %s but instead got %s", expectedError, err.Error())
}
}
}
func TestSimpleHTTPUnexpectedServerState(t *testing.T) {
privKey, _ := generatePrivateKey(rsakey, 512)
jws := &jws{privKey: privKey.(*rsa.PrivateKey)} jws := &jws{privKey: privKey.(*rsa.PrivateKey)}
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Replay-Nonce", "12345") w.Header().Add("Replay-Nonce", "12345")
w.Write([]byte("{\"type\":\"simpleHttp\",\"status\":\"what\",\"uri\":\"http://some.url\",\"token\":\"4\"}"))
})) }))
solver := &simpleHTTPChallenge{jws: jws} solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"}
clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "123456789"} clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "4"}
// validate error on non-root bind to 443 if err := solver.Solve(clientChallenge, "test.domain"); err == nil {
if err = solver.Solve(clientChallenge, "test.domain"); err == nil { t.Error("UNEXPECTED: Expected Solve to return an error but the error was nil.")
t.Error("BIND: Expected Solve to return an error but the error was nil.") } else {
expectedError := "The server returned an unexpected state."
if err.Error() != expectedError {
t.Errorf("Expected error %s but instead got %s", expectedError, err.Error())
}
} }
}
// Validate error on unexpected state func TestSimpleHTTPChallengeServerUnexpectedDomain(t *testing.T) {
solver.optPort = "23456" privKey, _ := generatePrivateKey(rsakey, 512)
if err = solver.Solve(clientChallenge, "test.domain"); err == nil { jws := &jws{privKey: privKey.(*rsa.PrivateKey)}
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
req, _ := client.Get("https://localhost:23456/.well-known/acme-challenge/" + "5")
reqBytes, _ := ioutil.ReadAll(req.Body)
if string(reqBytes) != "TEST" {
t.Error("Expected simpleHTTP server to return string TEST on unexpected domain.")
}
}
w.Header().Add("Replay-Nonce", "12345")
w.Write([]byte("{\"type\":\"simpleHttp\",\"status\":\"invalid\",\"uri\":\"http://some.url\",\"token\":\"5\"}"))
}))
solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"}
clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "5"}
if err := solver.Solve(clientChallenge, "test.domain"); err == nil {
t.Error("UNEXPECTED: Expected Solve to return an error but the error was nil.") t.Error("UNEXPECTED: Expected Solve to return an error but the error was nil.")
} }
}
// Validate error on invalid status func TestSimpleHTTPServerError(t *testing.T) {
ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { privKey, _ := generatePrivateKey(rsakey, 512)
w.Header().Add("Replay-Nonce", "12345") jws := &jws{privKey: privKey.(*rsa.PrivateKey)}
failed := challenge{Type: "simpleHttp", Status: "invalid", URI: ts.URL, Token: "1234567810"}
jsonBytes, _ := json.Marshal(&failed) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write(jsonBytes) if r.Method == "HEAD" {
}) w.Header().Add("Replay-Nonce", "12345")
clientChallenge.Token = "1234567810" } else {
if err = solver.Solve(clientChallenge, "test.domain"); err == nil { w.WriteHeader(http.StatusInternalServerError)
t.Error("FAILED: Expected Solve to return an error but the error was nil.") w.Header().Add("Replay-Nonce", "12345")
w.Write([]byte("{\"type\":\"urn:acme:error:unauthorized\",\"detail\":\"Error creating new authz :: Syntax error\"}"))
}
}))
solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"}
clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "6"}
if err := solver.Solve(clientChallenge, "test.domain"); err == nil {
t.Error("UNEXPECTED: Expected Solve to return an error but the error was nil.")
} else {
expectedError := "[500] Type: urn:acme:error:unauthorized Detail: Error creating new authz :: Syntax error"
if err.Error() != expectedError {
t.Errorf("Expected error |%s| but instead got |%s|", expectedError, err.Error())
}
} }
}
// Validate no error on valid response func TestSimpleHTTPInvalidServerState(t *testing.T) {
ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { privKey, _ := generatePrivateKey(rsakey, 512)
jws := &jws{privKey: privKey.(*rsa.PrivateKey)}
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Replay-Nonce", "12345") w.Header().Add("Replay-Nonce", "12345")
valid := challenge{Type: "simpleHttp", Status: "valid", URI: ts.URL, Token: "1234567811"} w.Write([]byte("{\"type\":\"simpleHttp\",\"status\":\"invalid\",\"uri\":\"http://some.url\",\"token\":\"7\"}"))
jsonBytes, _ := json.Marshal(&valid) }))
w.Write(jsonBytes)
}) solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"}
clientChallenge.Token = "1234567811" clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "7"}
if err = solver.Solve(clientChallenge, "test.domain"); err != nil {
if err := solver.Solve(clientChallenge, "test.domain"); err == nil {
t.Error("UNEXPECTED: Expected Solve to return an error but the error was nil.")
} else {
expectedError := "The server could not validate our request."
if err.Error() != expectedError {
t.Errorf("Expected error |%s| but instead got |%s|", expectedError, err.Error())
}
}
}
func TestSimpleHTTPValidServerResponse(t *testing.T) {
privKey, _ := generatePrivateKey(rsakey, 512)
jws := &jws{privKey: privKey.(*rsa.PrivateKey)}
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Replay-Nonce", "12345")
w.Write([]byte("{\"type\":\"simpleHttp\",\"status\":\"valid\",\"uri\":\"http://some.url\",\"token\":\"8\"}"))
}))
solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"}
clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "8"}
if err := solver.Solve(clientChallenge, "test.domain"); err != nil {
t.Errorf("VALID: Expected Solve to return no error but the error was -> %v", err) t.Errorf("VALID: Expected Solve to return no error but the error was -> %v", err)
} }
}
func TestSimpleHTTPValidFull(t *testing.T) {
privKey, _ := generatePrivateKey(rsakey, 512)
jws := &jws{privKey: privKey.(*rsa.PrivateKey)}
ts := httptest.NewServer(nil)
solver := &simpleHTTPChallenge{jws: jws, optPort: "23456"}
clientChallenge := challenge{Type: "simpleHttp", Status: "pending", URI: ts.URL, Token: "9"}
// Validate server on port 23456 which responds appropriately // Validate server on port 23456 which responds appropriately
clientChallenge.Token = "1234567812" clientChallenge.Token = "1234567812"
@ -112,7 +241,8 @@ func TestSimpleHTTP(t *testing.T) {
jsonBytes, _ := json.Marshal(&valid) jsonBytes, _ := json.Marshal(&valid)
w.Write(jsonBytes) w.Write(jsonBytes)
}) })
if err = solver.Solve(clientChallenge, "test.domain"); err != nil {
if err := solver.Solve(clientChallenge, "test.domain"); err != nil {
t.Errorf("VALID: Expected Solve to return no error but the error was -> %v", err) t.Errorf("VALID: Expected Solve to return no error but the error was -> %v", err)
} }
} }