forked from TrueCloudLab/lego
Fix nonce error (#354)
* Adding a NonceError type to detect nonce errors * Implement a one off retry on a nonce error.
This commit is contained in:
parent
09d8a49bf2
commit
9f94aabbd2
2 changed files with 28 additions and 4 deletions
|
@ -8,7 +8,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const tosAgreementError = "Must agree to subscriber agreement before any further actions"
|
const (
|
||||||
|
tosAgreementError = "Must agree to subscriber agreement before any further actions"
|
||||||
|
invalidNonceError = "JWS has invalid anti-replay nonce"
|
||||||
|
)
|
||||||
|
|
||||||
// RemoteError is the base type for all errors specific to the ACME protocol.
|
// RemoteError is the base type for all errors specific to the ACME protocol.
|
||||||
type RemoteError struct {
|
type RemoteError struct {
|
||||||
|
@ -28,6 +31,12 @@ type TOSError struct {
|
||||||
RemoteError
|
RemoteError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NonceError represents the error which is returned if the
|
||||||
|
// nonce sent by the client was not accepted by the server.
|
||||||
|
type NonceError struct {
|
||||||
|
RemoteError
|
||||||
|
}
|
||||||
|
|
||||||
type domainError struct {
|
type domainError struct {
|
||||||
Domain string
|
Domain string
|
||||||
Error error
|
Error error
|
||||||
|
@ -73,6 +82,10 @@ func handleHTTPError(resp *http.Response) error {
|
||||||
return TOSError{errorDetail}
|
return TOSError{errorDetail}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if errorDetail.StatusCode == http.StatusBadRequest && strings.HasPrefix(errorDetail.Detail, invalidNonceError) {
|
||||||
|
return NonceError{errorDetail}
|
||||||
|
}
|
||||||
|
|
||||||
return errorDetail
|
return errorDetail
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
acme/jws.go
17
acme/jws.go
|
@ -41,15 +41,26 @@ func (j *jws) post(url string, content []byte) (*http.Response, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := httpPost(url, "application/jose+json", bytes.NewBuffer([]byte(signedContent.FullSerialize())))
|
resp, err := httpPost(url, "application/jose+json", bytes.NewBuffer([]byte(signedContent.FullSerialize())))
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Even in case of an error, the response should still contain a nonce.
|
||||||
nonce, nonceErr := getNonceFromResponse(resp)
|
nonce, nonceErr := getNonceFromResponse(resp)
|
||||||
if nonceErr == nil {
|
if nonceErr == nil {
|
||||||
j.nonces.Push(nonce)
|
j.nonces.Push(nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
switch err.(type) {
|
||||||
|
case NonceError:
|
||||||
|
// In case of a nonce error - retry once
|
||||||
|
resp, err = httpPost(url, "application/jose+json", bytes.NewBuffer([]byte(signedContent.FullSerialize())))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue