forked from TrueCloudLab/certificates
acme/retry: Cleanup tls-alpn-01 tests
This logic was already in the correct form so it was much easier to update.
This commit is contained in:
parent
d54f963b81
commit
05780554d2
2 changed files with 282 additions and 437 deletions
|
@ -463,12 +463,12 @@ func (tc *tlsALPN01Challenge) validate(jwk *jose.JSONWebKey, vo validateOptions)
|
||||||
|
|
||||||
if len(certs) == 0 {
|
if len(certs) == 0 {
|
||||||
e := errors.Errorf("%s challenge for %s resulted in no certificates", tc.Type, tc.Value)
|
e := errors.Errorf("%s challenge for %s resulted in no certificates", tc.Type, tc.Value)
|
||||||
up.Error = RejectedIdentifierErr(e).ToACME()
|
up.Error = TLSErr(e).ToACME()
|
||||||
return up, nil
|
return up, nil
|
||||||
}
|
}
|
||||||
if !cs.NegotiatedProtocolIsMutual || cs.NegotiatedProtocol != "acme-tls/1" {
|
if !cs.NegotiatedProtocolIsMutual || cs.NegotiatedProtocol != "acme-tls/1" {
|
||||||
e := errors.Errorf("cannot negotiate ALPN acme-tls/1 protocol for tls-alpn-01 challenge")
|
e := errors.Errorf("cannot negotiate ALPN acme-tls/1 protocol for tls-alpn-01 challenge")
|
||||||
up.Error = RejectedIdentifierErr(e).ToACME()
|
up.Error = TLSErr(e).ToACME()
|
||||||
return up, nil
|
return up, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,7 +476,7 @@ func (tc *tlsALPN01Challenge) validate(jwk *jose.JSONWebKey, vo validateOptions)
|
||||||
if len(leafCert.DNSNames) != 1 || !strings.EqualFold(leafCert.DNSNames[0], tc.Value) {
|
if len(leafCert.DNSNames) != 1 || !strings.EqualFold(leafCert.DNSNames[0], tc.Value) {
|
||||||
e := errors.Errorf("incorrect certificate for tls-alpn-01 challenge: "+
|
e := errors.Errorf("incorrect certificate for tls-alpn-01 challenge: "+
|
||||||
"leaf certificate must contain a single DNS name, %v", tc.Value)
|
"leaf certificate must contain a single DNS name, %v", tc.Value)
|
||||||
up.Error = RejectedIdentifierErr(e).ToACME()
|
up.Error = TLSErr(e).ToACME()
|
||||||
return up, nil
|
return up, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,7 +541,7 @@ func (tc *tlsALPN01Challenge) validate(jwk *jose.JSONWebKey, vo validateOptions)
|
||||||
e := errors.Errorf("incorrect certificate for tls-alpn-01 challenge: " +
|
e := errors.Errorf("incorrect certificate for tls-alpn-01 challenge: " +
|
||||||
"missing acmeValidationV1 extension")
|
"missing acmeValidationV1 extension")
|
||||||
up.Error = IncorrectResponseErr(e).ToACME()
|
up.Error = IncorrectResponseErr(e).ToACME()
|
||||||
return tc, nil
|
return up, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// dns01Challenge represents an dns-01 acme challenge.
|
// dns01Challenge represents an dns-01 acme challenge.
|
||||||
|
|
|
@ -1052,493 +1052,358 @@ func TestTLSALPN01Validate(t *testing.T) {
|
||||||
err *Error
|
err *Error
|
||||||
}
|
}
|
||||||
tests := map[string]func(t *testing.T) test{
|
tests := map[string]func(t *testing.T) test{
|
||||||
"ok/status-already-valid": func(t *testing.T) test {
|
|
||||||
|
"valid/status-noop": func(t *testing.T) test {
|
||||||
ch, err := newTLSALPNCh()
|
ch, err := newTLSALPNCh()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
_ch, ok := ch.(*tlsALPN01Challenge)
|
b := ch.clone()
|
||||||
assert.Fatal(t, ok)
|
b.Status = StatusValid
|
||||||
_ch.baseChallenge.Status = StatusValid
|
ch = b.morph()
|
||||||
|
|
||||||
return test{
|
return test{
|
||||||
ch: ch,
|
ch: ch,
|
||||||
res: ch,
|
res: ch,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok/status-already-invalid": func(t *testing.T) test {
|
|
||||||
|
"invalid/status-noop": func(t *testing.T) test {
|
||||||
ch, err := newTLSALPNCh()
|
ch, err := newTLSALPNCh()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
_ch, ok := ch.(*tlsALPN01Challenge)
|
b := ch.clone()
|
||||||
assert.Fatal(t, ok)
|
b.Status = StatusInvalid
|
||||||
_ch.baseChallenge.Status = StatusInvalid
|
ch = b.morph()
|
||||||
|
|
||||||
return test{
|
return test{
|
||||||
ch: ch,
|
ch: ch,
|
||||||
res: ch,
|
res: ch,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok/tls-dial-error": func(t *testing.T) test {
|
|
||||||
|
"processing/tls-dial-error": func(t *testing.T) test {
|
||||||
ch, err := newTLSALPNCh()
|
ch, err := newTLSALPNCh()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
oldb, err := json.Marshal(ch)
|
b := ch.clone()
|
||||||
assert.FatalError(t, err)
|
b.Status = StatusProcessing
|
||||||
|
|
||||||
expErr := ConnectionErr(errors.Errorf("error doing TLS dial for %v:443: force", ch.getValue()))
|
a := b.clone()
|
||||||
baseClone := ch.clone()
|
e := (errors.Errorf("error doing TLS dial for %v:443: force", ch.getValue()))
|
||||||
baseClone.Error = expErr.ToACME()
|
a.Error = ConnectionErr(e).ToACME()
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
newb, err := json.Marshal(newCh)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
return test{
|
return test{
|
||||||
ch: ch,
|
ch: b.morph(),
|
||||||
vo: validateOptions{
|
vo: validateOptions{
|
||||||
tlsDial: func(network, addr string, config *tls.Config) (*tls.Conn, error) {
|
tlsDial: func(network, addr string, config *tls.Config) (*tls.Conn, error) {
|
||||||
return nil, errors.New("force")
|
return nil, errors.New("force")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
db: &db.MockNoSQLDB{
|
res: a.morph(),
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
assert.Equals(t, newval, newb)
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: ch,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok/timeout": func(t *testing.T) test {
|
|
||||||
|
"processing/timeout": func(t *testing.T) test {
|
||||||
ch, err := newTLSALPNCh()
|
ch, err := newTLSALPNCh()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
oldb, err := json.Marshal(ch)
|
b := ch.clone()
|
||||||
assert.FatalError(t, err)
|
b.Status = StatusProcessing
|
||||||
|
|
||||||
expErr := ConnectionErr(errors.Errorf("error doing TLS dial for %v:443: tls: DialWithDialer timed out", ch.getValue()))
|
a := b.clone()
|
||||||
baseClone := ch.clone()
|
e := errors.Errorf("error doing TLS dial for %v:443: tls: DialWithDialer timed out", ch.getValue())
|
||||||
baseClone.Error = expErr.ToACME()
|
a.Error = ConnectionErr(e).ToACME()
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
newb, err := json.Marshal(newCh)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
srv, tlsDial := newTestTLSALPNServer(nil)
|
srv, tlsDial := newTestTLSALPNServer(nil)
|
||||||
// srv.Start() - do not start server to cause timeout
|
// srv.Start() - do not start server to cause timeout
|
||||||
|
|
||||||
return test{
|
return test{
|
||||||
srv: srv,
|
srv: srv,
|
||||||
ch: ch,
|
ch: b.morph(),
|
||||||
vo: validateOptions{
|
vo: validateOptions{
|
||||||
tlsDial: tlsDial,
|
tlsDial: tlsDial,
|
||||||
},
|
},
|
||||||
db: &db.MockNoSQLDB{
|
res: a.morph(),
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
assert.Equals(t, string(newval), string(newb))
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: ch,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok/no-certificates": func(t *testing.T) test {
|
|
||||||
|
"processing/no-certificates": func(t *testing.T) test {
|
||||||
ch, err := newTLSALPNCh()
|
ch, err := newTLSALPNCh()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
oldb, err := json.Marshal(ch)
|
b := ch.clone()
|
||||||
assert.FatalError(t, err)
|
b.Status = StatusProcessing
|
||||||
|
|
||||||
expErr := RejectedIdentifierErr(errors.Errorf("tls-alpn-01 challenge for %v resulted in no certificates", ch.getValue()))
|
a := b.clone()
|
||||||
baseClone := ch.clone()
|
e := errors.Errorf("tls-alpn-01 challenge for %v resulted in no certificates", ch.getValue())
|
||||||
baseClone.Error = expErr.ToACME()
|
a.Error = TLSErr(e).ToACME()
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
newb, err := json.Marshal(newCh)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
return test{
|
return test{
|
||||||
ch: ch,
|
ch: b.morph(),
|
||||||
vo: validateOptions{
|
vo: validateOptions{
|
||||||
tlsDial: func(network, addr string, config *tls.Config) (*tls.Conn, error) {
|
tlsDial: func(network, addr string, config *tls.Config) (*tls.Conn, error) {
|
||||||
return tls.Client(&noopConn{}, config), nil
|
return tls.Client(&noopConn{}, config), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
db: &db.MockNoSQLDB{
|
res: a.morph(),
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
assert.Equals(t, string(newval), string(newb))
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: ch,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok/no-names": func(t *testing.T) test {
|
|
||||||
|
"processing/no-protocol": func(t *testing.T) test {
|
||||||
ch, err := newTLSALPNCh()
|
ch, err := newTLSALPNCh()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
oldb, err := json.Marshal(ch)
|
b := ch.clone()
|
||||||
assert.FatalError(t, err)
|
b.Status = StatusProcessing
|
||||||
|
|
||||||
expErr := RejectedIdentifierErr(errors.Errorf("incorrect certificate for tls-alpn-01 challenge: leaf certificate must contain a single DNS name, %v", ch.getValue()))
|
a := b.clone()
|
||||||
baseClone := ch.clone()
|
e := errors.New("cannot negotiate ALPN acme-tls/1 protocol for tls-alpn-01 challenge")
|
||||||
baseClone.Error = expErr.ToACME()
|
a.Error = TLSErr(e).ToACME()
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
newb, err := json.Marshal(newCh)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
expKeyAuthHash := sha256.Sum256([]byte(expKeyAuth))
|
|
||||||
|
|
||||||
cert, err := newTLSALPNValidationCert(expKeyAuthHash[:], false, true)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
srv, tlsDial := newTestTLSALPNServer(cert)
|
|
||||||
srv.Start()
|
|
||||||
|
|
||||||
return test{
|
|
||||||
srv: srv,
|
|
||||||
ch: ch,
|
|
||||||
vo: validateOptions{
|
|
||||||
tlsDial: tlsDial,
|
|
||||||
},
|
|
||||||
jwk: jwk,
|
|
||||||
db: &db.MockNoSQLDB{
|
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
assert.Equals(t, string(newval), string(newb))
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: ch,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ok/too-many-names": func(t *testing.T) test {
|
|
||||||
ch, err := newTLSALPNCh()
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
oldb, err := json.Marshal(ch)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
expErr := RejectedIdentifierErr(errors.Errorf("incorrect certificate for tls-alpn-01 challenge: leaf certificate must contain a single DNS name, %v", ch.getValue()))
|
|
||||||
baseClone := ch.clone()
|
|
||||||
baseClone.Error = expErr.ToACME()
|
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
newb, err := json.Marshal(newCh)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
expKeyAuthHash := sha256.Sum256([]byte(expKeyAuth))
|
|
||||||
|
|
||||||
cert, err := newTLSALPNValidationCert(expKeyAuthHash[:], false, true, ch.getValue(), "other.internal")
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
srv, tlsDial := newTestTLSALPNServer(cert)
|
|
||||||
srv.Start()
|
|
||||||
|
|
||||||
return test{
|
|
||||||
srv: srv,
|
|
||||||
ch: ch,
|
|
||||||
vo: validateOptions{
|
|
||||||
tlsDial: tlsDial,
|
|
||||||
},
|
|
||||||
jwk: jwk,
|
|
||||||
db: &db.MockNoSQLDB{
|
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
assert.Equals(t, string(newval), string(newb))
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: ch,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ok/wrong-name": func(t *testing.T) test {
|
|
||||||
ch, err := newTLSALPNCh()
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
oldb, err := json.Marshal(ch)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
expErr := RejectedIdentifierErr(errors.Errorf("incorrect certificate for tls-alpn-01 challenge: leaf certificate must contain a single DNS name, %v", ch.getValue()))
|
|
||||||
baseClone := ch.clone()
|
|
||||||
baseClone.Error = expErr.ToACME()
|
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
newb, err := json.Marshal(newCh)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
expKeyAuthHash := sha256.Sum256([]byte(expKeyAuth))
|
|
||||||
|
|
||||||
cert, err := newTLSALPNValidationCert(expKeyAuthHash[:], false, true, "other.internal")
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
srv, tlsDial := newTestTLSALPNServer(cert)
|
|
||||||
srv.Start()
|
|
||||||
|
|
||||||
return test{
|
|
||||||
srv: srv,
|
|
||||||
ch: ch,
|
|
||||||
vo: validateOptions{
|
|
||||||
tlsDial: tlsDial,
|
|
||||||
},
|
|
||||||
jwk: jwk,
|
|
||||||
db: &db.MockNoSQLDB{
|
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
assert.Equals(t, string(newval), string(newb))
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: ch,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ok/no-extension": func(t *testing.T) test {
|
|
||||||
ch, err := newTLSALPNCh()
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
oldb, err := json.Marshal(ch)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
expErr := RejectedIdentifierErr(errors.New("incorrect certificate for tls-alpn-01 challenge: missing acmeValidationV1 extension"))
|
|
||||||
baseClone := ch.clone()
|
|
||||||
baseClone.Error = expErr.ToACME()
|
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
newb, err := json.Marshal(newCh)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
cert, err := newTLSALPNValidationCert(nil, false, true, ch.getValue())
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
srv, tlsDial := newTestTLSALPNServer(cert)
|
|
||||||
srv.Start()
|
|
||||||
|
|
||||||
return test{
|
|
||||||
srv: srv,
|
|
||||||
ch: ch,
|
|
||||||
vo: validateOptions{
|
|
||||||
tlsDial: tlsDial,
|
|
||||||
},
|
|
||||||
jwk: jwk,
|
|
||||||
db: &db.MockNoSQLDB{
|
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
assert.Equals(t, string(newval), string(newb))
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: ch,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ok/extension-not-critical": func(t *testing.T) test {
|
|
||||||
ch, err := newTLSALPNCh()
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
oldb, err := json.Marshal(ch)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
expErr := RejectedIdentifierErr(errors.New("incorrect certificate for tls-alpn-01 challenge: acmeValidationV1 extension not critical"))
|
|
||||||
baseClone := ch.clone()
|
|
||||||
baseClone.Error = expErr.ToACME()
|
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
newb, err := json.Marshal(newCh)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
expKeyAuthHash := sha256.Sum256([]byte(expKeyAuth))
|
|
||||||
|
|
||||||
cert, err := newTLSALPNValidationCert(expKeyAuthHash[:], false, false, ch.getValue())
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
srv, tlsDial := newTestTLSALPNServer(cert)
|
|
||||||
srv.Start()
|
|
||||||
|
|
||||||
return test{
|
|
||||||
srv: srv,
|
|
||||||
ch: ch,
|
|
||||||
vo: validateOptions{
|
|
||||||
tlsDial: tlsDial,
|
|
||||||
},
|
|
||||||
jwk: jwk,
|
|
||||||
db: &db.MockNoSQLDB{
|
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
assert.Equals(t, string(newval), string(newb))
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: ch,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ok/extension-malformed": func(t *testing.T) test {
|
|
||||||
ch, err := newTLSALPNCh()
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
oldb, err := json.Marshal(ch)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
expErr := RejectedIdentifierErr(errors.New("incorrect certificate for tls-alpn-01 challenge: malformed acmeValidationV1 extension value"))
|
|
||||||
baseClone := ch.clone()
|
|
||||||
baseClone.Error = expErr.ToACME()
|
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
newb, err := json.Marshal(newCh)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
cert, err := newTLSALPNValidationCert([]byte{1, 2, 3}, false, true, ch.getValue())
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
srv, tlsDial := newTestTLSALPNServer(cert)
|
|
||||||
srv.Start()
|
|
||||||
|
|
||||||
return test{
|
|
||||||
srv: srv,
|
|
||||||
ch: ch,
|
|
||||||
vo: validateOptions{
|
|
||||||
tlsDial: tlsDial,
|
|
||||||
},
|
|
||||||
jwk: jwk,
|
|
||||||
db: &db.MockNoSQLDB{
|
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
assert.Equals(t, string(newval), string(newb))
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: ch,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ok/no-protocol": func(t *testing.T) test {
|
|
||||||
ch, err := newTLSALPNCh()
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
oldb, err := json.Marshal(ch)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
expErr := RejectedIdentifierErr(errors.New("cannot negotiate ALPN acme-tls/1 protocol for tls-alpn-01 challenge"))
|
|
||||||
baseClone := ch.clone()
|
|
||||||
baseClone.Error = expErr.ToACME()
|
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
newb, err := json.Marshal(newCh)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
srv := httptest.NewTLSServer(nil)
|
srv := httptest.NewTLSServer(nil)
|
||||||
|
|
||||||
return test{
|
return test{
|
||||||
srv: srv,
|
srv: srv,
|
||||||
ch: ch,
|
ch: b.morph(),
|
||||||
vo: validateOptions{
|
vo: validateOptions{
|
||||||
tlsDial: func(network, addr string, config *tls.Config) (*tls.Conn, error) {
|
tlsDial: func(network, addr string, config *tls.Config) (*tls.Conn, error) {
|
||||||
return tls.DialWithDialer(&net.Dialer{Timeout: time.Second}, "tcp", srv.Listener.Addr().String(), config)
|
return tls.DialWithDialer(&net.Dialer{Timeout: time.Second}, "tcp", srv.Listener.Addr().String(), config)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
jwk: jwk,
|
jwk: jwk,
|
||||||
db: &db.MockNoSQLDB{
|
res: a.morph(),
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
assert.Equals(t, string(newval), string(newb))
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: ch,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok/mismatched-token": func(t *testing.T) test {
|
|
||||||
|
"processing/no-names": func(t *testing.T) test {
|
||||||
ch, err := newTLSALPNCh()
|
ch, err := newTLSALPNCh()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
oldb, err := json.Marshal(ch)
|
b := ch.clone()
|
||||||
assert.FatalError(t, err)
|
b.Status = StatusProcessing
|
||||||
|
|
||||||
|
a := b.clone()
|
||||||
|
e := errors.Errorf("incorrect certificate for tls-alpn-01 challenge: leaf certificate must contain a single DNS name, %v", ch.getValue())
|
||||||
|
a.Error = TLSErr(e).ToACME()
|
||||||
|
|
||||||
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
expKeyAuthHash := sha256.Sum256([]byte(expKeyAuth))
|
expKeyAuthHash := sha256.Sum256([]byte(expKeyAuth))
|
||||||
incorrectTokenHash := sha256.Sum256([]byte("mismatched"))
|
|
||||||
|
|
||||||
expErr := RejectedIdentifierErr(errors.Errorf("incorrect certificate for tls-alpn-01 challenge: "+
|
cert, err := newTLSALPNValidationCert(expKeyAuthHash[:], false, true)
|
||||||
"expected acmeValidationV1 extension value %s for this challenge but got %s",
|
|
||||||
hex.EncodeToString(expKeyAuthHash[:]), hex.EncodeToString(incorrectTokenHash[:])))
|
|
||||||
baseClone := ch.clone()
|
|
||||||
baseClone.Error = expErr.ToACME()
|
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
newb, err := json.Marshal(newCh)
|
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
cert, err := newTLSALPNValidationCert(incorrectTokenHash[:], false, true, ch.getValue())
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
srv, tlsDial := newTestTLSALPNServer(cert)
|
srv, tlsDial := newTestTLSALPNServer(cert)
|
||||||
srv.Start()
|
srv.Start()
|
||||||
|
|
||||||
return test{
|
return test{
|
||||||
srv: srv,
|
srv: srv,
|
||||||
ch: ch,
|
ch: b.morph(),
|
||||||
vo: validateOptions{
|
vo: validateOptions{
|
||||||
tlsDial: tlsDial,
|
tlsDial: tlsDial,
|
||||||
},
|
},
|
||||||
jwk: jwk,
|
jwk: jwk,
|
||||||
db: &db.MockNoSQLDB{
|
res: a.morph(),
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
assert.Equals(t, string(newval), string(newb))
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: ch,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok/obsolete-oid": func(t *testing.T) test {
|
|
||||||
|
"processing/too-many-names": func(t *testing.T) test {
|
||||||
ch, err := newTLSALPNCh()
|
ch, err := newTLSALPNCh()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
oldb, err := json.Marshal(ch)
|
b := ch.clone()
|
||||||
|
b.Status = StatusProcessing
|
||||||
|
|
||||||
|
a := b.clone()
|
||||||
|
e := errors.Errorf("incorrect certificate for tls-alpn-01 challenge: leaf certificate must contain a single DNS name, %v", ch.getValue())
|
||||||
|
a.Error = TLSErr(e).ToACME()
|
||||||
|
|
||||||
|
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
expKeyAuthHash := sha256.Sum256([]byte(expKeyAuth))
|
||||||
|
|
||||||
|
cert, err := newTLSALPNValidationCert(expKeyAuthHash[:], false, true, ch.getValue(), "other.internal")
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
srv, tlsDial := newTestTLSALPNServer(cert)
|
||||||
|
srv.Start()
|
||||||
|
|
||||||
|
return test{
|
||||||
|
srv: srv,
|
||||||
|
ch: b.morph(),
|
||||||
|
vo: validateOptions{
|
||||||
|
tlsDial: tlsDial,
|
||||||
|
},
|
||||||
|
jwk: jwk,
|
||||||
|
res: a.morph(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"processing/wrong-name": func(t *testing.T) test {
|
||||||
|
ch, err := newTLSALPNCh()
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
b := ch.clone()
|
||||||
|
b.Status = StatusProcessing
|
||||||
|
|
||||||
|
a := b.clone()
|
||||||
|
e := errors.Errorf("incorrect certificate for tls-alpn-01 challenge: leaf certificate must contain a single DNS name, %v", ch.getValue())
|
||||||
|
a.Error = TLSErr(e).ToACME()
|
||||||
|
|
||||||
|
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
expKeyAuthHash := sha256.Sum256([]byte(expKeyAuth))
|
||||||
|
|
||||||
|
cert, err := newTLSALPNValidationCert(expKeyAuthHash[:], false, true, "other.internal")
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
srv, tlsDial := newTestTLSALPNServer(cert)
|
||||||
|
srv.Start()
|
||||||
|
|
||||||
|
return test{
|
||||||
|
srv: srv,
|
||||||
|
ch: b.morph(),
|
||||||
|
vo: validateOptions{
|
||||||
|
tlsDial: tlsDial,
|
||||||
|
},
|
||||||
|
jwk: jwk,
|
||||||
|
res: a.morph(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"processing/no-extension": func(t *testing.T) test {
|
||||||
|
ch, err := newTLSALPNCh()
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
b := ch.clone()
|
||||||
|
b.Status = StatusProcessing
|
||||||
|
|
||||||
|
a := b.clone()
|
||||||
|
e := errors.New("incorrect certificate for tls-alpn-01 challenge: missing acmeValidationV1 extension")
|
||||||
|
a.Error = IncorrectResponseErr(e).ToACME()
|
||||||
|
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
|
cert, err := newTLSALPNValidationCert(nil, false, true, ch.getValue())
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
srv, tlsDial := newTestTLSALPNServer(cert)
|
||||||
|
srv.Start()
|
||||||
|
|
||||||
|
return test{
|
||||||
|
srv: srv,
|
||||||
|
ch: b.morph(),
|
||||||
|
vo: validateOptions{
|
||||||
|
tlsDial: tlsDial,
|
||||||
|
},
|
||||||
|
jwk: jwk,
|
||||||
|
res: a.morph(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"processing/extension-not-critical": func(t *testing.T) test {
|
||||||
|
ch, err := newTLSALPNCh()
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
b := ch.clone()
|
||||||
|
b.Status = StatusProcessing
|
||||||
|
|
||||||
|
a := b.clone()
|
||||||
|
e := errors.New("incorrect certificate for tls-alpn-01 challenge: acmeValidationV1 extension not critical")
|
||||||
|
a.Error = IncorrectResponseErr(e).ToACME()
|
||||||
|
|
||||||
|
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
expKeyAuthHash := sha256.Sum256([]byte(expKeyAuth))
|
||||||
|
|
||||||
|
cert, err := newTLSALPNValidationCert(expKeyAuthHash[:], false, false, ch.getValue())
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
srv, tlsDial := newTestTLSALPNServer(cert)
|
||||||
|
srv.Start()
|
||||||
|
|
||||||
|
return test{
|
||||||
|
srv: srv,
|
||||||
|
ch: b.morph(),
|
||||||
|
vo: validateOptions{
|
||||||
|
tlsDial: tlsDial,
|
||||||
|
},
|
||||||
|
jwk: jwk,
|
||||||
|
res: a.morph(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"processing/extension-malformed": func(t *testing.T) test {
|
||||||
|
ch, err := newTLSALPNCh()
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
b := ch.clone()
|
||||||
|
b.Status = StatusProcessing
|
||||||
|
|
||||||
|
a := b.clone()
|
||||||
|
e := errors.New("incorrect certificate for tls-alpn-01 challenge: malformed acmeValidationV1 extension value")
|
||||||
|
a.Error = IncorrectResponseErr(e).ToACME()
|
||||||
|
|
||||||
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
expErr := RejectedIdentifierErr(errors.New("incorrect certificate for tls-alpn-01 challenge: " +
|
cert, err := newTLSALPNValidationCert([]byte{1, 2, 3}, false, true, ch.getValue())
|
||||||
"obsolete id-pe-acmeIdentifier in acmeValidationV1 extension"))
|
|
||||||
baseClone := ch.clone()
|
|
||||||
baseClone.Error = expErr.ToACME()
|
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
newb, err := json.Marshal(newCh)
|
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
srv, tlsDial := newTestTLSALPNServer(cert)
|
||||||
|
srv.Start()
|
||||||
|
|
||||||
|
return test{
|
||||||
|
srv: srv,
|
||||||
|
ch: b.morph(),
|
||||||
|
vo: validateOptions{
|
||||||
|
tlsDial: tlsDial,
|
||||||
|
},
|
||||||
|
jwk: jwk,
|
||||||
|
res: a.morph(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"invalid/mismatched-token": func(t *testing.T) test {
|
||||||
|
ch, err := newTLSALPNCh()
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
b := ch.clone()
|
||||||
|
b.Status = StatusProcessing
|
||||||
|
|
||||||
|
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
expKeyAuthHash := sha256.Sum256([]byte(expKeyAuth))
|
||||||
|
incorrectTokenHash := sha256.Sum256([]byte("mismatched"))
|
||||||
|
|
||||||
|
a := b.clone()
|
||||||
|
e := errors.Errorf("incorrect certificate for tls-alpn-01 challenge: "+
|
||||||
|
"expected acmeValidationV1 extension value %s for this challenge but got %s",
|
||||||
|
hex.EncodeToString(expKeyAuthHash[:]), hex.EncodeToString(incorrectTokenHash[:]))
|
||||||
|
a.Error = IncorrectResponseErr(e).ToACME()
|
||||||
|
a.Status = StatusInvalid
|
||||||
|
|
||||||
|
cert, err := newTLSALPNValidationCert(incorrectTokenHash[:], false, true, ch.getValue())
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
srv, tlsDial := newTestTLSALPNServer(cert)
|
||||||
|
srv.Start()
|
||||||
|
|
||||||
|
return test{
|
||||||
|
srv: srv,
|
||||||
|
ch: b.morph(),
|
||||||
|
vo: validateOptions{
|
||||||
|
tlsDial: tlsDial,
|
||||||
|
},
|
||||||
|
jwk: jwk,
|
||||||
|
res: a.morph(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"processing/obsolete-oid": func(t *testing.T) test {
|
||||||
|
ch, err := newTLSALPNCh()
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
b := ch.clone()
|
||||||
|
b.Status = StatusProcessing
|
||||||
|
|
||||||
|
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
|
a := b.clone()
|
||||||
|
e := errors.New("incorrect certificate for tls-alpn-01 challenge: " +
|
||||||
|
"obsolete id-pe-acmeIdentifier in acmeValidationV1 extension")
|
||||||
|
a.Error = IncorrectResponseErr(e).ToACME()
|
||||||
|
|
||||||
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
@ -1546,92 +1411,63 @@ func TestTLSALPN01Validate(t *testing.T) {
|
||||||
|
|
||||||
cert, err := newTLSALPNValidationCert(expKeyAuthHash[:], true, true, ch.getValue())
|
cert, err := newTLSALPNValidationCert(expKeyAuthHash[:], true, true, ch.getValue())
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
srv, tlsDial := newTestTLSALPNServer(cert)
|
srv, tlsDial := newTestTLSALPNServer(cert)
|
||||||
srv.Start()
|
srv.Start()
|
||||||
|
|
||||||
return test{
|
return test{
|
||||||
srv: srv,
|
srv: srv,
|
||||||
ch: ch,
|
ch: b.morph(),
|
||||||
vo: validateOptions{
|
vo: validateOptions{
|
||||||
tlsDial: tlsDial,
|
tlsDial: tlsDial,
|
||||||
},
|
},
|
||||||
jwk: jwk,
|
jwk: jwk,
|
||||||
db: &db.MockNoSQLDB{
|
res: a.morph(),
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
assert.Equals(t, string(newval), string(newb))
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: ch,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok": func(t *testing.T) test {
|
|
||||||
|
"valid/expected-identifier": func(t *testing.T) test {
|
||||||
ch, err := newTLSALPNCh()
|
ch, err := newTLSALPNCh()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
_ch, ok := ch.(*tlsALPN01Challenge)
|
b := ch.clone()
|
||||||
assert.Fatal(t, ok)
|
b.Status = StatusProcessing
|
||||||
_ch.baseChallenge.Error = MalformedErr(nil).ToACME()
|
|
||||||
oldb, err := json.Marshal(ch)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
|
|
||||||
baseClone := ch.clone()
|
|
||||||
baseClone.Status = StatusValid
|
|
||||||
baseClone.Error = nil
|
|
||||||
newCh := &tlsALPN01Challenge{baseClone}
|
|
||||||
|
|
||||||
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
expKeyAuth, err := KeyAuthorization(ch.getToken(), jwk)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
expKeyAuthHash := sha256.Sum256([]byte(expKeyAuth))
|
expKeyAuthHash := sha256.Sum256([]byte(expKeyAuth))
|
||||||
|
|
||||||
|
a := b.clone()
|
||||||
|
a.Validated = clock.Now()
|
||||||
|
a.Status = StatusValid
|
||||||
|
a.Error = nil
|
||||||
|
a.Retry = nil
|
||||||
|
|
||||||
cert, err := newTLSALPNValidationCert(expKeyAuthHash[:], false, true, ch.getValue())
|
cert, err := newTLSALPNValidationCert(expKeyAuthHash[:], false, true, ch.getValue())
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
srv, tlsDial := newTestTLSALPNServer(cert)
|
srv, tlsDial := newTestTLSALPNServer(cert)
|
||||||
srv.Start()
|
srv.Start()
|
||||||
|
|
||||||
return test{
|
return test{
|
||||||
srv: srv,
|
srv: srv,
|
||||||
ch: ch,
|
ch: b.morph(),
|
||||||
vo: validateOptions{
|
vo: validateOptions{
|
||||||
tlsDial: func(network, addr string, config *tls.Config) (conn *tls.Conn, err error) {
|
tlsDial: func(network, addr string, config *tls.Config) (conn *tls.Conn, err error) {
|
||||||
assert.Equals(t, network, "tcp")
|
assert.Equals(t, network, "tcp")
|
||||||
assert.Equals(t, addr, net.JoinHostPort(newCh.getValue(), "443"))
|
assert.Equals(t, addr, net.JoinHostPort(ch.getValue(), "443"))
|
||||||
assert.Equals(t, config.NextProtos, []string{"acme-tls/1"})
|
assert.Equals(t, config.NextProtos, []string{"acme-tls/1"})
|
||||||
assert.Equals(t, config.ServerName, newCh.getValue())
|
assert.Equals(t, config.ServerName, ch.getValue())
|
||||||
assert.True(t, config.InsecureSkipVerify)
|
assert.True(t, config.InsecureSkipVerify)
|
||||||
|
|
||||||
return tlsDial(network, addr, config)
|
return tlsDial(network, addr, config)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
jwk: jwk,
|
jwk: jwk,
|
||||||
db: &db.MockNoSQLDB{
|
res: a.morph(),
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
|
||||||
assert.Equals(t, bucket, challengeTable)
|
|
||||||
assert.Equals(t, key, []byte(ch.getID()))
|
|
||||||
assert.Equals(t, old, oldb)
|
|
||||||
|
|
||||||
alpnCh, err := unmarshalChallenge(newval)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, alpnCh.getStatus(), StatusValid)
|
|
||||||
assert.True(t, alpnCh.getValidated().Before(time.Now().UTC().Add(time.Minute)))
|
|
||||||
assert.True(t, alpnCh.getValidated().After(time.Now().UTC().Add(-1*time.Second)))
|
|
||||||
|
|
||||||
baseClone.Validated = alpnCh.getValidated()
|
|
||||||
|
|
||||||
return nil, true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
res: newCh,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, run := range tests {
|
for name, run := range tests {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
tc := run(t)
|
tc := run(t)
|
||||||
|
@ -1657,7 +1493,16 @@ func TestTLSALPN01Validate(t *testing.T) {
|
||||||
assert.Equals(t, tc.res.getToken(), ch.getToken())
|
assert.Equals(t, tc.res.getToken(), ch.getToken())
|
||||||
assert.Equals(t, tc.res.getCreated(), ch.getCreated())
|
assert.Equals(t, tc.res.getCreated(), ch.getCreated())
|
||||||
assert.Equals(t, tc.res.getValidated(), ch.getValidated())
|
assert.Equals(t, tc.res.getValidated(), ch.getValidated())
|
||||||
|
if tc.res.getValidated() != ch.getValidated() {
|
||||||
|
now := clock.Now()
|
||||||
|
window := now.Sub(tc.res.getValidated())
|
||||||
|
assert.True(t, now.Sub(ch.getValidated()) <= window,
|
||||||
|
"validated timestamp should come before now but after test case setup")
|
||||||
|
} else {
|
||||||
|
assert.Equals(t, tc.res.getValidated(), ch.getValidated())
|
||||||
|
}
|
||||||
assert.Equals(t, tc.res.getError(), ch.getError())
|
assert.Equals(t, tc.res.getError(), ch.getError())
|
||||||
|
assert.Equals(t, tc.res.getRetry(), ch.getRetry())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue