certdepot

package module
v0.0.0-...-e623e53 Latest Latest
Warning

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

Go to latest
Published: Jun 5, 2023 License: Apache-2.0 Imports: 18 Imported by: 10

README

======================================
``certdepot`` -- SSL Certificate Store
======================================

Overview
--------

Tools for creating and storing SSL certificates.


Motivation
----------

Certdepot is based off `certstrap <https://github.com/square/certstrap>`_ by
Square. This project heavily depends certstrap by expanding its capabilities.

Features
--------

Certificate Creation and Signing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SSL certificates and certificate authorities (CAs) can easily be created and
signed using Certdepot.


MongoDB Backed Depot
~~~~~~~~~~~~~~~~~~~~

Certdepot implements a certstrap
`depot <https://godoc.org/github.com/square/certstrap/depot#Depot>`_ backed by
MongoDB. This facilitates the storing and fetching of SSL certificates to and
from a Mongo database. There are various functions for maintaining the depot,
such as checking for expiration and rotating certs.


Bootstrap
~~~~~~~~~

Bootsrapping a depot facilitates creating a certificate depot with both a CA
and service certificate. ``BootstrapDepot`` currently supports bootstrapping
``FileDepots`` and ``MongoDepots``.


Code Examples
-------------

Create a depot, initialize a CA in the depot, and create and sign service cert
with that CA in the depot: ::
	mongoOpts := certdepot.MongoDBOptions{} // populate options
	d, err := certdepot.NewMongoDBCertDepot(ctx, mongoOpts)
	// handle err

	certOpts := certdepot.CertificateOptions{
		Organization:       "mongodb",
		Country:            "USA",
		Locality:           "NYC",
		OrganizationalUnit: "evergreen",
		Province:           "Manhattan",
		Expires:            24 * time.Hour,

		IP:           []string{"0.0.0.0"},
		Domain:       []string{"evergreen"},
		URI:          []string{"evergreen.mongodb.com"},
		Host:         "evergreen",
		CA:           "ca",
		CAPassphrase: "passphrase",
		Intermediate: true,
	}

	// initialize CA named `ca` and stores it in the depot
	certOpts.Init(d)
	// creates a new certificate named `evergreen`, signs it with `ca`, and
	// stores it in the depot
	certOpts.CreateCertificate(d)

The following does the same as above, but now using the bootstrap
functionality: ::
	bootstrapConf := certdepot.BootstrapDepotConfig{
                MongoDepot:  mongoOpts,
		CAOpts:      certOpts,
		ServiceOpts: certOpts,
	}
	d, err := BootstrapDepot(ctx, bootstrapConf)



Development
-----------

The certdepot project uses a ``makefile`` to coordinate testing.

The makefile provides the following targets:

``build``
   Compiles non-test code.

``test``
   Runs all tests, sequentially, for all packages.

``test-<package>``
   Runs all tests for a specific package.

``race``, ``race-<package>``
   As with their ``test`` counterpart, these targets run tests with
   the race detector enabled.

``lint``, ``lint-<package>``
   Installs and runs the ``gometaliter`` with appropriate settings to
   lint the project.

Note that in order for tests to run successfully and local mongod must be
running.

File tickets in Jira with the `MAKE <https://jira.mongodb.org/browse/MAKE>`_
project.


Documentation
-------------

See the
`certdepot godoc <https://godoc.org/github.com/evergreen-ci/certdepot>`_ for
complete documentation of certdepot.

See the `certstrap godoc <https://godoc.org/github.com/square/certstrap>`_ for
complete documentation of certstrap.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckCertificate

func CheckCertificate(d Depot, name string) bool

CheckCertificate checks the depot for existence of a certificate for a given name.

func CheckCertificateSigningRequest

func CheckCertificateSigningRequest(d Depot, name string) bool

CheckCertificateSigningRequest checks the depot for existence of a certificate signing request for a given name.

func CheckCertificateSigningRequestWithError

func CheckCertificateSigningRequestWithError(d Depot, name string) (bool, error)

CheckCertificateSigningRequestWithError checks the depot for existence of a certificate signing request for a given name. In the event of an internal error, an error is returned.

func CheckCertificateWithError

func CheckCertificateWithError(d Depot, name string) (bool, error)

CheckCertificateWithError checks the depot for existence of a certificate for a given name. In the event of an internal error, an error is returned.

func CheckPrivateKey

func CheckPrivateKey(d Depot, name string) bool

CheckPrivateKey checks the depot for existence of a private key for a given given name.

func CheckPrivateKeyWithError

func CheckPrivateKeyWithError(d Depot, name string) (bool, error)

CheckPrivateKeyWithError checks the depot for existence of a private key for a given name. In the event of an internal error, an error is returned.

func CrlTag

func CrlTag(prefix string) *depot.Tag

CrlTag returns a tag corresponding to a certificate revocation list.

func CrtTag

func CrtTag(prefix string) *depot.Tag

CrtTag returns a tag corresponding to a certificate.

func CsrTag

func CsrTag(prefix string) *depot.Tag

CsrTag returns a tag corresponding to a certificate signature request.

func DeleteCertificate

func DeleteCertificate(d Depot, name string) error

DeleteCertificate removes a certificate for a given name from the depot.

func DeleteCertificateRevocationList

func DeleteCertificateRevocationList(d Depot, name string) error

DeleteCertificateRevocationList removes a CRL for a given name in the depot.

func DeleteCertificateSigningRequest

func DeleteCertificateSigningRequest(d Depot, name string) error

DeleteCertificateSigningRequest removes a certificate signing request for a given name from the depot.

func DeleteOnExpiration

func DeleteOnExpiration(wd Depot, name string, after time.Duration) (bool, error)

DeleteOnExpiration deletes the given certificate from the depot if it has an expiration date within the duration `after`. True is returned if the certificate is deleted, false otherwise.

func DeletePrivateKey

func DeletePrivateKey(d Depot, name string) error

DeletePrivateKey removes a private key for a given name from the depot. This works for both encrypted and unencrypted private keys.

func GetCertificate

func GetCertificate(d Depot, name string) (crt *pkix.Certificate, err error)

GetCertificate retrieves a certificate for a given name from the depot.

func GetCertificateRevocationList

func GetCertificateRevocationList(d Depot, name string) (*pkix.CertificateRevocationList, error)

GetCertificateRevocationList gets a CRL for a given name in the depot.

func GetCertificateSigningRequest

func GetCertificateSigningRequest(d Depot, name string) (crt *pkix.CertificateSigningRequest, err error)

GetCertificateSigningRequest retrieves a certificate signing request for a given name from the depot.

func GetEncryptedPrivateKey

func GetEncryptedPrivateKey(d Depot, name string, passphrase []byte) (key *pkix.Key, err error)

GetEncryptedPrivateKey retrieves an encrypted private key for a given name from the depot.

func GetNameFromCrlTag

func GetNameFromCrlTag(tag *depot.Tag) string

GetNameFromCrlTag returns the name from a certificate revocation list tag.

func GetNameFromCrtTag

func GetNameFromCrtTag(tag *depot.Tag) string

GetNameFromCrtTag returns the name from a certificate tag.

func GetNameFromCsrTag

func GetNameFromCsrTag(tag *depot.Tag) string

GetNameFromCsrTag returns the name from a certificate request tag.

func GetNameFromPrivKeyTag

func GetNameFromPrivKeyTag(tag *depot.Tag) string

GetNameFromPrivKeyTag returns the name from a private key tag.

func GetPrivateKey

func GetPrivateKey(d Depot, name string) (key *pkix.Key, err error)

GetPrivateKey retrieves a private key for a given name from the depot.

func PrivKeyTag

func PrivKeyTag(prefix string) *depot.Tag

PrivKeyTag returns a tag corresponding to a private key.

func PutCertificate

func PutCertificate(d Depot, name string, crt *pkix.Certificate) error

PutCertificate creates a certificate for a given name in the depot.

func PutCertificateRevocationList

func PutCertificateRevocationList(d Depot, name string, crl *pkix.CertificateRevocationList) error

PutCertificateRevocationList creates a CRL for a given name in the depot.

func PutCertificateSigningRequest

func PutCertificateSigningRequest(d Depot, name string, csr *pkix.CertificateSigningRequest) error

PutCertificateSigningRequest creates a certificate signing request for a given name and csr in the depot.

func PutEncryptedPrivateKey

func PutEncryptedPrivateKey(d Depot, name string, key *pkix.Key, passphrase []byte) error

PutEncryptedPrivateKey creates an encrypted private key for a given name in the depot.

func PutPrivateKey

func PutPrivateKey(d Depot, name string, key *pkix.Key) error

PutPrivateKey creates a private key for a given name in the depot.

func ValidityBounds

func ValidityBounds(wd Depot, name string) (time.Time, time.Time, error)

ValidityBounds returns the date range for which the certificate is valid.

Types

type BootstrapDepotConfig

type BootstrapDepotConfig struct {
	// Name of FileDepot (directory). If a MongoDepot is desired, leave
	// empty.
	FileDepot string `bson:"file_depot,omitempty" json:"file_depot,omitempty" yaml:"file_depot,omitempty"`
	// Options for setting up a MongoDepot. If a FileDepot is desired,
	// leave pointer nil or the struct empty.
	MongoDepot *MongoDBOptions `bson:"mongo_depot,omitempty" json:"mongo_depot,omitempty" yaml:"mongo_depot,omitempty"`
	// CA certificate, this is optional unless CAKey is not empty, in
	// which case a CA certificate must also be provided.
	CACert string `bson:"ca_cert" json:"ca_cert" yaml:"ca_cert"`
	// CA key, this is optional unless CACert is not empty, in which case
	// a CA key must also be provided.
	CAKey string `bson:"ca_key" json:"ca_key" yaml:"ca_key"`
	// Common name of the CA (required).
	CAName string `bson:"ca_name" json:"ca_name" yaml:"ca_name"`
	// Common name of the service (required).
	ServiceName string `bson:"service_name" json:"service_name" yaml:"service_name"`
	// Options to initialize a CA. This is optional and only used if there
	// is no existing `CAName` in the depot and `CACert` is empty.
	// `CAOpts.CommonName` must equal `CAName`.
	CAOpts *CertificateOptions `bson:"ca_opts,omitempty" json:"ca_opts,omitempty" yaml:"ca_opts,omitempty"`
	// Options to create a service certificate. This is optional and only
	// used if there is no existing `ServiceName` in the depot.
	// `ServiceOpts.CommonName` must equal `ServiceName`.
	// `ServiceOpts.CA` must equal `CAName`.
	ServiceOpts *CertificateOptions `bson:"service_opts,omitempty" json:"service_opts,omitempty" yaml:"service_opts,omitempty"`
}

BootstrapDepotConfig contains options for BootstrapDepot. Must provide either the name of the FileDepot or the MongoDepot options, not both or neither.

func (*BootstrapDepotConfig) Validate

func (c *BootstrapDepotConfig) Validate() error

Validate ensures that the BootstrapDepotConfig is configured correctly.

type CertificateOptions

type CertificateOptions struct {
	//
	// Options specific to Init and CertRequest.
	//
	// Passprhase to encrypt private-key PEM block.
	Passphrase string `bson:"passphrase,omitempty" json:"passphrase,omitempty" yaml:"passphrase,omitempty"`
	// Size (in bits) of RSA keypair to generate (defaults to 2048).
	KeyBits int `bson:"key_bits,omitempty" json:"key_bits,omitempty" yaml:"key_bits,omitempty"`
	// Sets the Organization (O) field of the certificate.
	Organization string `bson:"o,omitempty" json:"o,omitempty" yaml:"o,omitempty"`
	// Sets the Country (C) field of the certificate.
	Country string `bson:"c,omitempty" json:"c,omitempty" yaml:"c,omitempty"`
	// Sets the Locality (L) field of the certificate.
	Locality string `bson:"l,omitempty" json:"l,omitempty" yaml:"l,omitempty"`
	// Sets the Common Name (CN) field of the certificate.
	CommonName string `bson:"cn,omitempty" json:"cn,omitempty" yaml:"cn,omitempty"`
	// Sets the Organizational Unit (OU) field of the certificate.
	OrganizationalUnit string `bson:"ou,omitempty" json:"ou,omitempty" yaml:"ou,omitempty"`
	// Sets the State/Province (ST) field of the certificate.
	Province string `bson:"st,omitempty" json:"st,omitempty" yaml:"st,omitempty"`
	// IP addresses to add as subject alt name.
	IP []string `bson:"ip,omitempty" json:"ip,omitempty" yaml:"ip,omitempty"`
	// DNS entries to add as subject alt name.
	Domain []string `bson:"dns,omitempty" json:"dns,omitempty" yaml:"dns,omitempty"`
	// URI values to add as subject alt name.
	URI []string `bson:"uri,omitempty" json:"uri,omitempty" yaml:"uri,omitempty"`
	// Path to private key PEM file (if blank, will generate new keypair).
	Key string `bson:"key,omitempty" json:"key,omitempty" yaml:"key,omitempty"`

	//
	// Options specific to Init and Sign.
	//
	// How long until the certificate expires.
	Expires time.Duration `bson:"expires,omitempty" json:"expires,omitempty" yaml:"expires,omitempty"`

	//
	// Options specific to Sign.
	//
	// Host name of the certificate to be signed.
	Host string `bson:"host,omitempty" json:"host,omitempty" yaml:"host,omitempty"`
	// Name of CA to issue cert with.
	CA string `bson:"ca,omitempty" json:"ca,omitempty" yaml:"ca,omitempty"`
	// Passphrase to decrypt CA's private-key PEM block.
	CAPassphrase string `bson:"ca_passphrase,omitempty" json:"ca_passphrase,omitempty" yaml:"ca_passphrase,omitempty"`
	// Whether generated certificate should be an intermediate.
	Intermediate bool `bson:"intermediate,omitempty" json:"intermediate,omitempty" yaml:"intermediate,omitempty"`
	// contains filtered or unexported fields
}

CertificateOptions contains options to use for Init, CertRequest, and Sign.

func (*CertificateOptions) CertRequest

func (opts *CertificateOptions) CertRequest(wd Depot) error

CertRequest creates a new certificate signing request (CSR) and key and puts them in the depot.

func (*CertificateOptions) CertRequestInMemory

func (opts *CertificateOptions) CertRequestInMemory() (*pkix.CertificateSigningRequest, *pkix.Key, error)

CertRequestInMemory is the same as CertRequest but returns the resulting certificate signing request and private key without putting them in the depot. Use PutCertRequestFromMemory to put the certificate in the depot.

func (*CertificateOptions) CreateCertificate

func (opts *CertificateOptions) CreateCertificate(wd Depot) error

CreateCertificate is a convenience function for creating a certificate request and signing it.

func (*CertificateOptions) CreateCertificateOnExpiration

func (opts *CertificateOptions) CreateCertificateOnExpiration(wd Depot, after time.Duration) (bool, error)

CreateCertificateOnExpiration checks if a certificate does not exist or if it expires within the duration `after` and creates a new certificate if either condition is met. True is returned if a certificate is created, false otherwise. If the certificate is a CA, the behavior is undefined.

func (*CertificateOptions) Init

func (opts *CertificateOptions) Init(wd Depot) error

Init initializes a new CA.

func (*CertificateOptions) PutCertFromMemory

func (opts *CertificateOptions) PutCertFromMemory(wd Depot) error

PutCertFromMemory stores the certificate generated from the options in the depot, along with the expiration TTL on the certificate.

func (*CertificateOptions) PutCertRequestFromMemory

func (opts *CertificateOptions) PutCertRequestFromMemory(wd Depot) error

PutCertRequestFromMemory stores the certificate request and key generated from the options in the depot.

func (*CertificateOptions) Reset

func (opts *CertificateOptions) Reset()

Reset clears the cached results of CertificateOptions so that the options can be changed after a certificate has already been requested or signed. For example, if the options have been modified, a new certificate request can be made with the new options by using Reset.

func (*CertificateOptions) Sign

func (opts *CertificateOptions) Sign(wd Depot) error

Sign signs a CSR with a given CA for a new certificate.

func (*CertificateOptions) SignInMemory

func (opts *CertificateOptions) SignInMemory(wd Depot) (*pkix.Certificate, error)

SignInMemory is the same as Sign but returns the resulting certificate without putting it in the depot. Use PutCertFromMemory to put the certificate in the depot.

type Credentials

type Credentials struct {
	// CACert is the PEM-encoded client CA certificate. If the credentials are
	// used by a client, this should be the certificate of the root CA to verify
	// the server certificate. If the credentials are used by a server, this
	// should be the certificate of the root CA to verify the client
	// certificate.
	CACert []byte `bson:"ca_cert" json:"ca_cert" yaml:"ca_cert"`
	// Cert is the PEM-encoded certificate.
	Cert []byte `bson:"cert" json:"cert" yaml:"cert"`
	// Key is the PEM-encoded private key.
	Key []byte `bson:"key" json:"key" yaml:"key"`

	// ServerName is the name of the service being contacted.
	ServerName string `bson:"server_name" json:"server_name" yaml:"server_name"`
}

Credentials represent a bundle of assets for doing TLS authentication.

func NewCredentials

func NewCredentials(caCert, cert, key []byte) (*Credentials, error)

NewCredentials initializes a new Credential struct.

func NewCredentialsFromFile

func NewCredentialsFromFile(path string) (*Credentials, error)

NewCredentialsFromFile parses the PEM-encoded credentials in JSON format in the file at path into a Credentials struct.

func (*Credentials) Export

func (c *Credentials) Export() ([]byte, error)

Export exports the Credentials struct into JSON-encoded bytes.

func (*Credentials) Resolve

func (c *Credentials) Resolve() (*tls.Config, error)

Resolve converts the Credentials struct into a tls.Config.

func (*Credentials) Validate

func (c *Credentials) Validate() error

Validate checks that the Credentials are all set to non-empty values.

type Depot

type Depot interface {
	depot.Depot
	CheckWithError(tag *depot.Tag) (bool, error)
	Save(string, *Credentials) error
	Find(string) (*Credentials, error)
	Generate(string) (*Credentials, error)
	GenerateWithOptions(CertificateOptions) (*Credentials, error)
}

Depot is a superset wrapper around certrstap's depot.Depot interface.

func BootstrapDepot

func BootstrapDepot(ctx context.Context, conf BootstrapDepotConfig) (Depot, error)

BootstrapDepot creates a certificate depot with a CA and service certificate.

func BootstrapDepotWithMongoClient

func BootstrapDepotWithMongoClient(ctx context.Context, client *mongo.Client, conf BootstrapDepotConfig) (Depot, error)

BootstrapDepotWithMongoClient creates a certificate depot with a CA and service certificate using the provided mongo driver client.

func CreateDepot

func CreateDepot(ctx context.Context, client *mongo.Client, conf BootstrapDepotConfig) (Depot, error)

CreateDepot creates a certificate depot with the given BootstrapDepotConfig. If a mongo client is passed in it will be used to create the mongo depot.

func MakeFileDepot

func MakeFileDepot(dir string, opts DepotOptions) (Depot, error)

MakeFileDepot constructs a file-based depot implementation and allows users to specify options for the default CA name and expiration time.

func NewFileDepot

func NewFileDepot(dir string) (Depot, error)

NewFileDepot creates a FileDepot wrapped with certdepot.Depot.

func NewMongoDBCertDepot

func NewMongoDBCertDepot(ctx context.Context, opts *MongoDBOptions) (Depot, error)

NewMongoDBCertDepot returns a new cert depot backed by MongoDB using the mongo driver.

func NewMongoDBCertDepotWithClient

func NewMongoDBCertDepotWithClient(ctx context.Context, client *mongo.Client, opts *MongoDBOptions) (Depot, error)

NewMongoDBCertDepotWithClient returns a new cert depot backed by MongoDB using the provided mongo driver client.

type DepotOptions

type DepotOptions struct {
	CA                string        `bson:"ca" json:"ca" yaml:"ca"`
	DefaultExpiration time.Duration `bson:"default_expiration" json:"default_expiration" yaml:"default_expiration"`
}

DepotOptions capture default options used during certificate generation and creation used by depots.

type MongoDBOptions

type MongoDBOptions struct {
	MongoDBURI           string        `bson:"mongodb_uri" json:"mongodb_uri" yaml:"mongodb_uri"`
	DatabaseName         string        `bson:"db_name" json:"db_name" yaml:"db_name"`
	CollectionName       string        `bson:"coll_name" json:"coll_name" yaml:"coll_name"`
	MongoDBDialTimeout   time.Duration `bson:"dial_timeout,omitempty" json:"dial_timeout,omitempty" yaml:"dial_timeout,omitempty"`
	MongoDBSocketTimeout time.Duration `bson:"socket_timeout,omitempty" json:"socket_timeout,omitempty" yaml:"socket_timeout,omitempty"`
	DepotOptions         DepotOptions  `bson:"depot_options" json:"depot_options" yaml:"depot_options"`
}

MongoDBOptions contains options for NewMongoDBCertDepot, NewMongoDBCertDepotWithClient, NewMgoCertDepot, and NewMgoCertDepotWithSession.

func (*MongoDBOptions) IsZero

func (opts *MongoDBOptions) IsZero() bool

IsZero returns whether the given MongoDBOptions struct holds the "zero" value of the struct.

type User

type User struct {
	ID            string    `bson:"_id"`
	Cert          string    `bson:"cert"`
	PrivateKey    string    `bson:"private_key"`
	CertReq       string    `bson:"cert_req"`
	CertRevocList string    `bson:"cert_revoc_list"`
	TTL           time.Time `bson:"ttl,omitempty"`
}

User stores information for a user in the mongo certificate depot.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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