code: func GetRemoteCA(ctx context.Context, d digest.Digest, connBroker *connectionbroker.Broker) (RootCA, error) {
  	// This TLS Config is intentionally using InsecureSkipVerify. We use the
  	// digest instead to check the integrity of the CA certificate.
  	insecureCreds := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})
  	conn, err := getGRPCConnection(insecureCreds, connBroker, false)
  	if err != nil {
  		return RootCA{}, err
  	}
  
  	client := api.NewCAClient(conn.ClientConn)
  	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
  	defer cancel()
  	defer func() {
  		conn.Close(err == nil)
  	}()
  	response, err := client.GetRootCACertificate(ctx, &api.GetRootCACertificateRequest{})
  	if err != nil {
  		return RootCA{}, err
  	}
  
  	// If a bundle of certificates are provided, the digest covers the entire bundle and not just
  	// one of the certificates in the bundle.  Otherwise, a node can be MITMed while joining if
  	// the MITM CA provides a single certificate which matches the digest, and providing arbitrary
  	// other non-verified root certs that the manager certificate actually chains up to.
  	if d != "" {
  		verifier := d.Verifier()
  		if err != nil {
  			return RootCA{}, errors.Wrap(err, "unexpected error getting digest verifier")
  		}
  
  		io.Copy(verifier, bytes.NewReader(response.Certificate))
  
  		if !verifier.Verified() {
  			return RootCA{}, errors.Errorf("remote CA does not match fingerprint. Expected: %s", d.Hex())
  		}
  	}
  
  	// NewRootCA will validate that the certificates are otherwise valid and create a RootCA object.
  	// Since there is no key, the certificate expiry does not matter and will not be used.
  	return NewRootCA(response.Certificate, nil, nil, DefaultNodeCertExpiration, nil)
  }
docs: // GetRemoteCA returns the remote endpoint's CA certificate bundle