pki

package module
v0.2.5 Latest Latest
Warning

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

Go to latest
Published: Dec 19, 2023 License: GPL-2.0 Imports: 31 Imported by: 3

README

GoDoc

TL;DR

This is an opinionated single-file OpenVPN TLS certificate library. It has no dependencies on any other external tool such as openssl.

Features

  • Uses a single boltdb instance to store the certificates and keys.
  • All data strored in the database is encrypted with keys derived from a user supplied CA passphrase.
  • Support for issuing & revoking:
    • Server Certs (optionally signed by intermediate CAs)
    • Client Certs (optionally signed by intermediate CAs)
    • Intermediate CA certs (optionally signed by other intermediate CAs)
  • Flexible CRL generation
  • The certificates and keys are opinionated:
    • All CA cert private keys are Secp521r1
    • Client & Servers cert private keys are Secp256k1
    • "SSL-Server" attribute set on server certificates (nsCertType)
    • "SSL-Client" attribute set on client certificates (nsCertType)
    • ECDSA with SHA512 is used as the signature algorithm of encryption to thwart DoS attacks.

Who uses this?

Two tools use this:

  • ovpn-tool - an opnionated PKI and OpenVPN Configuration manager
  • certik - an example CLI program that uses this library

How to use this?

You will need a fairly recent golang toolchain (>1.10). go-pki is modules ready. You just import the code in your project as:


    import (
        "github.com/opencoff/go-pki"
    )

Documentation

Overview

Package pki abstracts creating an opinionated PKI. The certs and keys are stored in a boltDB instance. The private keys are stored in encrypted form. The CA passphrase is used in a KDF to derive the encryption keys. User (client) certs are also encrypted - but with user provided passphrase.

Index

Constants

View Source
const DBVersion uint32 = 1

DB Version. This must be updated whenever we change the schema

Variables

View Source
var (
	ErrNoConfigBucket = errors.New("db: can't find config bucket")
	ErrNotFound       = errors.New("no such CN")
	ErrTooSmall       = errors.New("decrypt: input buffer too small")
	ErrExpired        = errors.New("certificate has expired")
	ErrCARevoked      = errors.New("issuing CA is revoked")
)

Functions

func CertificateRequestText

func CertificateRequestText(csr *x509.CertificateRequest) (string, error)

CertificateRequestText returns a human-readable string representation of the certificate request csr. The format is similar (but not identical) to the OpenSSL way of printing certificates.

func CertificateText

func CertificateText(cert *x509.Certificate) (string, error)

CertificateText returns a human-readable string representation of the certificate cert. The format is similar (but not identical) to the OpenSSL way of printing certificates.

Types

type CA

type CA struct {
	*x509.Certificate

	Expired   bool
	CARevoked bool
	// contains filtered or unexported fields
}

CA is a special type of Credential that also has a CSR in it.

func New

func New(cfg *Config, dbname string, create bool) (*CA, error)

New creates a new PKI CA instance with storage backed by boltdb in 'dbname'

func NewFromJSON

func NewFromJSON(cfg *Config, dbname, jsonStr string) (*CA, error)

NewFromJSON creates a new PKI CA instance with storage backed by boltDB in 'dbname' with initial contents coming from the JSON blob

func NewWithStorage

func NewWithStorage(cfg *Config, db Storage, create bool) (*CA, error)

NewWithStorage creates a new RootCA with the given storage engine

func (*CA) CRL

func (ca *CA) CRL(crlValidDays int) ([]byte, error)

Return a CRL with a given validity

func (*CA) Chain

func (ca *CA) Chain() ([]*CA, error)

return the signing chain for _this_ CA

func (*CA) ChainFor

func (ca *CA) ChainFor(c *Cert) ([]*CA, error)

Return chain of signing certs for the named cert. This function operates on the global namespace; i.e., it is NOT dependent on the specific instance of 'ca' (which may be an intermediate CA).

func (*CA) Close

func (ca *CA) Close() error

Close the CA and associated storage

func (*CA) ExportJSON

func (ca *CA) ExportJSON(wr io.Writer) error

Export Entire DB as a JSON

func (*CA) Find

func (ca *CA) Find(cn string) (*Cert, error)

Find _all_ entities in the system: client certs, server certs and intermediate certs

func (*CA) FindCA

func (ca *CA) FindCA(cn string) (*CA, error)

Find the CA with the given name. This operates on the global "namespace". i.e., even if 'ca' is an intermediate CA, it will search in the parent namespaces till a match is found.

func (*CA) FindClient

func (ca *CA) FindClient(cn string) (*Cert, error)

FindClient returns the given client cert

func (*CA) FindServer

func (ca *CA) FindServer(cn string) (*Cert, error)

FindServer returns the given server cert

func (*CA) GetAllRevoked

func (ca *CA) GetAllRevoked() (*pkix.CertificateList, error)

Return list of revoked certs

func (*CA) GetCAs

func (ca *CA) GetCAs() ([]*CA, error)

Return _all_ CAs in the system (including the root CA)

func (*CA) GetClients

func (ca *CA) GetClients() ([]*Cert, error)

Return all the client certs

func (*CA) GetServers

func (ca *CA) GetServers() ([]*Cert, error)

Return all server certs

func (*CA) IsRevokedCA

func (ca *CA) IsRevokedCA(xca *CA) (bool, error)

Return true if 'xca' is revoked. This looks in the global namespace and not just the CAs signed by 'ca'.

func (*CA) IsValid

func (ca *CA) IsValid() bool

Return true if the CA hasn't expired and is not revoked

func (*CA) ListRevoked

func (ca *CA) ListRevoked() (map[string]Revoked, error)

func (*CA) NewClientCert

func (ca *CA) NewClientCert(ci *CertInfo, pw string) (*Cert, error)

NewClientCert issues a new client certificate

func (*CA) NewIntermediateCA

func (ca *CA) NewIntermediateCA(ci *CertInfo) (*CA, error)

Create and issue a new intermediate CA cert

func (*CA) NewServerCert

func (ca *CA) NewServerCert(ci *CertInfo, pw string) (*Cert, error)

NewServerCert issues a new server certificate

func (*CA) PEM

func (ca *CA) PEM() []byte

Return PEM encoded cert for this CA

func (*CA) Rekey

func (ca *CA) Rekey(newpw string) error

Change the DB encryption key. This merely changes the KEK for the DB.

func (*CA) RevokeCA

func (ca *CA) RevokeCA(cn string) error

RevokeCA revokes a given intermediate CA We don't allow for the root-ca to be revoked.

func (*CA) RevokeClient

func (ca *CA) RevokeClient(cn string) error

RevokeClient revokes the given client

func (*CA) RevokeServer

func (ca *CA) RevokeServer(cn string) error

RevokeServer revokes the given server

func (*CA) SignCert

func (ca *CA) SignCert(csr *x509.Certificate) (*x509.Certificate, error)

Sign the given CSR with the provided CA

type Cert

type Cert struct {
	*x509.Certificate

	Key    *ecdsa.PrivateKey
	Rawkey []byte

	IsServer  bool
	IsCA      bool
	Expired   bool
	CARevoked bool

	// Additional info provided when cert was created
	Additional []byte
}

Cert represents a client or server certificate

func (*Cert) PEM

func (ck *Cert) PEM() (crt, key []byte)

Return PEM encoded cert & key

type CertInfo

type CertInfo struct {
	Subject  pkix.Name
	Validity time.Duration

	EmailAddresses []string
	DNSNames       []string

	// We only support exactly _one_ IP address
	IPAddresses []net.IP

	// Additional info stored in the DB against this certificate
	// This info is *NOT* in the x509 object.
	Additional []byte
}

Information needed to create a certificate

type Config

type Config struct {
	// Passphrase to encrypt the CA credentials
	Passwd string

	// Root-CA subject name; also used for all intermediate CAs
	Subject pkix.Name

	// Validity of the root-CA
	Validity time.Duration
}

Config holds the initial info needed to setup a CA

type Revoked

type Revoked struct {
	*Cert
	When time.Time
}

Revoked Certificate

type Storage

type Storage interface {
	Rekey(newpw string) error
	Close() error

	// Get the Root CA
	GetRootCA() (*Cert, error)

	// Store root CA
	StoreRootCA(*Cert) error

	// Return current serial#
	GetSerial() *big.Int

	// increment serial#, update db and return new serial#
	NewSerial() (*big.Int, error)

	// get intermediate CA
	GetICA(nm string) (*Cert, error)

	// Fetch client cert
	GetClientCert(nm string, pw string) (*Cert, error)

	// Fetch server cert
	GetServerCert(nm string, pw string) (*Cert, error)

	// Store intermediate CA
	StoreICA(c *Cert) error

	// Store client cert
	StoreClientCert(c *Cert, pw string) error

	// Store server cert
	StoreServerCert(c *Cert, pw string) error

	// Delete a given CA -- revocation
	DeleteICA(cn string) error

	// Delete client cert
	DeleteClientCert(cn string) error

	// delete server cert
	DeleteServerCert(cn string) error

	// Export DB in portable JSON
	ExportJSON() (string, error)

	// - Iterators -
	MapICA(func(*Cert) error) error
	MapClientCerts(func(*Cert) error) error
	MapServerCerts(func(*Cert) error) error
	MapRevoked(func(time.Time, *Cert)) error

	FindRevoked(skid []byte) (time.Time, *Cert, error)
}

Storage abstracts the underlying persistent storage provider.

Jump to

Keyboard shortcuts

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