...
1
18
19
20
21
22 package credentials
23
24 import (
25 "crypto/tls"
26 "crypto/x509"
27 "net/url"
28
29 "google.golang.org/grpc/grpclog"
30 )
31
32 var logger = grpclog.Component("credentials")
33
34
35
36 func SPIFFEIDFromState(state tls.ConnectionState) *url.URL {
37 if len(state.PeerCertificates) == 0 || len(state.PeerCertificates[0].URIs) == 0 {
38 return nil
39 }
40 return SPIFFEIDFromCert(state.PeerCertificates[0])
41 }
42
43
44
45 func SPIFFEIDFromCert(cert *x509.Certificate) *url.URL {
46 if cert == nil || cert.URIs == nil {
47 return nil
48 }
49 var spiffeID *url.URL
50 for _, uri := range cert.URIs {
51 if uri == nil || uri.Scheme != "spiffe" || uri.Opaque != "" || (uri.User != nil && uri.User.Username() != "") {
52 continue
53 }
54
55 if len(uri.String()) > 2048 {
56 logger.Warning("invalid SPIFFE ID: total ID length larger than 2048 bytes")
57 return nil
58 }
59 if len(uri.Host) == 0 || len(uri.Path) == 0 {
60 logger.Warning("invalid SPIFFE ID: domain or workload ID is empty")
61 return nil
62 }
63 if len(uri.Host) > 255 {
64 logger.Warning("invalid SPIFFE ID: domain length larger than 255 characters")
65 return nil
66 }
67
68 if len(cert.URIs) > 1 {
69 logger.Warning("invalid SPIFFE ID: multiple URI SANs")
70 return nil
71 }
72 spiffeID = uri
73 }
74 return spiffeID
75 }
76
View as plain text