testcerts

package module
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 26, 2024 License: MIT Imports: 13 Imported by: 5

README

testcerts

Actions Status codecov Go Report Card Go Reference license

Stop saving test certificates in your code repos. Start generating them in your tests.

func TestFunc(t *testing.T) {
	// Create and write self-signed Certificate and Key to temporary files
	cert, key, err := testcerts.GenerateToTempFile("/tmp/")
	if err != nil {
		// do something
	}
	defer os.Remove(key)
	defer os.Remove(cert)

	// Start HTTP Listener with test certificates
	err = http.ListenAndServeTLS("127.0.0.1:443", cert, key, someHandler)
	if err != nil {
		// do something
	}
}

For more complex tests, you can also use this package to create a Certificate Authority and a key pair signed by that Certificate Authority for any test domain you want.

func TestFunc(t *testing.T) {
	// Generate Certificate Authority
	ca := testcerts.NewCA()

	go func() {
		// Create a signed Certificate and Key for "localhost"
		certs, err := ca.NewKeyPair("localhost")
		if err != nil {
			// do something
		}

		// Write certificates to a file
		err = certs.ToFile("/tmp/cert", "/tmp/key")
		if err {
			// do something
		}

		// Start HTTP Listener
		err = http.ListenAndServeTLS("localhost:443", "/tmp/cert", "/tmp/key", someHandler)
		if err != nil {
			// do something
		}
	}()

	// Create a client with the self-signed CA
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: certs.ConfigureTLSConfig(ca.GenerateTLSConfig()),
		},
	}

	// Make an HTTPS request
	r, _ := client.Get("https://localhost")
}

Simplify your testing, and don't hassle with certificates anymore.

Contributing

If you find a bug or have an idea for a feature, please open an issue or a pull request.

License

testcerts is released under the MIT License. See LICENSE for details.

Documentation

Overview

Package testcerts provides an easy-to-use suite of functions for generating x509 test certificates.

Stop saving test certificates in your code repos. Start generating them in your tests.

func TestFunc(t *testing.T) {
	// Create and write self-signed Certificate and Key to temporary files
	cert, key, err := testcerts.GenerateToTempFile("/tmp/")
	if err != nil {
		// do something
	}
	defer os.Remove(key)
	defer os.Remove(cert)

	// Start HTTP Listener with test certificates
	err = http.ListenAndServeTLS("127.0.0.1:443", cert, key, someHandler)
	if err != nil {
		// do something
	}
}

For more complex tests, you can also use this package to create a Certificate Authority and a key pair signed by that Certificate Authority for any test domain you want.

func TestFunc(t *testing.T) {
	// Generate Certificate Authority
	ca := testcerts.NewCA()

	go func() {
		// Create a signed Certificate and Key for "localhost"
		certs, err := ca.NewKeyPair("localhost")
		if err != nil {
			// do something
		}

		// Write certificates to a file
		err = certs.ToFile("/tmp/cert", "/tmp/key")
		if err {
			// do something
		}

		// Start HTTP Listener
		err = http.ListenAndServeTLS("localhost:443", "/tmp/cert", "/tmp/key", someHandler)
		if err != nil {
			// do something
		}
	}()

	// Create a client with the self-signed CA
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: certs.ConfigureTLSConfig(ca.GenerateTLSConfig()),
		},
	}

	// Make an HTTPS request
	r, _ := client.Get("https://localhost")
}

Simplify your testing, and don't hassle with certificates anymore.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrEmptyConfig is returned when a KeyPairConfig is empty.
	ErrEmptyConfig = errors.New("empty KeyPairConfig")

	// ErrInvalidIP is returned when an IP address is invalid.
	ErrInvalidIP = errors.New("invalid IP address")
)

Functions

func GenerateCerts

func GenerateCerts(domains ...string) ([]byte, []byte, error)

GenerateCerts generates a x509 certificate and key. It returns the certificate and key as byte slices, and any error that occurred.

cert, key, err := GenerateCerts()
if err != nil {
	// handle error
}

func GenerateCertsToFile

func GenerateCertsToFile(certFile, keyFile string) error

GenerateCertsToFile creates a x509 certificate and key and writes it to the specified file paths.

err := GenerateCertsToFile("/path/to/cert", "/path/to/key")
if err != nil {
	// handle error
}

If the specified file paths already exist, it will overwrite the existing files.

func GenerateCertsToTempFile added in v1.0.2

func GenerateCertsToTempFile(dir string) (string, string, error)

GenerateCertsToTempFile will create a temporary x509 certificate and key in a randomly generated file using the directory path provided. If no directory is specified, the default directory for temporary files as returned by os.TempDir will be used.

cert, key, err := GenerateCertsToTempFile("/tmp/")
if err != nil {
	// handle error
}

Types

type CertificateAuthority added in v1.1.0

type CertificateAuthority struct {
	// contains filtered or unexported fields
}

CertificateAuthority represents a self-signed x509 certificate authority.

func NewCA added in v1.1.0

func NewCA() *CertificateAuthority

NewCA creates a new CertificateAuthority.

Example
// Generate a new Certificate Authority
ca := NewCA()

// Create a new KeyPair with a list of domains
certs, err := ca.NewKeyPair("localhost")
if err != nil {
	fmt.Printf("Error generating keypair - %s", err)
}

// Write the certificates to a file
cert, key, err := certs.ToTempFile("")
if err != nil {
	fmt.Printf("Error writing certs to temp files - %s", err)
}

// Setup Server TLS Config
serverTLSConfig, err := certs.ConfigureTLSConfig(ca.GenerateTLSConfig())
if err != nil {
	fmt.Printf("Error configuring server TLS - %s", err)
}

// Require Valid Client Cert
serverTLSConfig.ClientAuth = tls.RequireAndVerifyClientCert

// Create an HTTP Server
server := &http.Server{
	Addr: "0.0.0.0:8443",
	Handler: http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
		_, err := w.Write([]byte("Hello, World!"))
		if err != nil {
			fmt.Printf("Error writing response - %s", err)
		}
	}),
	TLSConfig: serverTLSConfig,
}
defer server.Close()

go func() {
	// Start HTTP Listener
	err = server.ListenAndServeTLS(cert.Name(), key.Name())
	if err != nil && err != http.ErrServerClosed {
		fmt.Printf("Listener returned error - %s", err)
	}
}()

// Wait for Listener to start
<-time.After(3 * time.Second)

// Client TLS Config
clientTLSConfig, err := certs.ConfigureTLSConfig(ca.GenerateTLSConfig())
if err != nil {
	fmt.Printf("Error configuring client TLS - %s", err)
}

// Setup HTTP Client with Cert Pool
client := &http.Client{
	Transport: &http.Transport{
		TLSClientConfig: clientTLSConfig,
	},
}

// Make an HTTPS request
rsp, err := client.Get("https://localhost:8443")
if err != nil {
	fmt.Printf("Client returned error - %s", err)
}

// Print the response
fmt.Println(rsp.Status)
Output:

200 OK

func (*CertificateAuthority) CertPool added in v1.1.0

func (ca *CertificateAuthority) CertPool() *x509.CertPool

CertPool returns a Certificate Pool of the CertificateAuthority Certificate.

func (*CertificateAuthority) GenerateTLSConfig added in v1.2.0

func (ca *CertificateAuthority) GenerateTLSConfig() *tls.Config

GenerateTLSConfig returns a tls.Config with the CertificateAuthority as the RootCA.

func (*CertificateAuthority) NewKeyPair added in v1.1.0

func (ca *CertificateAuthority) NewKeyPair(domains ...string) (*KeyPair, error)

NewKeyPair generates a new KeyPair signed by the CertificateAuthority for the given domains. The domains are used to populate the Subject Alternative Name field of the certificate.

func (*CertificateAuthority) NewKeyPairFromConfig added in v1.2.0

func (ca *CertificateAuthority) NewKeyPairFromConfig(config KeyPairConfig) (*KeyPair, error)

NewKeyPairFromConfig generates a new KeyPair signed by the CertificateAuthority from the given configuration. The configuration is used to populate the Subject Alternative Name field of the certificate.

func (*CertificateAuthority) PrivateKey added in v1.1.0

func (ca *CertificateAuthority) PrivateKey() []byte

PrivateKey returns the private key of the CertificateAuthority.

func (*CertificateAuthority) PublicKey added in v1.1.0

func (ca *CertificateAuthority) PublicKey() []byte

PublicKey returns the public key of the CertificateAuthority.

func (*CertificateAuthority) ToFile added in v1.1.0

func (ca *CertificateAuthority) ToFile(certFile, keyFile string) error

ToFile saves the CertificateAuthority certificate and private key to the specified files. Returns an error if any file operation fails.

func (*CertificateAuthority) ToTempFile added in v1.1.0

func (ca *CertificateAuthority) ToTempFile(dir string) (cfh *os.File, kfh *os.File, err error)

ToTempFile saves the CertificateAuthority certificate and private key to temporary files. The temporary files are created in the specified directory and have random names.

type KeyPair added in v1.1.0

type KeyPair struct {
	// contains filtered or unexported fields
}

KeyPair represents a pair of self-signed x509 certificate and private key.

func (*KeyPair) ConfigureTLSConfig added in v1.2.0

func (kp *KeyPair) ConfigureTLSConfig(tlsConfig *tls.Config) (*tls.Config, error)

ConfigureTLSConfig will configure the tls.Config with the KeyPair certificate and private key. The returned tls.Config can be used for a server or client.

func (*KeyPair) PrivateKey added in v1.1.0

func (kp *KeyPair) PrivateKey() []byte

PrivateKey returns the private key of the KeyPair.

func (*KeyPair) PublicKey added in v1.1.0

func (kp *KeyPair) PublicKey() []byte

PublicKey returns the public key of the KeyPair.

func (*KeyPair) ToFile added in v1.1.0

func (kp *KeyPair) ToFile(certFile, keyFile string) error

ToFile saves the KeyPair certificate and private key to the specified files. Returns an error if any file operation fails.

func (*KeyPair) ToTempFile added in v1.1.0

func (kp *KeyPair) ToTempFile(dir string) (cfh *os.File, kfh *os.File, err error)

ToTempFile saves the KeyPair certificate and private key to temporary files. The temporary files are created in the specified directory and have random names.

type KeyPairConfig added in v1.2.0

type KeyPairConfig struct {
	// Domains is a list of domains to include in the certificate as Subject
	// Alternative Names.
	Domains []string

	// IPAddresses is a list of IP addresses to include in the certificate
	// as Subject Alternative Names.
	IPAddresses []string

	// SerialNumber is the serial number to use for the certificate.
	SerialNumber *big.Int

	// CommonName is the Common Name to use for the certificate.
	CommonName string
}

KeyPairConfig is a configuration for generating an X.509 key pair.

func (*KeyPairConfig) IPNetAddresses added in v1.2.0

func (c *KeyPairConfig) IPNetAddresses() ([]net.IP, error)

IPAddresses returns a list of IP addresses in Net.IP format.

func (*KeyPairConfig) Validate added in v1.2.0

func (c *KeyPairConfig) Validate() error

Validate validates the KeyPairConfig ensuring that it is not empty and that provided values are valid.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL