feat(签名验签): 优化签名验签
build.yaml / build (push) Successful in 37s

This commit is contained in:
2026-07-10 19:46:44 +08:00
parent c20d3dd246
commit 19fadab4ad
+26 -9
View File
@@ -594,9 +594,9 @@ func (report *SignatureVerifyReport) applySignatureCertificatePolicy(options *si
if len(options.TrustCerts) != 0 { if len(options.TrustCerts) != 0 {
report.CertTrustChecked = true report.CertTrustChecked = true
report.CertTrustOK = true report.CertTrustOK = true
pool := append([][]byte{}, options.SignCerts...) pool := append([][]byte{}, options.TrustCerts...)
pool = append(pool, options.SignCerts...)
pool = append(pool, extraCerts...) pool = append(pool, extraCerts...)
pool = append(pool, options.TrustCerts...)
pool = compactSignatureCerts(pool) pool = compactSignatureCerts(pool)
for _, cert := range certs { for _, cert := range certs {
if !signatureCertTrustedBy(cert, pool, options.TrustCerts, options.VerifyTime) { if !signatureCertTrustedBy(cert, pool, options.TrustCerts, options.VerifyTime) {
@@ -638,17 +638,27 @@ func signatureCertsValidAt(certs [][]byte, t time.Time) bool {
return true return true
} }
// signatureCertMaxChecks 最大证书签名验证次数
const signatureCertMaxChecks = 100
// signatureCertPathState 证书路径状态
type signatureCertPathState struct {
Visited map[string]bool
SignatureChecks int
}
// signatureCertTrustedBy 判断证书是否可链到信任证书 // signatureCertTrustedBy 判断证书是否可链到信任证书
// 入参: cert 证书, pool 证书池, trusts 信任证书, verifyTime 中间证书验证时间 // 入参: cert 证书, pool 证书池, trusts 信任证书, verifyTime 中间证书验证时间
// 返回: bool 是否受信任 // 返回: bool 是否受信任
func signatureCertTrustedBy(cert []byte, pool, trusts [][]byte, verifyTime *time.Time) bool { func signatureCertTrustedBy(cert []byte, pool, trusts [][]byte, verifyTime *time.Time) bool {
return signatureCertPathTrustedBy(cert, pool, trusts, verifyTime, make(map[string]bool), 0, true) state := signatureCertPathState{Visited: make(map[string]bool)}
return signatureCertPathTrustedBy(cert, pool, trusts, verifyTime, &state, 0, true)
} }
// signatureCertPathTrustedBy 验证证书路径 // signatureCertPathTrustedBy 验证证书路径
// 入参: cert 证书, pool 证书池, trusts 信任证书, verifyTime 中间证书验证时间, visited 当前路径证书, caBelow 下级非自颁发中间CA数量, target 是否目标证书 // 入参: cert 证书, pool 证书池, trusts 信任证书, verifyTime 中间证书验证时间, state 路径状态, caBelow 下级非自颁发中间CA数量, target 是否目标证书
// 返回: bool 是否受信任 // 返回: bool 是否受信任
func signatureCertPathTrustedBy(cert []byte, pool, trusts [][]byte, verifyTime *time.Time, visited map[string]bool, caBelow int, target bool) bool { func signatureCertPathTrustedBy(cert []byte, pool, trusts [][]byte, verifyTime *time.Time, state *signatureCertPathState, caBelow int, target bool) bool {
if len(cert) == 0 { if len(cert) == 0 {
return false return false
} }
@@ -663,11 +673,11 @@ func signatureCertPathTrustedBy(cert []byte, pool, trusts [][]byte, verifyTime *
return true return true
} }
key := string(cert) key := string(cert)
if visited[key] { if state.Visited[key] {
return false return false
} }
visited[key] = true state.Visited[key] = true
defer delete(visited, key) defer delete(state.Visited, key)
c, err := parseSignatureCertificate(cert) c, err := parseSignatureCertificate(cert)
if err != nil { if err != nil {
return false return false
@@ -701,6 +711,9 @@ func signatureCertPathTrustedBy(cert []byte, pool, trusts [][]byte, verifyTime *
nextCABelow++ nextCABelow++
} }
for _, issuerCert := range pool { for _, issuerCert := range pool {
if state.SignatureChecks >= signatureCertMaxChecks {
return false
}
if bytes.Equal(cert, issuerCert) { if bytes.Equal(cert, issuerCert) {
continue continue
} }
@@ -708,10 +721,11 @@ func signatureCertPathTrustedBy(cert []byte, pool, trusts [][]byte, verifyTime *
if err != nil || !bytes.Equal(c.Issuer, issuer.Subject) { if err != nil || !bytes.Equal(c.Issuer, issuer.Subject) {
continue continue
} }
state.SignatureChecks++
if ok, err := verifyCertificateSignature(c, issuerCert); err != nil || !ok { if ok, err := verifyCertificateSignature(c, issuerCert); err != nil || !ok {
continue continue
} }
if signatureCertPathTrustedBy(issuerCert, pool, trusts, verifyTime, visited, nextCABelow, false) { if signatureCertPathTrustedBy(issuerCert, pool, trusts, verifyTime, state, nextCABelow, false) {
return true return true
} }
} }
@@ -830,6 +844,9 @@ func parseSignatureCertificate(data []byte) (signatureCertificate, error) {
if len(items) <= idx+5 { if len(items) <= idx+5 {
return signatureCertificate{}, fmt.Errorf("invalid certificate") return signatureCertificate{}, fmt.Errorf("invalid certificate")
} }
if !bytes.Equal(items[idx+1].FullBytes, cert.SignatureAlgorithm.FullBytes) {
return signatureCertificate{}, fmt.Errorf("certificate signature algorithm mismatch")
}
serial, err := asn1IntegerBig(items[idx]) serial, err := asn1IntegerBig(items[idx])
if err != nil { if err != nil {
return signatureCertificate{}, err return signatureCertificate{}, err