diff --git a/common.go b/common.go index 5d213a1..ec3b849 100644 --- a/common.go +++ b/common.go @@ -656,6 +656,13 @@ type Config struct { // testing or in combination with VerifyConnection or VerifyPeerCertificate. InsecureSkipVerify bool + // InsecureSkipTimeVerify controls whether a client verifies the server's + // certificate chain against time. If InsecureSkipTimeVerify is true, + // crypto/tls accepts the certificate even when it is expired. + // + // This field is ignored when InsecureSkipVerify is true. + InsecureSkipTimeVerify bool // [uTLS] + // InsecureServerNameToVerify is used to verify the hostname on the returned // certificates. It is intended to use with spoofed ServerName. // If InsecureServerNameToVerify is "*", crypto/tls will do normal @@ -821,6 +828,7 @@ func (c *Config) Clone() *Config { ClientAuth: c.ClientAuth, ClientCAs: c.ClientCAs, InsecureSkipVerify: c.InsecureSkipVerify, + InsecureSkipTimeVerify: c.InsecureSkipTimeVerify, InsecureServerNameToVerify: c.InsecureServerNameToVerify, CipherSuites: c.CipherSuites, PreferServerCipherSuites: c.PreferServerCipherSuites, diff --git a/handshake_client.go b/handshake_client.go index e0f21eb..a5bedc9 100644 --- a/handshake_client.go +++ b/handshake_client.go @@ -303,14 +303,26 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string, return cacheKey, nil, nil, nil, nil } serverCert := session.serverCertificates[0] - if c.config.time().After(serverCert.NotAfter) { - // Expired certificate, delete the entry. - c.config.ClientSessionCache.Put(cacheKey, nil) - return cacheKey, nil, nil, nil, nil + // [UTLS SECTION START] + if !c.config.InsecureSkipTimeVerify { + if c.config.time().After(serverCert.NotAfter) { + // Expired certificate, delete the entry. + c.config.ClientSessionCache.Put(cacheKey, nil) + return cacheKey, nil, nil, nil, nil + } } - if err := serverCert.VerifyHostname(c.config.ServerName); err != nil { - return cacheKey, nil, nil, nil, nil + var dnsName string + if len(c.config.InsecureServerNameToVerify) == 0 { + dnsName = c.config.ServerName + } else if c.config.InsecureServerNameToVerify != "*" { + dnsName = c.config.InsecureServerNameToVerify } + if len(dnsName) > 0 { + if err := serverCert.VerifyHostname(dnsName); err != nil { + return cacheKey, nil, nil, nil, nil + } + } + // [UTLS SECTION END] } if session.vers != VersionTLS13 { @@ -895,6 +907,10 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error { Intermediates: x509.NewCertPool(), } + if c.config.InsecureSkipTimeVerify { + opts.CurrentTime = certs[0].NotAfter + } + if len(c.config.InsecureServerNameToVerify) == 0 { opts.DNSName = c.config.ServerName } else if c.config.InsecureServerNameToVerify != "*" { diff --git a/tls_test.go b/tls_test.go index 98de1df..dd02f9b 100644 --- a/tls_test.go +++ b/tls_test.go @@ -814,7 +814,7 @@ func TestCloneNonFuncFields(t *testing.T) { f.Set(reflect.ValueOf("b")) case "ClientAuth": f.Set(reflect.ValueOf(VerifyClientCertIfGiven)) - case "InsecureSkipVerify", "SessionTicketsDisabled", "DynamicRecordSizingDisabled", "PreferServerCipherSuites": + case "InsecureSkipVerify", "InsecureSkipTimeVerify", "SessionTicketsDisabled", "DynamicRecordSizingDisabled", "PreferServerCipherSuites": f.Set(reflect.ValueOf(true)) case "InsecureServerNameToVerify": f.Set(reflect.ValueOf("c"))