mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2026-03-06 22:29:55 +00:00
chore: fingerprint verifier handle non-leaf certificate will check the SNI matches the certificate's DNS name
This commit is contained in:
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
// NewFingerprintVerifier returns a function that verifies whether a certificate's SHA-256 fingerprint matches the given one.
|
||||
func NewFingerprintVerifier(fingerprint string, time func() time.Time) (func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error, error) {
|
||||
func NewFingerprintVerifier(fingerprint string, time func() time.Time) (func(certs []*x509.Certificate, serverName string) error, error) {
|
||||
switch fingerprint {
|
||||
case "chrome", "firefox", "safari", "ios", "android", "edge", "360", "qq", "random", "randomized": // WTF???
|
||||
return nil, fmt.Errorf("`fingerprint` is used for TLS certificate pinning. If you need to specify the browser fingerprint, use `client-fingerprint`")
|
||||
@@ -26,37 +26,24 @@ func NewFingerprintVerifier(fingerprint string, time func() time.Time) (func(raw
|
||||
return nil, fmt.Errorf("fingerprint string length error,need sha256 fingerprint")
|
||||
}
|
||||
|
||||
return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
|
||||
return func(certs []*x509.Certificate, serverName string) error {
|
||||
// ssl pining
|
||||
for i, rawCert := range rawCerts {
|
||||
hash := sha256.Sum256(rawCert)
|
||||
for i, cert := range certs {
|
||||
hash := sha256.Sum256(cert.Raw)
|
||||
if bytes.Equal(fpByte, hash[:]) {
|
||||
if i > 0 {
|
||||
|
||||
// When the fingerprint matches a non-leaf certificate,
|
||||
// the certificate chain validity is verified using the certificate as the trusted root certificate.
|
||||
//
|
||||
// Currently, we do not verify that the SNI matches the certificate's DNS name,
|
||||
// but we do verify the validity of the child certificate,
|
||||
// including the issuance time and whether the child certificate was issued by the parent certificate.
|
||||
|
||||
certs := make([]*x509.Certificate, i+1) // stop at i
|
||||
for j := range certs {
|
||||
cert, err := x509.ParseCertificate(rawCerts[j])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
certs[j] = cert
|
||||
}
|
||||
opts := x509.VerifyOptions{
|
||||
Roots: x509.NewCertPool(),
|
||||
Intermediates: x509.NewCertPool(),
|
||||
DNSName: serverName,
|
||||
}
|
||||
if time != nil {
|
||||
opts.CurrentTime = time()
|
||||
}
|
||||
opts.Roots.AddCert(certs[i])
|
||||
for _, cert := range certs[1:] {
|
||||
for _, cert := range certs[1 : i+1] { // stop at i
|
||||
opts.Intermediates.AddCert(cert)
|
||||
}
|
||||
_, err := certs[0].Verify(opts)
|
||||
|
||||
Reference in New Issue
Block a user