Skip to content

Commit e704589

Browse files
authored
TLS client: Verify leaf cert (name, time) when pinning self-signed CA (XTLS#5532)
XTLS#5154 (comment)
1 parent 463915c commit e704589

1 file changed

Lines changed: 30 additions & 15 deletions

File tree

transport/internet/tls/config.go

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,10 @@ func (r *RandCarrier) verifyPeerCert(rawCerts [][]byte, verifiedChains [][]*x509
290290
// directly return success if pinned cert is leaf
291291
// or add the CA to RootCAs if pinned cert is CA(and can be used in VerifyPeerCertInNames for Self signed CA)
292292
RootCAs := r.RootCAs
293+
var verifyResult verifyResult
294+
var verifiedCert *x509.Certificate
293295
if r.PinnedPeerCertSha256 != nil {
294-
verifyResult, verifiedCert := verifyChain(certs, r.PinnedPeerCertSha256)
296+
verifyResult, verifiedCert = verifyChain(certs, r.PinnedPeerCertSha256)
295297
switch verifyResult {
296298
case certNotFound:
297299
return errors.New("peer cert is unrecognized")
@@ -305,27 +307,39 @@ func (r *RandCarrier) verifyPeerCert(rawCerts [][]byte, verifiedChains [][]*x509
305307
}
306308
}
307309

308-
if r.VerifyPeerCertInNames != nil {
309-
if len(r.VerifyPeerCertInNames) > 0 {
310-
opts := x509.VerifyOptions{
311-
Roots: RootCAs,
312-
CurrentTime: time.Now(),
313-
Intermediates: x509.NewCertPool(),
314-
}
315-
for _, cert := range certs[1:] {
316-
opts.Intermediates.AddCert(cert)
317-
}
318-
for _, opts.DNSName = range r.VerifyPeerCertInNames {
319-
if _, err := certs[0].Verify(opts); err == nil {
320-
return nil
321-
}
310+
if len(r.VerifyPeerCertInNames) > 0 {
311+
opts := x509.VerifyOptions{
312+
Roots: RootCAs,
313+
CurrentTime: time.Now(),
314+
Intermediates: x509.NewCertPool(),
315+
}
316+
for _, cert := range certs[1:] {
317+
opts.Intermediates.AddCert(cert)
318+
}
319+
for _, opts.DNSName = range r.VerifyPeerCertInNames {
320+
if _, err := certs[0].Verify(opts); err == nil {
321+
return nil
322322
}
323323
}
324+
} else if len(verifiedChains) == 0 && verifyResult == foundCA { // if found ca and verifiedChains is empty, we need to verify here
325+
opts := x509.VerifyOptions{
326+
Roots: RootCAs,
327+
CurrentTime: time.Now(),
328+
Intermediates: x509.NewCertPool(),
329+
DNSName: r.Config.ServerName,
330+
}
331+
for _, cert := range certs[1:] {
332+
opts.Intermediates.AddCert(cert)
333+
}
334+
if _, err := certs[0].Verify(opts); err == nil {
335+
return nil
336+
}
324337
}
325338
return nil
326339
}
327340

328341
type RandCarrier struct {
342+
Config *tls.Config
329343
RootCAs *x509.CertPool
330344
VerifyPeerCertInNames []string
331345
PinnedPeerCertSha256 [][]byte
@@ -366,6 +380,7 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
366380
SessionTicketsDisabled: !c.EnableSessionResumption,
367381
VerifyPeerCertificate: randCarrier.verifyPeerCert,
368382
}
383+
randCarrier.Config = config
369384
if len(c.VerifyPeerCertInNames) > 0 {
370385
config.InsecureSkipVerify = true
371386
} else {

0 commit comments

Comments
 (0)