豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit b459cee

Browse files
RPRXFangliding
authored andcommitted
TLS client: Skip TLS' built-in verification when using pinnedPeerCertSha256
#5532 (comment) #5532 (comment)
1 parent d75b33a commit b459cee

File tree

1 file changed

+23
-20
lines changed

1 file changed

+23
-20
lines changed

transport/internet/tls/config.go

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -281,58 +281,64 @@ func (c *Config) parseServerName() string {
281281
}
282282

283283
func (r *RandCarrier) verifyPeerCert(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) (err error) {
284-
// extract x509 certificates from rawCerts(verifiedChains will be nil if InsecureSkipVerify is true)
284+
// extract x509 certificates from rawCerts (verifiedChains will be nil if InsecureSkipVerify is true)
285285
certs := make([]*x509.Certificate, len(rawCerts))
286286
for i, asn1Data := range rawCerts {
287287
certs[i], _ = x509.ParseCertificate(asn1Data)
288288
}
289+
if len(certs) == 0 {
290+
return errors.New("unexpected certs")
291+
}
292+
if certs[0].IsCA {
293+
slices.Reverse(certs)
294+
}
289295

290296
// directly return success if pinned cert is leaf
291-
// or add the CA to RootCAs if pinned cert is CA(and can be used in VerifyPeerCertInNames for Self signed CA)
292-
RootCAs := r.RootCAs
297+
// or replace RootCAs if pinned cert is CA (and can be used in VerifyPeerCertInNames)
298+
CAs := r.RootCAs
293299
var verifyResult verifyResult
294300
var verifiedCert *x509.Certificate
295-
if r.PinnedPeerCertSha256 != nil {
301+
if len(r.PinnedPeerCertSha256) > 0 {
296302
verifyResult, verifiedCert = verifyChain(certs, r.PinnedPeerCertSha256)
297303
switch verifyResult {
298304
case certNotFound:
299305
return errors.New("peer cert is unrecognized")
300306
case foundLeaf:
301307
return nil
302308
case foundCA:
303-
RootCAs = x509.NewCertPool()
304-
RootCAs.AddCert(verifiedCert)
309+
CAs = x509.NewCertPool()
310+
CAs.AddCert(verifiedCert)
305311
default:
306-
panic("impossible PinnedPeerCertificateSha256 verify result")
312+
panic("impossible pinnedPeerCertSha256 verify result")
307313
}
308314
}
309315

310316
if len(r.VerifyPeerCertInNames) > 0 {
311317
opts := x509.VerifyOptions{
312-
Roots: RootCAs,
318+
Roots: CAs,
313319
CurrentTime: time.Now(),
314320
Intermediates: x509.NewCertPool(),
315321
}
316322
for _, cert := range certs[1:] {
317323
opts.Intermediates.AddCert(cert)
318324
}
319325
for _, opts.DNSName = range r.VerifyPeerCertInNames {
320-
if _, err := certs[0].Verify(opts); err == nil {
321-
return nil
326+
if _, err := certs[0].Verify(opts); err != nil {
327+
return errors.New("peer cert is unrecognized")
322328
}
323329
}
324-
} else if len(verifiedChains) == 0 && verifyResult == foundCA { // if found ca and verifiedChains is empty, we need to verify here
330+
} else if verifyResult == foundCA { // if found CA, we need to verify here
325331
opts := x509.VerifyOptions{
326-
Roots: RootCAs,
332+
Roots: CAs,
327333
CurrentTime: time.Now(),
328334
Intermediates: x509.NewCertPool(),
329335
DNSName: r.Config.ServerName,
330336
}
331337
for _, cert := range certs[1:] {
332338
opts.Intermediates.AddCert(cert)
333339
}
334-
if _, err := certs[0].Verify(opts); err == nil {
335-
return nil
340+
if _, err := certs[0].Verify(opts); err != nil {
341+
return errors.New("peer cert is unrecognized")
336342
}
337343
}
338344
return nil
@@ -381,10 +387,8 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
381387
VerifyPeerCertificate: randCarrier.verifyPeerCert,
382388
}
383389
randCarrier.Config = config
384-
if len(c.VerifyPeerCertInNames) > 0 {
390+
if len(c.VerifyPeerCertInNames) > 0 || len(c.PinnedPeerCertSha256) > 0 {
385391
config.InsecureSkipVerify = true
386-
} else {
387-
randCarrier.VerifyPeerCertInNames = nil
388392
}
389393

390394
for _, opt := range opts {
@@ -540,17 +544,16 @@ const (
540544
foundCA
541545
)
542546

543-
func verifyChain(certs []*x509.Certificate, PinnedPeerCertificateSha256 [][]byte) (verifyResult, *x509.Certificate) {
547+
func verifyChain(certs []*x509.Certificate, pinnedPeerCertSha256 [][]byte) (verifyResult, *x509.Certificate) {
544548
for _, cert := range certs {
545549
certHash := GenerateCertHash(cert)
546-
for _, c := range PinnedPeerCertificateSha256 {
550+
for _, c := range pinnedPeerCertSha256 {
547551
if hmac.Equal(certHash, c) {
548552
if cert.IsCA {
549553
return foundCA, cert
550554
} else {
551555
return foundLeaf, cert
552556
}
553-
554557
}
555558
}
556559
}

0 commit comments

Comments
 (0)