简单总结
参考https://github.com/spiffe/spiffe/blob/main/standards/X509-SVID.md
spiffe中svid用于身份认证,而其中的spiffeid用于权限认证
以x509svid为例,x509证书中的uri即为spiffeid
服务端/客户端从证书中解析出spiffeid,然后根据spiffeid进行权限认证
源码
v2/spiffetls/listen.go中
初始化listener
func NewListener(ctx context.Context, inner net.Listener, authorizer tlsconfig.Authorizer, options ...ListenOption) (net.Listener, error) {
return NewListenerWithMode(ctx, inner, MTLSServer(authorizer), options...)
}
根据mode初始化listener
func NewListenerWithMode(ctx context.Context, inner net.Listener, mode ListenMode, options ...ListenOption) (_ net.Listener, err error) {
...
switch m.mode {
...
以mtlsServerMode为例
case mtlsServerMode:
hook tlsconfig
tlsconfig.HookMTLSServerConfig(tlsConfig, m.svid, m.bundle, m.authorizer, opt.tlsOptions...)
...
}
...
}
v2/spiffetls/tlsconfig/config.go中
hook tlsconfig
func HookMTLSServerConfig(config *tls.Config, svid x509svid.Source, bundle x509bundle.Source, authorizer Authorizer, opts ...Option) {
resetAuthFields(config)
config.ClientAuth = tls.RequireAnyClientCert
config.GetCertificate = GetCertificate(svid, opts...)
验证客户端证书
config.VerifyPeerCertificate = WrapVerifyPeerCertificate(config.VerifyPeerCertificate, bundle, authorizer, opts...)
}
包装tlsconfig中的VerifyPeerCertificate返回新的VerifyPeerCertificate
func WrapVerifyPeerCertificate(wrapped func([][]byte, [][]*x509.Certificate) error, bundle x509bundle.Source, authorizer Authorizer, opts ...Option) func([][]byte, [][]*x509.Certificate) error {
...
以tlsconfig中的VerifyPeerCertificate为空为例
if wrapped == nil {
验证客户端证书
return VerifyPeerCertificate(bundle, authorizer, opts...)
}
...
}
验证客户端证书
func VerifyPeerCertificate(bundle x509bundle.Source, authorizer Authorizer, opts ...Option) func([][]byte, [][]*x509.Certificate) error {
return func(raw [][]byte, _ [][]*x509.Certificate) error {
解析出id和验证certs
id, certs, err := x509svid.ParseAndVerify(raw, bundle)
if err != nil {
return err
}
验证id和certs是否有权限
return authorizer(id, certs)
}
}
v2/svid/x509svid/verify.go中
解析出id和验证certs
func ParseAndVerify(rawCerts [][]byte, bundleSource x509bundle.Source, opts ...VerifyOption) (spiffeid.ID, [][]*x509.Certificate, error) {
var certs []*x509.Certificate
for _, rawCert := range rawCerts {
解析出cert
cert, err := x509.ParseCertificate(rawCert)
if err != nil {
return spiffeid.ID{}, nil, x509svidErr.New("unable to parse certificate: %w", err)
}
certs = append(certs, cert)
}
return Verify(certs, bundleSource, opts...)
}
解析出id和验证certs
func Verify(certs []*x509.Certificate, bundleSource x509bundle.Source, opts ...VerifyOption) (spiffeid.ID, [][]*x509.Certificate, error) {
...
解析出id
id, err := IDFromCert(leaf)
if err != nil {
return spiffeid.ID{}, nil, x509svidErr.New("could not get leaf SPIFFE ID: %w", err)
}
...
验证证书
verifiedChains, err := leaf.Verify(x509.VerifyOptions{
Roots: x509util.NewCertPool(bundle.X509Authorities()),
Intermediates: x509util.NewCertPool(certs[1:]),
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
CurrentTime: config.now,
})
}
从cert中解析出id
func IDFromCert(cert *x509.Certificate) (spiffeid.ID, error) {
...
从cert的URIs中中解析出id
return spiffeid.FromURI(cert.URIs[0])
}