@@ -22,6 +22,7 @@ package jwkscache
22
22
import (
23
23
"context"
24
24
"crypto/tls"
25
+ "crypto/x509"
25
26
"encoding/base64"
26
27
"errors"
27
28
"fmt"
@@ -38,6 +39,7 @@ import (
38
39
39
40
"github.com/dapr/kit/fswatcher"
40
41
"github.com/dapr/kit/logger"
42
+ "github.com/dapr/kit/utils"
41
43
)
42
44
43
45
const (
@@ -49,11 +51,11 @@ const (
49
51
50
52
// JWKSCache is a cache of JWKS objects.
51
53
// It fetches a JWKS object from a file on disk, a URL, or from a value passed as-is.
52
- // TODO: Move this to dapr/kit and use it for the JWKS crypto component too
53
54
type JWKSCache struct {
54
55
location string
55
56
requestTimeout time.Duration
56
57
minRefreshInterval time.Duration
58
+ caCertificate string
57
59
58
60
jwks jwk.Set
59
61
logger logger.Logger
@@ -113,6 +115,12 @@ func (c *JWKSCache) SetMinRefreshInterval(minRefreshInterval time.Duration) {
113
115
c .minRefreshInterval = minRefreshInterval
114
116
}
115
117
118
+ // SetCACertificate sets the CA certificate to trust.
119
+ // Can be a path to a local file or an actual, PEM-encoded certificate
120
+ func (c * JWKSCache ) SetCACertificate (caCertificate string ) {
121
+ c .caCertificate = caCertificate
122
+ }
123
+
116
124
// SetHTTPClient sets the HTTP client object to use.
117
125
func (c * JWKSCache ) SetHTTPClient (client * http.Client ) {
118
126
c .client = client
@@ -184,12 +192,28 @@ func (c *JWKSCache) initJWKSFromURL(ctx context.Context, url string) error {
184
192
185
193
// We also need to create a custom HTTP client (if we don't have one already) because otherwise there's no timeout.
186
194
if c .client == nil {
195
+ tlsConfig := & tls.Config {
196
+ MinVersion : tls .VersionTLS12 ,
197
+ }
198
+
199
+ // Load CA certificates if we have one
200
+ if c .caCertificate != "" {
201
+ caCert , err := utils .GetPEM (c .caCertificate )
202
+ if err != nil {
203
+ return fmt .Errorf ("failed to load CA certificate: %w" , err )
204
+ }
205
+
206
+ caCertPool := x509 .NewCertPool ()
207
+ if ! caCertPool .AppendCertsFromPEM (caCert ) {
208
+ return errors .New ("failed to add root certificate to certificate pool" )
209
+ }
210
+ tlsConfig .RootCAs = caCertPool
211
+ }
212
+
187
213
c .client = & http.Client {
188
214
Timeout : c .requestTimeout ,
189
215
Transport : & http.Transport {
190
- TLSClientConfig : & tls.Config {
191
- MinVersion : tls .VersionTLS12 ,
192
- },
216
+ TLSClientConfig : tlsConfig ,
193
217
},
194
218
}
195
219
}
0 commit comments