acme

package
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2018 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package acme provides an implementation of the Automatic Certificate Management Environment (ACME) spec. See https://tools.ietf.org/html/draft-ietf-acme-acme-09 for details.

Most common scenarios will want to use autocert subdirectory instead, which provides automatic access to certificates from Let's Encrypt and any other ACME-based CA.

This package is a work in progress and makes no API stability promises.

Index

Constants

View Source
const (
	StatusUnknown     = "unknown"
	StatusPending     = "pending"
	StatusProcessing  = "processing"
	StatusValid       = "valid"
	StatusInvalid     = "invalid"
	StatusRevoked     = "revoked"
	StatusDeactivated = "deactivated"
	StatusReady       = "ready"
)

ACME server response statuses used to describe Account, Authorization, and Challenge states.

View Source
const LetsEncryptURL = "https://acme-v02.api.letsencrypt.org/directory"

LetsEncryptURL is the Directory endpoint of Let's Encrypt CA.

Variables

View Source
var ErrUnsupportedKey = errors.New("acme: unknown key type; only RSA and ECDSA are supported")

ErrUnsupportedKey is returned when an unsupported key type is encountered.

Functions

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.

func RateLimit

func RateLimit(err error) (time.Time, bool)

RateLimit reports whether err represents a rate limit error and any Retry-After duration returned by the server.

See the following for more details on rate limiting: https://tools.ietf.org/html/draft-ietf-acme-acme-09#section-6.5

Types

type Account

type Account struct {
	// URL uniquely identifies the account.
	URL string

	// Status is the status of the account. Valid values are StatusValid,
	// StatusDeactivated, and StatusRevoked.
	Status string

	// Contact is a list of URLs that the server can use to contact the client
	// for issues related to this account.
	Contact []string

	// TermsAgreed indicates agreement with the terms of service. It is not
	// modifiable after account creation.
	TermsAgreed bool

	// OrdersURL is the URL used to fetch a list of orders submitted by this
	// account.
	OrdersURL string
}

Account is a user account. It is associated with a private key.

type Authorization

type Authorization struct {
	// URL uniquely identifies the authorization.
	URL string

	// Status is the status of the authorization. Valid values are
	// StatusPending, StatusProcessing, StatusValid, StatusInvalid, and
	// StatusRevoked.
	Status string

	// Identifier is the identifier that the account is authorized to represent.
	Identifier AuthzID

	// Expires is the timestamp after which the server will consider this authorization invalid.
	Expires time.Time

	// Challenges is the list of challenges that the client can fulfill in order
	// to prove posession of the identifier. For valid/invalid authorizations,
	// this is the list of challenges that were used.
	Challenges []*Challenge

	// Wildcard is set to true if this authorization is for a 'wildcard' dnsName.
	Wildcard bool
}

Authorization encodes an authorization response.

type AuthorizationError

type AuthorizationError struct {
	// Authorization is the authorization that is invalid.
	Authorization *Authorization
}

AuthorizationError is returned when an authorization is marked as invalid.

func (AuthorizationError) Error

func (e AuthorizationError) Error() string

type AuthzID

type AuthzID struct {
	Type  string // The type of identifier, e.g. "dns".
	Value string // The identifier itself, e.g. "example.org".
}

AuthzID is an identifier that an account is authorized to represent.

type CRLReasonCode

type CRLReasonCode int

CRLReasonCode identifies the reason for a certificate revocation.

const (
	CRLReasonUnspecified          CRLReasonCode = 0
	CRLReasonKeyCompromise        CRLReasonCode = 1
	CRLReasonCACompromise         CRLReasonCode = 2
	CRLReasonAffiliationChanged   CRLReasonCode = 3
	CRLReasonSuperseded           CRLReasonCode = 4
	CRLReasonCessationOfOperation CRLReasonCode = 5
	CRLReasonCertificateHold      CRLReasonCode = 6
	CRLReasonRemoveFromCRL        CRLReasonCode = 8
	CRLReasonPrivilegeWithdrawn   CRLReasonCode = 9
	CRLReasonAACompromise         CRLReasonCode = 10
)

CRL reason codes as defined in RFC 5280.

type Challenge

type Challenge struct {
	// Type is the challenge type, e.g. "http-01" or "dns-01".
	Type string

	// URL is the URL where a challenge response can be posted.
	URL string

	// Token is a random value that uniquely identifies the challenge.
	Token string

	// Validated is the time at which the server validated this challenge.
	Validated time.Time

	// Status identifies the status of this challenge. Valid values are
	// StatusPending, StatusValid, and StatusInvalid.
	Status string

	// Error indicates the errors that occurred while the server was validating
	// this challenge.
	Error *Error
}

A Challenge is a CA challenge for an identifier.

type Client

type Client struct {
	// Key is the account key used to register with a CA and sign requests.
	// Key.Public() must return a *rsa.PublicKey or *ecdsa.PublicKey.
	Key crypto.Signer

	// HTTPClient optionally specifies an HTTP client to use
	// instead of http.DefaultClient.
	HTTPClient *http.Client

	// DirectoryURL points to the CA directory endpoint.
	// If empty, LetsEncryptURL is used.
	// Mutating this value after a successful call of Client's Discover method
	// will have no effect.
	DirectoryURL string
	// contains filtered or unexported fields
}

Client is an ACME client. The only required field is Key. An example of creating a client with a new key is as follows:

key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
	log.Fatal(err)
}
client := &Client{Key: key}

func (*Client) AcceptChallenge

func (c *Client) AcceptChallenge(ctx context.Context, chal *Challenge) (*Challenge, error)

AcceptChallenge informs the server that the client accepts one of its authorization challenges previously obtained with CreateOrder/GetAuthorization.

The server will then perform the validation asynchronously.

func (*Client) CreateAccount

func (c *Client) CreateAccount(ctx context.Context, a *Account) (*Account, error)

CreateAccount creates a new account. It returns the account details from the server and does not modify the account argument that it is called with.

func (*Client) CreateOrder

func (c *Client) CreateOrder(ctx context.Context, order *Order) (*Order, error)

CreateOrder creates a new certificate order. The input order argument is not modified and can be built using NewOrder.

func (*Client) DNS01ChallengeRecord

func (c *Client) DNS01ChallengeRecord(token string) (string, error)

DNS01ChallengeRecord returns a DNS record value for a dns-01 challenge response. A TXT record containing the returned value must be provisioned under "_acme-challenge" name of the domain being validated.

The token argument is a Challenge.Token value.

func (*Client) DeactivateAuthorization

func (c *Client) DeactivateAuthorization(ctx context.Context, url string) error

DeactivateAuthorization relinquishes an existing authorization identified by the given URL.

If successful, the caller will be required to obtain a new authorization before a new certificate for the domain associated with the authorization is issued.

It does not revoke existing certificates.

func (*Client) Discover

func (c *Client) Discover(ctx context.Context) (Directory, error)

Discover performs ACME server discovery using c.DirectoryURL.

It caches successful result. So, subsequent calls will not result in a network round-trip. This also means mutating c.DirectoryURL after successful call of this method will have no effect.

func (*Client) FinalizeOrder

func (c *Client) FinalizeOrder(ctx context.Context, finalizeURL string, csr []byte) (der [][]byte, err error)

FinalizeOrder finalizes an order using the Certificate Signing Request csr encoded in DER format. If the order has not been fully authorized, an OrderPendingError will be returned.

After requesting finalization, FinalizOrder polls the order using WaitOrder until it is finalized and then fetches the associated certificate and returns it.

Callers are encouraged to parse the returned certificate chain to ensure it is valid and has the expected attributes.

func (*Client) GetAccount

func (c *Client) GetAccount(ctx context.Context) (*Account, error)

GetAccount retrieves the account that the client is configured with.

func (*Client) GetAuthorization

func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorization, error)

GetAuthorization retrieves an authorization identified by the given URL.

If a caller needs to poll an authorization until its status is final, see the WaitAuthorization method.

func (*Client) GetChallenge

func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error)

GetChallenge retrieves the current status of a challenge.

A client typically polls a challenge status using this method.

func (*Client) GetOrder

func (c *Client) GetOrder(ctx context.Context, url string) (*Order, error)

GetOrder retrieves an order identified by url.

If a caller needs to poll an order until its status is final, see the WaitOrder method.

func (*Client) HTTP01ChallengePath

func (c *Client) HTTP01ChallengePath(token string) string

HTTP01ChallengePath returns the URL path at which the response for an http-01 challenge should be provided by the servers. The response value can be obtained with HTTP01ChallengeResponse.

The token argument is a Challenge.Token value.

func (*Client) HTTP01ChallengeResponse

func (c *Client) HTTP01ChallengeResponse(token string) (string, error)

HTTP01ChallengeResponse returns the response for an http-01 challenge. Servers should respond with the value to HTTP requests at the URL path provided by HTTP01ChallengePath to validate the challenge and prove control over a domain name.

The token argument is a Challenge.Token value.

func (*Client) RevokeCert

func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error

RevokeCert revokes a previously issued certificate cert, provided in DER format.

If key is nil, the account must have been used to issue the certificate or have valid authorizations for all of the identifiers in the certificate. If key is provided, it must be the certificate's private key.

func (*Client) UpdateAccount

func (c *Client) UpdateAccount(ctx context.Context, a *Account) (*Account, error)

UpdateAccount updates an existing account. It returns an updated account copy. The provided account is not modified.

func (*Client) WaitAuthorization

func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorization, error)

WaitAuthorization retrieves authorization details. If the authorization is not in a final state (StatusValid/StatusInvalid), it retries the request until the authorization is final, ctx is cancelled by the caller, an error response is received, or the ACME CA responded with a 4xx error.

It returns a non-nil Authorization only if its Status is StatusValid. In all other cases WaitAuthorization returns an error. If the Status is StatusInvalid or StatusDeactivated, the returned error will be of type AuthorizationError.

func (*Client) WaitOrder

func (c *Client) WaitOrder(ctx context.Context, url string) (*Order, error)

WaitOrder waits for an order to transition from StatusProcessing to a final state (StatusValid/StatusInvalid), it retries the request until the order is final, ctx is cancelled by the caller, or an error response is received.

It returns a non-nil Order only if its Status is StatusValid. In all other cases WaitOrder returns an error. If the Status is StatusInvalid, the returned error will be of type OrderInvalidError. If the status is StatusPending, the returned error will be of type OrderPendingError.

type Directory

type Directory struct {
	// NewNonceURL is used to retrieve new nonces.
	NewNonceURL string

	// NewAccountURL is used to create new accounts.
	NewAccountURL string

	// NewOrderURL is used to create new orders.
	NewOrderURL string

	// NewAuthzURL is used to create new authorizations.
	NewAuthzURL string

	// RevokeCertURL is used to revoke a certificate.
	RevokeCertURL string

	// KeyChangeURL is used to change the account key.
	KeyChangeURL string

	// Terms is a URL identifying the current terms of service.
	Terms string

	// Website is an HTTP or HTTPS URL locating a website
	// providing more information about the ACME server.
	Website string

	// CAA consists of lowercase hostname elements, which the ACME server
	// recognises as referring to itself for the purposes of CAA record validation
	// as defined in RFC6844.
	CAA []string

	// ExternalAccountRequired, if true, indicates that the CA requires that all
	// new account requests include an ExternalAccountBinding field associating
	// the new account with an external account.
	ExternalAccountRequired bool
}

Directory is ACME server discovery data.

type Error

type Error struct {
	// StatusCode is The HTTP status code generated by the origin server.
	StatusCode int

	// Type is a URI that identifies the problem type, typically in
	// a "urn:ietf:params:acme:error:xxx" form.
	Type string

	// Detail is a human-readable explanation specific to this occurrence of the problem.
	Detail string

	// Subproblems is an optional list of additional error information, usually
	// indicating problems with specific identifiers during authorization.
	Subproblems []Subproblem

	// Header is the original server error response headers.
	// It may be nil.
	Header http.Header
}

Error is an ACME error as defined in RFC 7807, Problem Details for HTTP APIs.

func (*Error) Error

func (e *Error) Error() string

type Order

type Order struct {
	// URL uniquely identifies the order.
	URL string

	// Status is the status of the order. It will be one of StatusPending,
	// StatusReady, StatusProcessing, StatusValid, and StatusInvalid.
	Status string

	// Expires is the teimstamp after which the server will consider the order invalid.
	Expires time.Time

	// Identifiers is a list of identifiers that the order pertains to.
	Identifiers []AuthzID

	// NotBefore is an optional requested value of the notBefore field in the certificate.
	NotBefore time.Time

	// NotAfter is an optional requested value of the notAfter field in the certificate.
	NotAfter time.Time

	// Error is the error that occurred while processing the order, if any.
	Error *Error

	// Authorizations is a list of URLs for authorizations that the client needs
	// to complete before the requested certificate can be issued. For
	// valid/invalid orders, these are the authorizations that were completed.
	Authorizations []string

	// FinalizeURL is the URL that is used to finalize the Order.
	FinalizeURL string

	// CertificateURL is the URL for the certificate that has been issued in
	// response to this order.
	CertificateURL string

	// RetryAfter is the timestamp, if any, to wait for before fetching this
	// order again.
	RetryAfter time.Time
}

An Order represents a request for a certificate and is used to track the progress through to issuance.

func NewOrder

func NewOrder(domains ...string) *Order

NewOrder creates a new order with the domains provided, suitable for creating a TLS certificate order with CreateOrder.

type OrderInvalidError

type OrderInvalidError struct {
	// Order is the order that is invalid.
	Order *Order
}

OrderInvalidError is returned when an order is marked as invalid.

func (OrderInvalidError) Error

func (e OrderInvalidError) Error() string

type OrderPendingError

type OrderPendingError struct {
	// Order is the order that is pending.
	Order *Order
}

OrderPendingError is returned when an order is still pending after an attempted finalization.

func (OrderPendingError) Error

func (e OrderPendingError) Error() string

type Subproblem

type Subproblem struct {
	// Type is a URI that identifies the subproblem type, typically in
	// "urn:ietf:params:acme:error:xxx" form.
	Type string

	// Detail is a human-readable explanation specific to this occurrence of the
	// subproblem.
	Detail string

	// Identifier optionally indicates the identifier that this subproblem is about.
	Identifier *AuthzID
}

An Subproblem is additional error detail that is included in an Error, usually indicating a problem with a specific identifier during authorization.

Jump to

Keyboard shortcuts

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