enterprise_cert.go raw

   1  // Copyright 2022 Google LLC.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  // Package cert contains certificate tools for Google API clients.
   6  // This package is intended to be used with crypto/tls.Config.GetClientCertificate.
   7  //
   8  // The certificates can be used to satisfy Google's Endpoint Validation.
   9  // See https://cloud.google.com/endpoint-verification/docs/overview
  10  //
  11  // This package is not intended for use by end developers. Use the
  12  // google.golang.org/api/option package to configure API clients.
  13  package cert
  14  
  15  import (
  16  	"crypto/tls"
  17  	"errors"
  18  
  19  	"github.com/googleapis/enterprise-certificate-proxy/client"
  20  )
  21  
  22  type ecpSource struct {
  23  	key *client.Key
  24  }
  25  
  26  // NewEnterpriseCertificateProxySource creates a certificate source
  27  // using the Enterprise Certificate Proxy client, which delegates
  28  // certifcate related operations to an OS-specific "signer binary"
  29  // that communicates with the native keystore (ex. keychain on MacOS).
  30  //
  31  // The configFilePath points to a config file containing relevant parameters
  32  // such as the certificate issuer and the location of the signer binary.
  33  // If configFilePath is empty, the client will attempt to load the config from
  34  // a well-known gcloud location.
  35  func NewEnterpriseCertificateProxySource(configFilePath string) (Source, error) {
  36  	key, err := client.Cred(configFilePath)
  37  	if err != nil {
  38  		if errors.Is(err, client.ErrCredUnavailable) {
  39  			return nil, errSourceUnavailable
  40  		}
  41  		return nil, err
  42  	}
  43  
  44  	return (&ecpSource{
  45  		key: key,
  46  	}).getClientCertificate, nil
  47  }
  48  
  49  func (s *ecpSource) getClientCertificate(info *tls.CertificateRequestInfo) (*tls.Certificate, error) {
  50  	var cert tls.Certificate
  51  	cert.PrivateKey = s.key
  52  	cert.Certificate = s.key.CertificateChain()
  53  	return &cert, nil
  54  }
  55