Scert/backend/internal/certificate/trust.go

55 lines
1.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package certificate
import (
"context"
"crypto/x509"
"embed"
"fmt"
"strings"
)
// 测试根仅供 ACME 测试签发结果校验,不加入系统、HTTP 客户端或正式环境信任库。
//
//go:embed trust/*.pem
var stagingTrust embed.FS
func acmeTrustRoots(environment string) (*x509.CertPool, error) {
switch strings.ToLower(strings.TrimSpace(environment)) {
case "production":
return nil, nil
case "staging":
roots := x509.NewCertPool()
entries, err := stagingTrust.ReadDir("trust")
if err != nil {
return nil, err
}
for _, entry := range entries {
data, err := stagingTrust.ReadFile("trust/" + entry.Name())
if err != nil || !roots.AppendCertsFromPEM(data) {
return nil, fmt.Errorf("内置 ACME 测试根证书无效:%s", entry.Name())
}
}
return roots, nil
default:
return nil, fmt.Errorf("ACME 环境无效:%s", environment)
}
}
func (s *Service) validateACMEResource(ctx context.Context, resource Resource, domains []string, environment string) error {
roots, err := acmeTrustRoots(environment)
if err != nil {
return err
}
if s.acmeRoots != nil {
roots = s.acmeRoots
}
chain := append([]byte(nil), resource.Certificate...)
chain = append(chain, resource.IssuerCertificate...)
// 即使签发器未返回单独的 issuer 字段,也必须验证完整信任链。
_, err = (LocalValidator{Roots: roots, VerifyChain: true}).ValidatePEM(ctx, chain, domains)
if err != nil {
return fmt.Errorf("ACME %s 证书信任链校验失败:%w", environment, err)
}
return nil
}