From 17e2929ff7382c59a12af27cc2ae2bee5b654dbc Mon Sep 17 00:00:00 2001 From: molon <3739161+molon@users.noreply.github.com> Date: Mon, 13 Mar 2023 00:58:57 +0800 Subject: [PATCH] Add `InsecureSkipTimeVerify` (#174) * add `InsecureSkipTimeVerify` * fix the cache verification when `InsecureServerNameToVerify` set * better description of `InsecureSkipTimeVerify` Co-authored-by: Gaukas Wang * minimize the change made + wrap the modified section * fix: use tab replace space indentation --------- Co-authored-by: Gaukas Wang --- common.go | 8 ++++++++ handshake_client.go | 28 ++++++++++++++++++++++------ tls_test.go | 2 +- 3 files changed, 31 insertions(+), 7 deletions(-) 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"))