mirror of
https://github.com/golang/go.git
synced 2026-01-29 07:02:05 +03:00
Compare commits
5 Commits
738bc3a33c
...
d5987bff8a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5987bff8a | ||
|
|
c2d04c0994 | ||
|
|
6b1110a40f | ||
|
|
0765a9d624 | ||
|
|
b19100991a |
@@ -301,17 +301,12 @@ func (f *File) saveExport(x interface{}, context astContext) {
|
||||
error_(c.Pos(), "export comment has wrong name %q, want %q", name, n.Name.Name)
|
||||
}
|
||||
|
||||
doc := ""
|
||||
for _, c1 := range n.Doc.List {
|
||||
if c1 != c {
|
||||
doc += c1.Text + "\n"
|
||||
}
|
||||
}
|
||||
|
||||
f.ExpFunc = append(f.ExpFunc, &ExpFunc{
|
||||
Func: n,
|
||||
ExpName: name,
|
||||
Doc: doc,
|
||||
// Caution: Do not set the Doc field on purpose
|
||||
// to ensure that there are no unintended artifacts
|
||||
// in the binary. See https://go.dev/issue/76697.
|
||||
})
|
||||
break
|
||||
}
|
||||
|
||||
@@ -942,10 +942,6 @@ const maxSessionTicketLifetime = 7 * 24 * time.Hour
|
||||
|
||||
// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a [Config] that is
|
||||
// being used concurrently by a TLS client or server.
|
||||
//
|
||||
// If Config.SessionTicketKey is unpopulated, and Config.SetSessionTicketKeys has not been
|
||||
// called, the clone will not share the same auto-rotated session ticket keys as the original
|
||||
// Config in order to prevent sessions from being resumed across Configs.
|
||||
func (c *Config) Clone() *Config {
|
||||
if c == nil {
|
||||
return nil
|
||||
@@ -986,8 +982,7 @@ func (c *Config) Clone() *Config {
|
||||
EncryptedClientHelloRejectionVerify: c.EncryptedClientHelloRejectionVerify,
|
||||
EncryptedClientHelloKeys: c.EncryptedClientHelloKeys,
|
||||
sessionTicketKeys: c.sessionTicketKeys,
|
||||
// We explicitly do not copy autoSessionTicketKeys, so that Configs do
|
||||
// not share the same auto-rotated keys.
|
||||
autoSessionTicketKeys: c.autoSessionTicketKeys,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1808,3 +1803,31 @@ func fipsAllowChain(chain []*x509.Certificate) bool {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// anyValidVerifiedChain reports if at least one of the chains in verifiedChains
|
||||
// is valid, as indicated by none of the certificates being expired and the root
|
||||
// being in opts.Roots (or in the system root pool if opts.Roots is nil). If
|
||||
// verifiedChains is empty, it returns false.
|
||||
func anyValidVerifiedChain(verifiedChains [][]*x509.Certificate, opts x509.VerifyOptions) bool {
|
||||
for _, chain := range verifiedChains {
|
||||
if len(chain) == 0 {
|
||||
continue
|
||||
}
|
||||
if slices.ContainsFunc(chain, func(cert *x509.Certificate) bool {
|
||||
return opts.CurrentTime.Before(cert.NotBefore) || opts.CurrentTime.After(cert.NotAfter)
|
||||
}) {
|
||||
continue
|
||||
}
|
||||
// Since we already validated the chain, we only care that it is
|
||||
// rooted in a CA in CAs, or in the system pool. On platforms where
|
||||
// we control chain validation (e.g. not Windows or macOS) this is a
|
||||
// simple lookup in the CertPool internal hash map. On other
|
||||
// platforms, this may be more expensive, depending on how they
|
||||
// implement verification of just root certificates.
|
||||
root := chain[len(chain)-1]
|
||||
if _, err := root.Verify(opts); err == nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -429,9 +429,6 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
|
||||
// Check that the cached server certificate is not expired, and that it's
|
||||
// valid for the ServerName. This should be ensured by the cache key, but
|
||||
// protect the application from a faulty ClientSessionCache implementation.
|
||||
if c.config.time().After(session.peerCertificates[0].NotAfter) {
|
||||
// Expired certificate, delete the entry.
|
||||
c.config.ClientSessionCache.Put(cacheKey, nil)
|
||||
@@ -443,6 +440,18 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
if err := session.peerCertificates[0].VerifyHostname(c.config.ServerName); err != nil {
|
||||
// This should be ensured by the cache key, but protect the
|
||||
// application from a faulty ClientSessionCache implementation.
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
opts := x509.VerifyOptions{
|
||||
CurrentTime: c.config.time(),
|
||||
Roots: c.config.RootCAs,
|
||||
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
}
|
||||
if !anyValidVerifiedChain(session.verifiedChains, opts) {
|
||||
// No valid chains, delete the entry.
|
||||
c.config.ClientSessionCache.Put(cacheKey, nil)
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,16 +520,16 @@ func (hs *serverHandshakeState) checkForResumption() error {
|
||||
if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
|
||||
return nil
|
||||
}
|
||||
if sessionHasClientCerts {
|
||||
now := c.config.time()
|
||||
for _, c := range sessionState.peerCertificates {
|
||||
if now.After(c.NotAfter) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if sessionHasClientCerts && c.config.time().After(sessionState.peerCertificates[0].NotAfter) {
|
||||
return nil
|
||||
}
|
||||
opts := x509.VerifyOptions{
|
||||
CurrentTime: c.config.time(),
|
||||
Roots: c.config.ClientCAs,
|
||||
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
}
|
||||
if sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven &&
|
||||
len(sessionState.verifiedChains) == 0 {
|
||||
!anyValidVerifiedChain(sessionState.verifiedChains, opts) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -2123,7 +2123,7 @@ func TestHandshakeContextHierarchy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandshakeChainExpiryResumptionTLS12(t *testing.T) {
|
||||
func TestHandshakeChainExpiryResumption(t *testing.T) {
|
||||
t.Run("TLS1.2", func(t *testing.T) {
|
||||
testHandshakeChainExpiryResumption(t, VersionTLS12)
|
||||
})
|
||||
@@ -2134,7 +2134,8 @@ func TestHandshakeChainExpiryResumptionTLS12(t *testing.T) {
|
||||
|
||||
func testHandshakeChainExpiryResumption(t *testing.T, version uint16) {
|
||||
now := time.Now()
|
||||
createChain := func(leafNotAfter, rootNotAfter time.Time) (certDER []byte, root *x509.Certificate) {
|
||||
|
||||
createChain := func(leafNotAfter, rootNotAfter time.Time) (leafDER, expiredLeafDER []byte, root *x509.Certificate) {
|
||||
tmpl := &x509.Certificate{
|
||||
Subject: pkix.Name{CommonName: "root"},
|
||||
NotBefore: rootNotAfter.Add(-time.Hour * 24),
|
||||
@@ -2158,39 +2159,177 @@ func testHandshakeChainExpiryResumption(t *testing.T, version uint16) {
|
||||
NotAfter: leafNotAfter,
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
}
|
||||
certDER, err = x509.CreateCertificate(rand.Reader, tmpl, root, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
leafCertDER, err := x509.CreateCertificate(rand.Reader, tmpl, root, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
tmpl.NotBefore, tmpl.NotAfter = leafNotAfter.Add(-time.Hour*24*365), leafNotAfter.Add(-time.Hour*24*364)
|
||||
expiredLeafDERCertDER, err := x509.CreateCertificate(rand.Reader, tmpl, root, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
|
||||
return certDER, root
|
||||
return leafCertDER, expiredLeafDERCertDER, root
|
||||
}
|
||||
testExpiration := func(name string, leafNotAfter, rootNotAfter time.Time) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
initialLeafDER, expiredLeafDER, initialRoot := createChain(leafNotAfter, rootNotAfter)
|
||||
|
||||
serverConfig := testConfig.Clone()
|
||||
serverConfig.MaxVersion = version
|
||||
serverConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{initialLeafDER, expiredLeafDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
serverConfig.ClientCAs = x509.NewCertPool()
|
||||
serverConfig.ClientCAs.AddCert(initialRoot)
|
||||
serverConfig.ClientAuth = RequireAndVerifyClientCert
|
||||
serverConfig.Time = func() time.Time {
|
||||
return now
|
||||
}
|
||||
serverConfig.InsecureSkipVerify = false
|
||||
serverConfig.ServerName = "expired-resume.example.com"
|
||||
|
||||
clientConfig := testConfig.Clone()
|
||||
clientConfig.MaxVersion = version
|
||||
clientConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{initialLeafDER, expiredLeafDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
clientConfig.RootCAs = x509.NewCertPool()
|
||||
clientConfig.RootCAs.AddCert(initialRoot)
|
||||
clientConfig.ServerName = "expired-resume.example.com"
|
||||
clientConfig.ClientSessionCache = NewLRUClientSessionCache(32)
|
||||
clientConfig.InsecureSkipVerify = false
|
||||
clientConfig.ServerName = "expired-resume.example.com"
|
||||
clientConfig.Time = func() time.Time {
|
||||
return now
|
||||
}
|
||||
|
||||
testResume := func(t *testing.T, sc, cc *Config, expectResume bool) {
|
||||
t.Helper()
|
||||
ss, cs, err := testHandshake(t, cc, sc)
|
||||
if err != nil {
|
||||
t.Fatalf("handshake: %v", err)
|
||||
}
|
||||
if cs.DidResume != expectResume {
|
||||
t.Fatalf("DidResume = %v; want %v", cs.DidResume, expectResume)
|
||||
}
|
||||
if ss.DidResume != expectResume {
|
||||
t.Fatalf("DidResume = %v; want %v", cs.DidResume, expectResume)
|
||||
}
|
||||
}
|
||||
|
||||
testResume(t, serverConfig, clientConfig, false)
|
||||
testResume(t, serverConfig, clientConfig, true)
|
||||
|
||||
expiredNow := time.Unix(0, min(leafNotAfter.UnixNano(), rootNotAfter.UnixNano())).Add(time.Minute)
|
||||
|
||||
freshLeafDER, expiredLeafDER, freshRoot := createChain(expiredNow.Add(time.Hour), expiredNow.Add(time.Hour))
|
||||
clientConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{freshLeafDER, expiredLeafDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
serverConfig.Time = func() time.Time {
|
||||
return expiredNow
|
||||
}
|
||||
serverConfig.ClientCAs = x509.NewCertPool()
|
||||
serverConfig.ClientCAs.AddCert(freshRoot)
|
||||
|
||||
testResume(t, serverConfig, clientConfig, false)
|
||||
})
|
||||
}
|
||||
|
||||
initialLeafDER, initialRoot := createChain(now.Add(time.Hour), now.Add(2*time.Hour))
|
||||
testExpiration("LeafExpiresBeforeRoot", now.Add(2*time.Hour), now.Add(3*time.Hour))
|
||||
testExpiration("LeafExpiresAfterRoot", now.Add(2*time.Hour), now.Add(time.Hour))
|
||||
}
|
||||
|
||||
func TestHandshakeGetConfigForClientDifferentClientCAs(t *testing.T) {
|
||||
t.Run("TLS1.2", func(t *testing.T) {
|
||||
testHandshakeGetConfigForClientDifferentClientCAs(t, VersionTLS12)
|
||||
})
|
||||
t.Run("TLS1.3", func(t *testing.T) {
|
||||
testHandshakeGetConfigForClientDifferentClientCAs(t, VersionTLS13)
|
||||
})
|
||||
}
|
||||
|
||||
func testHandshakeGetConfigForClientDifferentClientCAs(t *testing.T, version uint16) {
|
||||
now := time.Now()
|
||||
tmpl := &x509.Certificate{
|
||||
Subject: pkix.Name{CommonName: "root"},
|
||||
NotBefore: now.Add(-time.Hour * 24),
|
||||
NotAfter: now.Add(time.Hour * 24),
|
||||
IsCA: true,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
rootDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
rootA, err := x509.ParseCertificate(rootDER)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseCertificate: %v", err)
|
||||
}
|
||||
rootDER, err = x509.CreateCertificate(rand.Reader, tmpl, tmpl, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
rootB, err := x509.ParseCertificate(rootDER)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseCertificate: %v", err)
|
||||
}
|
||||
|
||||
tmpl = &x509.Certificate{
|
||||
Subject: pkix.Name{},
|
||||
DNSNames: []string{"example.com"},
|
||||
NotBefore: now.Add(-time.Hour * 24),
|
||||
NotAfter: now.Add(time.Hour * 24),
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
}
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, tmpl, rootA, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
|
||||
serverConfig := testConfig.Clone()
|
||||
serverConfig.MaxVersion = version
|
||||
serverConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{initialLeafDER},
|
||||
Certificate: [][]byte{certDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
serverConfig.ClientCAs = x509.NewCertPool()
|
||||
serverConfig.ClientCAs.AddCert(initialRoot)
|
||||
serverConfig.ClientAuth = RequireAndVerifyClientCert
|
||||
serverConfig.Time = func() time.Time {
|
||||
return now
|
||||
}
|
||||
serverConfig.ClientCAs = x509.NewCertPool()
|
||||
serverConfig.ClientCAs.AddCert(rootA)
|
||||
serverConfig.ClientAuth = RequireAndVerifyClientCert
|
||||
switchConfig := false
|
||||
serverConfig.GetConfigForClient = func(clientHello *ClientHelloInfo) (*Config, error) {
|
||||
if !switchConfig {
|
||||
return nil, nil
|
||||
}
|
||||
cfg := serverConfig.Clone()
|
||||
cfg.ClientCAs = x509.NewCertPool()
|
||||
cfg.ClientCAs.AddCert(rootB)
|
||||
return cfg, nil
|
||||
}
|
||||
serverConfig.InsecureSkipVerify = false
|
||||
serverConfig.ServerName = "example.com"
|
||||
|
||||
clientConfig := testConfig.Clone()
|
||||
clientConfig.MaxVersion = version
|
||||
clientConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{initialLeafDER},
|
||||
Certificate: [][]byte{certDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
clientConfig.RootCAs = x509.NewCertPool()
|
||||
clientConfig.RootCAs.AddCert(initialRoot)
|
||||
clientConfig.ServerName = "expired-resume.example.com"
|
||||
clientConfig.ClientSessionCache = NewLRUClientSessionCache(32)
|
||||
clientConfig.RootCAs = x509.NewCertPool()
|
||||
clientConfig.RootCAs.AddCert(rootA)
|
||||
clientConfig.Time = func() time.Time {
|
||||
return now
|
||||
}
|
||||
clientConfig.InsecureSkipVerify = false
|
||||
clientConfig.ServerName = "example.com"
|
||||
|
||||
testResume := func(t *testing.T, sc, cc *Config, expectResume bool) {
|
||||
t.Helper()
|
||||
@@ -2209,16 +2348,112 @@ func testHandshakeChainExpiryResumption(t *testing.T, version uint16) {
|
||||
testResume(t, serverConfig, clientConfig, false)
|
||||
testResume(t, serverConfig, clientConfig, true)
|
||||
|
||||
freshLeafDER, freshRoot := createChain(now.Add(2*time.Hour), now.Add(3*time.Hour))
|
||||
clientConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{freshLeafDER},
|
||||
// Cause GetConfigForClient to return a config cloned from the base config,
|
||||
// but with a different ClientCAs pool. This should cause resumption to fail.
|
||||
switchConfig = true
|
||||
|
||||
testResume(t, serverConfig, clientConfig, false)
|
||||
testResume(t, serverConfig, clientConfig, true)
|
||||
}
|
||||
|
||||
func TestHandshakeChangeRootCAsResumption(t *testing.T) {
|
||||
t.Run("TLS1.2", func(t *testing.T) {
|
||||
testHandshakeChangeRootCAsResumption(t, VersionTLS12)
|
||||
})
|
||||
t.Run("TLS1.3", func(t *testing.T) {
|
||||
testHandshakeChangeRootCAsResumption(t, VersionTLS13)
|
||||
})
|
||||
}
|
||||
|
||||
func testHandshakeChangeRootCAsResumption(t *testing.T, version uint16) {
|
||||
now := time.Now()
|
||||
tmpl := &x509.Certificate{
|
||||
Subject: pkix.Name{CommonName: "root"},
|
||||
NotBefore: now.Add(-time.Hour * 24),
|
||||
NotAfter: now.Add(time.Hour * 24),
|
||||
IsCA: true,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
rootDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
rootA, err := x509.ParseCertificate(rootDER)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseCertificate: %v", err)
|
||||
}
|
||||
rootDER, err = x509.CreateCertificate(rand.Reader, tmpl, tmpl, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
rootB, err := x509.ParseCertificate(rootDER)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseCertificate: %v", err)
|
||||
}
|
||||
|
||||
tmpl = &x509.Certificate{
|
||||
Subject: pkix.Name{},
|
||||
DNSNames: []string{"example.com"},
|
||||
NotBefore: now.Add(-time.Hour * 24),
|
||||
NotAfter: now.Add(time.Hour * 24),
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
}
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, tmpl, rootA, &testECDSAPrivateKey.PublicKey, testECDSAPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateCertificate: %v", err)
|
||||
}
|
||||
|
||||
serverConfig := testConfig.Clone()
|
||||
serverConfig.MaxVersion = version
|
||||
serverConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{certDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
serverConfig.Time = func() time.Time {
|
||||
return now.Add(1*time.Hour + 30*time.Minute)
|
||||
return now
|
||||
}
|
||||
serverConfig.ClientCAs = x509.NewCertPool()
|
||||
serverConfig.ClientCAs.AddCert(freshRoot)
|
||||
serverConfig.ClientCAs.AddCert(rootA)
|
||||
serverConfig.ClientAuth = RequireAndVerifyClientCert
|
||||
serverConfig.InsecureSkipVerify = false
|
||||
serverConfig.ServerName = "example.com"
|
||||
|
||||
clientConfig := testConfig.Clone()
|
||||
clientConfig.MaxVersion = version
|
||||
clientConfig.Certificates = []Certificate{{
|
||||
Certificate: [][]byte{certDER},
|
||||
PrivateKey: testECDSAPrivateKey,
|
||||
}}
|
||||
clientConfig.ClientSessionCache = NewLRUClientSessionCache(32)
|
||||
clientConfig.RootCAs = x509.NewCertPool()
|
||||
clientConfig.RootCAs.AddCert(rootA)
|
||||
clientConfig.Time = func() time.Time {
|
||||
return now
|
||||
}
|
||||
clientConfig.InsecureSkipVerify = false
|
||||
clientConfig.ServerName = "example.com"
|
||||
|
||||
testResume := func(t *testing.T, sc, cc *Config, expectResume bool) {
|
||||
t.Helper()
|
||||
ss, cs, err := testHandshake(t, cc, sc)
|
||||
if err != nil {
|
||||
t.Fatalf("handshake: %v", err)
|
||||
}
|
||||
if cs.DidResume != expectResume {
|
||||
t.Fatalf("DidResume = %v; want %v", cs.DidResume, expectResume)
|
||||
}
|
||||
if ss.DidResume != expectResume {
|
||||
t.Fatalf("DidResume = %v; want %v", cs.DidResume, expectResume)
|
||||
}
|
||||
}
|
||||
|
||||
testResume(t, serverConfig, clientConfig, false)
|
||||
testResume(t, serverConfig, clientConfig, true)
|
||||
|
||||
clientConfig = clientConfig.Clone()
|
||||
clientConfig.RootCAs = x509.NewCertPool()
|
||||
clientConfig.RootCAs.AddCert(rootB)
|
||||
|
||||
testResume(t, serverConfig, clientConfig, false)
|
||||
testResume(t, serverConfig, clientConfig, true)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"crypto/internal/hpke"
|
||||
"crypto/rsa"
|
||||
"crypto/tls/internal/fips140tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
@@ -354,7 +355,6 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
pskIdentityLoop:
|
||||
for i, identity := range hs.clientHello.pskIdentities {
|
||||
if i >= maxClientPSKIdentities {
|
||||
break
|
||||
@@ -407,16 +407,16 @@ pskIdentityLoop:
|
||||
if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
|
||||
continue
|
||||
}
|
||||
if sessionHasClientCerts {
|
||||
now := c.config.time()
|
||||
for _, c := range sessionState.peerCertificates {
|
||||
if now.After(c.NotAfter) {
|
||||
continue pskIdentityLoop
|
||||
}
|
||||
}
|
||||
if sessionHasClientCerts && c.config.time().After(sessionState.peerCertificates[0].NotAfter) {
|
||||
continue
|
||||
}
|
||||
opts := x509.VerifyOptions{
|
||||
CurrentTime: c.config.time(),
|
||||
Roots: c.config.ClientCAs,
|
||||
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
}
|
||||
if sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven &&
|
||||
len(sessionState.verifiedChains) == 0 {
|
||||
!anyValidVerifiedChain(sessionState.verifiedChains, opts) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -935,8 +935,8 @@ func TestCloneNonFuncFields(t *testing.T) {
|
||||
}
|
||||
}
|
||||
// Set the unexported fields related to session ticket keys, which are copied with Clone().
|
||||
c1.autoSessionTicketKeys = []ticketKey{c1.ticketKeyFromBytes(c1.SessionTicketKey)}
|
||||
c1.sessionTicketKeys = []ticketKey{c1.ticketKeyFromBytes(c1.SessionTicketKey)}
|
||||
// We explicitly don't copy autoSessionTicketKeys in Clone, so don't set it.
|
||||
|
||||
c2 := c1.Clone()
|
||||
if !reflect.DeepEqual(&c1, c2) {
|
||||
@@ -2347,12 +2347,3 @@ func TestECH(t *testing.T) {
|
||||
|
||||
check()
|
||||
}
|
||||
|
||||
func TestConfigCloneAutoSessionTicketKeys(t *testing.T) {
|
||||
orig := &Config{}
|
||||
orig.ticketKeys(nil)
|
||||
clone := orig.Clone()
|
||||
if slices.Equal(orig.autoSessionTicketKeys, clone.autoSessionTicketKeys) {
|
||||
t.Fatal("autoSessionTicketKeys slice copied in Clone")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1658,6 +1658,22 @@ var nameConstraintsTests = []nameConstraintsTest{
|
||||
},
|
||||
expectedError: "\"*.example.com\" is not permitted",
|
||||
},
|
||||
// #89: a TLD constraint doesn't exclude unrelated wildcards
|
||||
{
|
||||
roots: []constraintsSpec{
|
||||
{
|
||||
bad: []string{"dns:tld"},
|
||||
},
|
||||
},
|
||||
intermediates: [][]constraintsSpec{
|
||||
{
|
||||
{},
|
||||
},
|
||||
},
|
||||
leaf: leafSpec{
|
||||
sans: []string{"dns:*.example.com"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func makeConstraintsCACert(constraints constraintsSpec, name string, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) {
|
||||
|
||||
@@ -546,7 +546,7 @@ func matchDomainConstraint(domain, constraint string, excluded bool, reversedDom
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if excluded && wildcardDomain && len(domainLabels) > 1 && len(constraintLabels) > 0 {
|
||||
if excluded && wildcardDomain && len(domainLabels) > 1 && len(constraintLabels) > 1 {
|
||||
domainLabels = domainLabels[:len(domainLabels)-1]
|
||||
constraintLabels = constraintLabels[:len(constraintLabels)-1]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user