Skip to content

Commit b5c1b07

Browse files
committed
Fix public key verification
1 parent 7e9a58d commit b5c1b07

File tree

1 file changed

+12
-55
lines changed

1 file changed

+12
-55
lines changed

common/tls/std_client.go

Lines changed: 12 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"github.com/sagernet/sing-box/common/tlsfragment"
1717
C "github.com/sagernet/sing-box/constant"
1818
"github.com/sagernet/sing-box/option"
19-
"github.com/sagernet/sing/common"
2019
E "github.com/sagernet/sing/common/exceptions"
2120
"github.com/sagernet/sing/common/logger"
2221
"github.com/sagernet/sing/common/ntp"
@@ -198,62 +197,20 @@ func NewSTDClient(ctx context.Context, logger logger.ContextLogger, serverAddres
198197
}
199198

200199
func verifyPublicKeySHA256(knownHashValues [][]byte, rawCerts [][]byte, timeFunc func() time.Time) error {
201-
for i, rawCert := range rawCerts {
202-
certificate, err := x509.ParseCertificate(rawCert)
203-
if err != nil {
204-
continue
205-
}
206-
207-
// Extract public key and hash it
208-
pubKeyBytes, err := x509.MarshalPKIXPublicKey(certificate.PublicKey)
209-
if err != nil {
210-
continue
211-
}
212-
hash := sha256.Sum256(pubKeyBytes)
213-
214-
var matched bool
215-
for _, value := range knownHashValues {
216-
if bytes.Equal(value, hash[:]) {
217-
matched = true
218-
break
219-
}
220-
}
221-
if !matched {
222-
continue
223-
}
224-
if i == 0 {
225-
return nil
226-
}
227-
certificates := make([]*x509.Certificate, i+1)
228-
for j := range certificates {
229-
certificate, err := x509.ParseCertificate(rawCerts[j])
230-
if err != nil {
231-
return err
232-
}
233-
certificates[j] = certificate
234-
}
235-
verifyOptions := x509.VerifyOptions{
236-
Roots: x509.NewCertPool(),
237-
Intermediates: x509.NewCertPool(),
238-
}
239-
if timeFunc != nil {
240-
verifyOptions.CurrentTime = timeFunc()
241-
}
242-
verifyOptions.Roots.AddCert(certificates[i])
243-
for _, certificate := range certificates[1:] {
244-
verifyOptions.Intermediates.AddCert(certificate)
245-
}
246-
return common.Error(certificates[0].Verify(verifyOptions))
200+
leafCertificate, err := x509.ParseCertificate(rawCerts[0])
201+
if err != nil {
202+
return E.Cause(err, "failed to parse leaf certificate")
247203
}
248204

249-
// Generate error message with first certificate's public key hash
250-
if len(rawCerts) > 0 {
251-
if certificate, err := x509.ParseCertificate(rawCerts[0]); err == nil {
252-
if pubKeyBytes, err := x509.MarshalPKIXPublicKey(certificate.PublicKey); err == nil {
253-
hash := sha256.Sum256(pubKeyBytes)
254-
return E.New("unrecognized public key: ", base64.StdEncoding.EncodeToString(hash[:]))
255-
}
205+
pubKeyBytes, err := x509.MarshalPKIXPublicKey(leafCertificate.PublicKey)
206+
if err != nil {
207+
return E.Cause(err, "failed to marshal public key")
208+
}
209+
hashValue := sha256.Sum256(pubKeyBytes)
210+
for _, value := range knownHashValues {
211+
if bytes.Equal(value, hashValue[:]) {
212+
return nil
256213
}
257214
}
258-
return E.New("unrecognized certificate")
215+
return E.New("unrecognized remote public key: ", base64.StdEncoding.EncodeToString(hashValue[:]))
259216
}

0 commit comments

Comments
 (0)