| 229 | } |
| 230 | |
| 231 | func (o *Options) clientConfig() (*tls.Config, error) { |
| 232 | if o.VerificationType == SkipVerification && o.AdditionalPeerVerification == nil { |
| 233 | return nil, fmt.Errorf("client needs to provide custom verification mechanism if choose to skip default verification") |
| 234 | } |
| 235 | // Make sure users didn't specify more than one fields in |
| 236 | // RootCertificateOptions and IdentityCertificateOptions. |
| 237 | if num := o.RootOptions.nonNilFieldCount(); num > 1 { |
| 238 | return nil, fmt.Errorf("at most one field in RootCertificateOptions could be specified") |
| 239 | } |
| 240 | if num := o.IdentityOptions.nonNilFieldCount(); num > 1 { |
| 241 | return nil, fmt.Errorf("at most one field in IdentityCertificateOptions could be specified") |
| 242 | } |
| 243 | if o.IdentityOptions.GetIdentityCertificatesForServer != nil { |
| 244 | return nil, fmt.Errorf("GetIdentityCertificatesForServer cannot be specified on the client side") |
| 245 | } |
| 246 | if o.MinTLSVersion > o.MaxTLSVersion { |
| 247 | return nil, fmt.Errorf("the minimum TLS version is larger than the maximum TLS version") |
| 248 | } |
| 249 | // If the MinTLSVersion isn't set, default to 1.2 |
| 250 | if o.MinTLSVersion == 0 { |
| 251 | o.MinTLSVersion = tls.VersionTLS12 |
| 252 | } |
| 253 | // If the MaxTLSVersion isn't set, default to 1.3 |
| 254 | if o.MaxTLSVersion == 0 { |
| 255 | o.MaxTLSVersion = tls.VersionTLS13 |
| 256 | } |
| 257 | config := &tls.Config{ |
| 258 | ServerName: o.serverNameOverride, |
| 259 | // We have to set InsecureSkipVerify to true to skip the default checks and |
| 260 | // use the verification function we built from buildVerifyFunc. |
| 261 | InsecureSkipVerify: true, |
| 262 | MinVersion: o.MinTLSVersion, |
| 263 | MaxVersion: o.MaxTLSVersion, |
| 264 | CipherSuites: o.CipherSuites, |
| 265 | } |
| 266 | // Propagate root-certificate-related fields in tls.Config. |
| 267 | switch { |
| 268 | case o.RootOptions.RootCertificates != nil: |
| 269 | config.RootCAs = o.RootOptions.RootCertificates |
| 270 | case o.RootOptions.GetRootCertificates != nil: |
| 271 | // In cases when users provide GetRootCertificates callback, since this |
| 272 | // callback is not contained in tls.Config, we have nothing to set here. |
| 273 | // We will invoke the callback in ClientHandshake. |
| 274 | case o.RootOptions.RootProvider != nil: |
| 275 | o.RootOptions.GetRootCertificates = func(*ConnectionInfo) (*RootCertificates, error) { |
| 276 | km, err := o.RootOptions.RootProvider.KeyMaterial(context.Background()) |
| 277 | if err != nil { |
| 278 | return nil, err |
| 279 | } |
| 280 | return &RootCertificates{TrustCerts: km.Roots}, nil |
| 281 | } |
| 282 | default: |
| 283 | // No root certificate options specified by user. Use the certificates |
| 284 | // stored in system default path as the last resort. |
| 285 | if o.VerificationType != SkipVerification { |
| 286 | systemRootCAs, err := x509.SystemCertPool() |
| 287 | if err != nil { |
| 288 | return nil, err |