| 268 | } |
| 269 | |
| 270 | func (s *Server) getTrust(address string) (*x509.Certificate, error) { |
| 271 | if address == "" { |
| 272 | if s.trust != nil { |
| 273 | return s.trust, nil |
| 274 | } |
| 275 | return nil, errNoTrust.New() |
| 276 | } |
| 277 | _, host, port, err := parseAddress("https", address) |
| 278 | if err != nil { |
| 279 | return nil, err |
| 280 | } |
| 281 | address = net.JoinHostPort(host, port) |
| 282 | |
| 283 | trustI, err, _ := s.getTrustOnce.Do(address, func() (any, error) { |
| 284 | s.trustCacheMu.RLock() |
| 285 | trust, ok := s.trustCache[address] |
| 286 | s.trustCacheMu.RUnlock() |
| 287 | if ok { |
| 288 | return trust, nil |
| 289 | } |
| 290 | |
| 291 | conn, err := tls.DialWithDialer(&net.Dialer{ |
| 292 | Timeout: 5 * time.Second, |
| 293 | }, "tcp", address, s.tlsConfig) |
| 294 | if err != nil { |
| 295 | return nil, err |
| 296 | } |
| 297 | defer conn.Close() |
| 298 | if verifiedChains := conn.ConnectionState().VerifiedChains; len(verifiedChains) > 0 { |
| 299 | chain := verifiedChains[0] |
| 300 | trust = chain[len(chain)-1] |
| 301 | } |
| 302 | if s.tlsConfig != nil && s.tlsConfig.InsecureSkipVerify { |
| 303 | chain := conn.ConnectionState().PeerCertificates |
| 304 | trust = chain[len(chain)-1] |
| 305 | } |
| 306 | |
| 307 | if trust != nil { |
| 308 | s.trustCacheMu.Lock() |
| 309 | s.trustCache[address] = trust |
| 310 | s.trustCacheMu.Unlock() |
| 311 | return trust, nil |
| 312 | } |
| 313 | |
| 314 | return nil, errNoTrust.New() |
| 315 | }) |
| 316 | if err != nil { |
| 317 | return nil, err |
| 318 | } |
| 319 | return trustI.(*x509.Certificate), nil //nolint:revive |
| 320 | } |