...
1
18
19
20
21 package tlscreds
22
23 import (
24 "context"
25 "crypto/tls"
26 "encoding/json"
27 "errors"
28 "fmt"
29 "net"
30
31 "google.golang.org/grpc/credentials"
32 "google.golang.org/grpc/credentials/tls/certprovider"
33 "google.golang.org/grpc/credentials/tls/certprovider/pemfile"
34 "google.golang.org/grpc/internal/grpcsync"
35 )
36
37
38
39 type bundle struct {
40 transportCredentials credentials.TransportCredentials
41 }
42
43
44
45
46
47
48
49 func NewBundle(jd json.RawMessage) (credentials.Bundle, func(), error) {
50 cfg := &struct {
51 CertificateFile string `json:"certificate_file"`
52 CACertificateFile string `json:"ca_certificate_file"`
53 PrivateKeyFile string `json:"private_key_file"`
54 }{}
55
56 if jd != nil {
57 if err := json.Unmarshal(jd, cfg); err != nil {
58 return nil, nil, fmt.Errorf("failed to unmarshal config: %v", err)
59 }
60 }
61
62 if cfg.CACertificateFile == "" && cfg.CertificateFile == "" && cfg.PrivateKeyFile == "" {
63
64
65
66
67
68
69
70
71
72 return &bundle{transportCredentials: credentials.NewTLS(&tls.Config{})}, func() {}, nil
73 }
74
75
76
77
78 provider, err := certprovider.GetProvider(pemfile.PluginName, jd, certprovider.BuildOptions{})
79 if err != nil {
80 return nil, nil, err
81 }
82 return &bundle{
83 transportCredentials: &reloadingCreds{provider: provider},
84 }, grpcsync.OnceFunc(func() { provider.Close() }), nil
85 }
86
87 func (t *bundle) TransportCredentials() credentials.TransportCredentials {
88 return t.transportCredentials
89 }
90
91 func (t *bundle) PerRPCCredentials() credentials.PerRPCCredentials {
92
93
94 return nil
95 }
96
97 func (t *bundle) NewWithMode(string) (credentials.Bundle, error) {
98
99
100 return nil, fmt.Errorf("xDS TLS credentials only support one mode")
101 }
102
103
104
105
106
107
108 type reloadingCreds struct {
109 provider certprovider.Provider
110 }
111
112 func (c *reloadingCreds) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
113 km, err := c.provider.KeyMaterial(ctx)
114 if err != nil {
115 return nil, nil, err
116 }
117 config := &tls.Config{
118 RootCAs: km.Roots,
119 Certificates: km.Certs,
120 }
121 return credentials.NewTLS(config).ClientHandshake(ctx, authority, rawConn)
122 }
123
124 func (c *reloadingCreds) Info() credentials.ProtocolInfo {
125 return credentials.ProtocolInfo{SecurityProtocol: "tls"}
126 }
127
128 func (c *reloadingCreds) Clone() credentials.TransportCredentials {
129 return &reloadingCreds{provider: c.provider}
130 }
131
132 func (c *reloadingCreds) OverrideServerName(string) error {
133 return errors.New("overriding server name is not supported by xDS client TLS credentials")
134 }
135
136 func (c *reloadingCreds) ServerHandshake(net.Conn) (net.Conn, credentials.AuthInfo, error) {
137 return nil, nil, errors.New("server handshake is not supported by xDS client TLS credentials")
138 }
139
View as plain text