README

eggsampler/acme

GoDoc

About

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

The library is designed to provide a 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 registation, 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

Boulder

Tests can be run against a local instance of boulder running the config-next configuration.

This needs to have the chaltestsrv responding to http01 challenges. This is currently disabled by default and can be enabled by editing test/startservers.py and ensure chaltestsrv is running with the flag --http01 :5002 instead of --http01 ""

By default, tests run using the boulder client unless the environment variable ACME_SERVER is set to pebble, eg: ACME_SERVER=boulder go test -v

Pebble

Alternatively, tests can be run against a local instance of pebble running with the PEBBLE_VA_ALWAYS_VALID=1 environment variable.

Currently pebble does not support account key changes or deactivating authorizations, so these tests are disabled.

To run tests using the pebble client the environment variable ACME_SERVER must be set to pebble, eg: ACME_SERVER=pebble go test -v

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 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 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 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

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