acme

package module
v2.0.1 Latest Latest
Warning

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

Go to latest
Published: May 15, 2019 License: MIT Imports: 25 Imported by: 1

README

eggsampler/acme

GoDoc Build Status codecov.io

About

eggsampler/acme is a Go client library implementation for RFC8555 (previously ACME), specifically for use with the Let's Encrypt service.

The library is designed to provide a zero external dependency wrapper over exposed directory endpoints and provide objects in easy to use structures.

Example

A simple certbot-like example is provided in the examples/certbot directory. This code demonstrates account registration, new order submission, fulfilling challenges, finalising an order and fetching the issued certificate chain.

An example of how to use the autocert package is also provided in examples/autocert.

Tests

The tests can be run against an instance of boulder or pebble.

Challenge fulfilment is designed to use the new challtestsrv server present inside boulder and pebble which responds to dns queries and challenges as required.

To run tests against an already running instance of boulder or pebble, use the test target in the Makefile.

Some convenience targets for launching pebble/boulder using their respective docker compose files have also been included in the Makefile.

Documentation

Index

Constants

View Source
const (
	// LetsEncryptProduction holds the production directory url
	LetsEncryptProduction = "https://acme-v02.api.letsencrypt.org/directory"

	// LetsEncryptStaging holds the staging directory url
	LetsEncryptStaging = "https://acme-staging-v02.api.letsencrypt.org/directory"
)
View Source
const (
	ChallengeTypeDNS01     = "dns-01"
	ChallengeTypeHTTP01    = "http-01"
	ChallengeTypeTLSALPN01 = "tls-alpn-01"
	ChallengeTypeTLSSNI01  = "tls-sni-01"
)

Different possible challenge types provided by an ACME server.

View Source
const (
	ReasonUnspecified          = iota // 0
	ReasonKeyCompromise               // 1
	ReasonCaCompromise                // 2
	ReasonAffiliationChanged          // 3
	ReasonSuperseded                  // 4
	ReasonCessationOfOperation        // 5
	ReasonCertificateHold             // 6

	ReasonRemoveFromCRL      // 8
	ReasonPrivilegeWithdrawn // 9
	ReasonAaCompromise       // 10
)

Constants used for certificate revocation, used for RevokeCertificate

Variables

View Source
var (
	ErrUnsupported = errors.New("acme: unsupported")
)

Functions

func EncodeDNS01KeyAuthorization

func EncodeDNS01KeyAuthorization(keyAuth string) string

EncodeDNS01KeyAuthorization encodes a key authorization and provides a value to be put in the TXT record for the _acme-challenge DNS entry.

func JWKThumbprint

func JWKThumbprint(pub crypto.PublicKey) (string, error)

JWKThumbprint creates a JWK thumbprint out of pub as specified in https://tools.ietf.org/html/rfc7638.

Types

type Account

type Account struct {
	Status               string   `json:"status"`
	Contact              []string `json:"contact"`
	TermsOfServiceAgreed bool     `json:"onlyReturnExisting"`
	Orders               string   `json:"orders"`

	// Provided by the Location http header when creating a new account or fetching an existing account.
	URL string `json:"-"`

	// The private key used to create or fetch the account.
	// Not fetched from server.
	PrivateKey crypto.Signer `json:"-"`

	// SHA-256 digest JWK_Thumbprint of the account key.
	// Used in updating challenges, see: https://tools.ietf.org/html/draft-ietf-acme-acme-10#section-8.1
	Thumbprint string `json:"-"`
}

Account structure representing fields in an account object.

type Authorization

type Authorization struct {
	Identifier Identifier  `json:"identifier"`
	Status     string      `json:"status"`
	Expires    time.Time   `json:"expires"`
	Challenges []Challenge `json:"challenges"`
	Wildcard   bool        `json:"wildcard"`

	// For convenience access to the provided challenges
	ChallengeMap   map[string]Challenge `json:"-"`
	ChallengeTypes []string             `json:"-"`

	URL string `json:"-"`
}

Authorization object returned when fetching an authorization in an order.

type AutoCert

type AutoCert struct {
	// Acme directory Url
	// If nil, uses `LetsEncryptStaging`
	DirectoryURL string

	// Options contains the options used for creating the acme client
	Options []OptionFunc

	// A function to check whether a host is allowed or not
	// If nil, all hosts allowed
	// Use `WhitelistHosts(hosts ...string)` for a simple white list of hostnames
	HostCheck HostCheck

	// Cache dir to store account data and certificates
	// If nil, does not write cache data to file
	CacheDir string

	// When using a staging environment, include a root certificate for verification purposes
	RootCert string

	// Called before updating challenges
	PreUpdateChallengeHook func(Account, Challenge)
	// contains filtered or unexported fields
}

AutoCert is a stateful certificate manager for issuing certificates on connecting hosts

func (*AutoCert) GetCertificate

func (m *AutoCert) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error)

GetCertificate implements a tls.Config.GetCertificate hook

func (*AutoCert) HTTPHandler

func (m *AutoCert) HTTPHandler(handler http.Handler) http.Handler

HTTPHandler Wraps a handler and provides serving of http-01 challenge tokens from /.well-known/acme-challenge/ If handler is nil, will redirect all traffic otherwise to https

type Challenge

type Challenge struct {
	Type      string  `json:"type"`
	URL       string  `json:"url"`
	Status    string  `json:"status"`
	Validated string  `json:"validated"`
	Error     Problem `json:"error"`

	// Based on the challenge used
	Token            string `json:"token"`
	KeyAuthorization string `json:"keyAuthorization"`

	// Authorization url provided by the rel="up" Link http header
	AuthorizationURL string `json:"-"`
}

Challenge object fetched in an authorization or directly from the challenge url.

type Client

type Client struct {

	// The amount of total time the Client will wait at most for a challenge to be updated or a certificate to be issued.
	// Default 30 seconds if duration is not set or if set to 0.
	PollTimeout time.Duration

	// The time between checking if a challenge has been updated or a certificate has been issued.
	// Default 0.5 seconds if duration is not set or if set to 0.
	PollInterval time.Duration
	// contains filtered or unexported fields
}

Client structure to interact with an ACME server. This is typically how most, if not all, of the communication between the client and server occurs.

func NewClient

func NewClient(directoryURL string, options ...OptionFunc) (Client, error)

NewClient creates a new acme client given a valid directory url.

func (Client) AccountKeyChange

func (c Client) AccountKeyChange(account Account, newPrivateKey crypto.Signer) (Account, error)

AccountKeyChange rolls over an account to a new key.

func (Client) DeactivateAccount

func (c Client) DeactivateAccount(account Account) (Account, error)

DeactivateAccount deactivates a given account.

func (Client) DeactivateAuthorization

func (c Client) DeactivateAuthorization(account Account, authURL string) (Authorization, error)

DeactivateAuthorization deactivate a provided authorization url from an order.

func (Client) Directory

func (c Client) Directory() Directory

The directory object returned by the client connecting to a directory url.

func (Client) FetchAuthorization

func (c Client) FetchAuthorization(account Account, authURL string) (Authorization, error)

FetchAuthorization fetches an authorization from an authorization url provided in an order.

func (Client) FetchCertificates

func (c Client) FetchCertificates(account Account, certificateURL string) ([]*x509.Certificate, error)

FetchCertificates downloads a certificate chain from a url given in an order certificate.

func (Client) FetchChallenge

func (c Client) FetchChallenge(account Account, challengeURL string) (Challenge, error)

FetchChallenge fetches an existing challenge from the given url.

func (Client) FetchOrder

func (c Client) FetchOrder(account Account, orderURL string) (Order, error)

FetchOrder fetches an existing order given an order url.

func (Client) FinalizeOrder

func (c Client) FinalizeOrder(account Account, order Order, csr *x509.CertificateRequest) (Order, error)

FinalizeOrder indicates to the acme server that the client considers an order complete and "finalizes" it. If the server believes the authorizations have been filled successfully, a certificate should then be available. This function assumes that the order status is "ready".

func (Client) NewAccount

func (c Client) NewAccount(privateKey crypto.Signer, onlyReturnExisting, termsOfServiceAgreed bool, contact ...string) (Account, error)

NewAccount registers a new account with the acme service

func (Client) NewOrder

func (c Client) NewOrder(account Account, identifiers []Identifier) (Order, error)

NewOrder initiates a new order for a new certificate.

func (Client) NewOrderDomains

func (c Client) NewOrderDomains(account Account, domains ...string) (Order, error)

NewOrderDomains is a wrapper for NewOrder(AcmeAccount, []AcmeIdentifiers) Creates a dns identifier for each provided domain

func (Client) RevokeCertificate

func (c Client) RevokeCertificate(account Account, cert *x509.Certificate, key crypto.Signer, reason int) error

RevokeCertificate revokes a given certificate given the certificate key or account key, and a reason.

func (Client) UpdateAccount

func (c Client) UpdateAccount(account Account, termsOfServiceAgreed bool, contact ...string) (Account, error)

UpdateAccount updates an existing account with the acme service.

func (Client) UpdateChallenge

func (c Client) UpdateChallenge(account Account, challenge Challenge) (Challenge, error)

UpdateChallenge responds to a challenge to indicate to the server to complete the challenge.

type Directory

type Directory struct {
	NewNonce   string `json:"newNonce"`   // url to new nonce endpoint
	NewAccount string `json:"newAccount"` // url to new account endpoint
	NewOrder   string `json:"newOrder"`   // url to new order endpoint
	NewAuthz   string `json:"newAuthz"`   // url to new authz endpoint
	RevokeCert string `json:"revokeCert"` // url to revoke cert endpoint
	KeyChange  string `json:"keyChange"`  // url to key change endpoint

	// meta object containing directory metadata
	Meta struct {
		TermsOfService          string   `json:"termsOfService"`
		Website                 string   `json:"website"`
		CaaIdentities           []string `json:"caaIdentities"`
		ExternalAccountRequired bool     `json:"externalAccountRequired"`
	} `json:"meta"`

	// Directory url provided when creating a new acme client.
	URL string `json:"-"`
}

Directory object as returned from the client's directory url upon creation of client.

type HostCheck

type HostCheck func(host string) error

HostCheck function prototype to implement for checking hosts against before issuing certificates

func WhitelistHosts

func WhitelistHosts(hosts ...string) HostCheck

WhitelistHosts implements a simple whitelist HostCheck

type Identifier

type Identifier struct {
	Type  string `json:"type"`
	Value string `json:"value"`
}

Identifier object used in order and authorization objects

type OptionFunc

type OptionFunc func(client *Client) error

OptionFunc function prototype for passing options to NewClient

func WithAcceptLanguage

func WithAcceptLanguage(acceptLanguage string) OptionFunc

WithAcceptLanguage sets an Accept-Language header on http requests

func WithHTTPClient

func WithHTTPClient(httpClient *http.Client) OptionFunc

WithHTTPClient Allows setting a custom http client for acme connections

func WithHTTPTimeout

func WithHTTPTimeout(duration time.Duration) OptionFunc

WithHTTPTimeout sets a timeout on the http client used by the Client

func WithInsecureSkipVerify

func WithInsecureSkipVerify() OptionFunc

WithInsecureSkipVerify sets InsecureSkipVerify on the http client transport tls client config used by the Client

func WithRetryCount

func WithRetryCount(retryCount int) OptionFunc

WithRetryCount sets the number of times the acme client retries when receiving an api error (eg, nonce failures, etc). Default: 5

func WithUserAgentSuffix

func WithUserAgentSuffix(userAgentSuffix string) OptionFunc

WithUserAgentSuffix appends a user agent suffix for http requests to acme resources

type Order

type Order struct {
	Status         string       `json:"status"`
	Expires        time.Time    `json:"expires"`
	Identifiers    []Identifier `json:"identifiers"`
	Authorizations []string     `json:"authorizations"`
	Error          Problem      `json:"error"`
	Finalize       string       `json:"finalize"`
	Certificate    string       `json:"certificate"`

	// URL for the order object.
	// Provided by the rel="Location" Link http header
	URL string `json:"-"`
}

Order object returned when fetching or creating a new order.

type OrderList

type OrderList struct {
	Orders []string `json:"orders"`

	// Order list pagination, url to next orders.
	// Provided by the rel="next" Link http header
	Next string `json:"-"`
}

OrderList of challenge objects.

type Problem

type Problem struct {
	Status int `json:"status"`

	Type        string `json:"type"`
	Detail      string `json:"detail"`
	Instance    string `json:"instance"`
	SubProblems []struct {
		Type       string `json:"type"`
		Detail     string `json:"detail"`
		Identifier Identifier
	} `json:"subproblems"`
}

Problem represents an error returned by an acme server.

func (Problem) Error

func (err Problem) Error() string

Returns a human readable error string.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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