acme

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Jun 20, 2023 License: Apache-2.0 Imports: 27 Imported by: 60

Documentation

Overview

Package acme fully implements the ACME protocol specification as described in RFC 8555: https://tools.ietf.org/html/rfc8555.

It is designed to work smoothly in large-scale deployments with high resilience to errors and intermittent network or server issues, with retries built-in at every layer of the HTTP request stack.

NOTE: This is a low-level API. Most users will want the mholt/acmez package which is more concerned with configuring challenges and implementing the order flow. However, using this package directly is recommended for advanced use cases having niche requirements. See the examples in the examples/plumbing folder for a tutorial.

Index

Constants

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

Possible status values. From several spec sections: - Account §7.1.2 (valid, deactivated, revoked) - Order §7.1.3 (pending, ready, processing, valid, invalid) - Authorization §7.1.4 (pending, valid, invalid, deactivated, expired, revoked) - Challenge §7.1.5 (pending, processing, valid, invalid) - Status changes §7.1.6

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

	ReasonRemoveFromCRL      // 8
	ReasonPrivilegeWithdrawn // 9
	ReasonAACompromise       // 10
)

Reasons for revoking a certificate, as defined by RFC 5280 §5.3.1. https://tools.ietf.org/html/rfc5280#section-5.3.1

View Source
const (
	ChallengeTypeHTTP01         = "http-01"          // RFC 8555 §8.3
	ChallengeTypeDNS01          = "dns-01"           // RFC 8555 §8.4
	ChallengeTypeTLSALPN01      = "tls-alpn-01"      // RFC 8737 §3
	ChallengeTypeDeviceAttest01 = "device-attest-01" // draft-acme-device-attest-00 §5
)

The standard or well-known ACME challenge types.

View Source
const (
	// The ACME error URN prefix.
	ProblemTypeNamespace = "urn:ietf:params:acme:error:"

	ProblemTypeAccountDoesNotExist     = ProblemTypeNamespace + "accountDoesNotExist"
	ProblemTypeAlreadyRevoked          = ProblemTypeNamespace + "alreadyRevoked"
	ProblemTypeBadCSR                  = ProblemTypeNamespace + "badCSR"
	ProblemTypeBadNonce                = ProblemTypeNamespace + "badNonce"
	ProblemTypeBadPublicKey            = ProblemTypeNamespace + "badPublicKey"
	ProblemTypeBadRevocationReason     = ProblemTypeNamespace + "badRevocationReason"
	ProblemTypeBadSignatureAlgorithm   = ProblemTypeNamespace + "badSignatureAlgorithm"
	ProblemTypeCAA                     = ProblemTypeNamespace + "caa"
	ProblemTypeCompound                = ProblemTypeNamespace + "compound"
	ProblemTypeConnection              = ProblemTypeNamespace + "connection"
	ProblemTypeDNS                     = ProblemTypeNamespace + "dns"
	ProblemTypeExternalAccountRequired = ProblemTypeNamespace + "externalAccountRequired"
	ProblemTypeIncorrectResponse       = ProblemTypeNamespace + "incorrectResponse"
	ProblemTypeInvalidContact          = ProblemTypeNamespace + "invalidContact"
	ProblemTypeMalformed               = ProblemTypeNamespace + "malformed"
	ProblemTypeOrderNotReady           = ProblemTypeNamespace + "orderNotReady"
	ProblemTypeRateLimited             = ProblemTypeNamespace + "rateLimited"
	ProblemTypeRejectedIdentifier      = ProblemTypeNamespace + "rejectedIdentifier"
	ProblemTypeServerInternal          = ProblemTypeNamespace + "serverInternal"
	ProblemTypeTLS                     = ProblemTypeNamespace + "tls"
	ProblemTypeUnauthorized            = ProblemTypeNamespace + "unauthorized"
	ProblemTypeUnsupportedContact      = ProblemTypeNamespace + "unsupportedContact"
	ProblemTypeUnsupportedIdentifier   = ProblemTypeNamespace + "unsupportedIdentifier"
	ProblemTypeUserActionRequired      = ProblemTypeNamespace + "userActionRequired"
)

Standard token values for the "type" field of problems, as defined in RFC 8555 §6.7: https://tools.ietf.org/html/rfc8555#section-6.7

"To facilitate automatic response to errors, this document defines the following standard tokens for use in the 'type' field (within the ACME URN namespace 'urn:ietf:params:acme:error:') ... This list is not exhaustive. The server MAY return errors whose 'type' field is set to a URI other than those defined above."

Variables

This section is empty.

Functions

func CertIDSequence added in v1.1.1

func CertIDSequence(_ context.Context, certChain []*x509.Certificate, hash crypto.Hash, client *http.Client) (string, error)

CertIDSequence returns the "base64url-encoded [RFC4648] bytes of a DER-encoded CertID ASN.1 sequence [RFC6960]" without padding for the given certificate chain. It is used primarily for requests to OCSP and ARI.

The certificate chain must contain at least two elements: an end-entity certificate first, followed by an issuer certificate second. Of the end-entity certificate, only the SerialNumber field is required; and of the issuer certificate, only the RawSubjectPublicKeyInfo and RawSubject fields are required. If the issuer certificate is not provided, then it will be downloaded if the end-entity certificate contains the IssuingCertificateURL.

As the return value may be used often during a certificate's lifetime, and in bulk with potentially tens of thousands of other certificates, it may be preferable to store or cache this value so that ASN.1 documents do not need to be repeatedly decoded and re-encoded.

Types

type Account

type Account struct {
	// status (required, string):  The status of this account.  Possible
	// values are "valid", "deactivated", and "revoked".  The value
	// "deactivated" should be used to indicate client-initiated
	// deactivation whereas "revoked" should be used to indicate server-
	// initiated deactivation.  See Section 7.1.6.
	Status string `json:"status"`

	// contact (optional, array of string):  An array of URLs that the
	// server can use to contact the client for issues related to this
	// account.  For example, the server may wish to notify the client
	// about server-initiated revocation or certificate expiration.  For
	// information on supported URL schemes, see Section 7.3.
	Contact []string `json:"contact,omitempty"`

	// termsOfServiceAgreed (optional, boolean):  Including this field in a
	// newAccount request, with a value of true, indicates the client's
	// agreement with the terms of service.  This field cannot be updated
	// by the client.
	TermsOfServiceAgreed bool `json:"termsOfServiceAgreed,omitempty"`

	// externalAccountBinding (optional, object):  Including this field in a
	// newAccount request indicates approval by the holder of an existing
	// non-ACME account to bind that account to this ACME account.  This
	// field is not updateable by the client (see Section 7.3.4).
	//
	// Use SetExternalAccountBinding() to set this field's value properly.
	ExternalAccountBinding json.RawMessage `json:"externalAccountBinding,omitempty"`

	// orders (required, string):  A URL from which a list of orders
	// submitted by this account can be fetched via a POST-as-GET
	// request, as described in Section 7.1.2.1.
	Orders string `json:"orders"`

	// In response to new-account, "the server returns this account
	// object in a 201 (Created) response, with the account URL
	// in a Location header field." §7.3
	//
	// We transfer the value from the header to this field for
	// storage and recall purposes.
	Location string `json:"location,omitempty"`

	// The private key to the account. Because it is secret, it is
	// not serialized as JSON and must be stored separately (usually
	// a PEM-encoded file).
	PrivateKey crypto.Signer `json:"-"`
}

Account represents a set of metadata associated with an account as defined by the ACME spec §7.1.2: https://tools.ietf.org/html/rfc8555#section-7.1.2

func (*Account) SetExternalAccountBinding

func (a *Account) SetExternalAccountBinding(ctx context.Context, client *Client, eab EAB) error

SetExternalAccountBinding sets the ExternalAccountBinding field of the account. It only sets the field value; it does not register the account with the CA. (The client parameter is necessary because the EAB encoding depends on the directory.)

type Authorization

type Authorization struct {
	// identifier (required, object):  The identifier that the account is
	// authorized to represent.
	Identifier Identifier `json:"identifier"`

	// status (required, string):  The status of this authorization.
	// Possible values are "pending", "valid", "invalid", "deactivated",
	// "expired", and "revoked".  See Section 7.1.6.
	Status string `json:"status"`

	// expires (optional, string):  The timestamp after which the server
	// will consider this authorization invalid, encoded in the format
	// specified in [RFC3339].  This field is REQUIRED for objects with
	// "valid" in the "status" field.
	Expires time.Time `json:"expires,omitempty"`

	// challenges (required, array of objects):  For pending authorizations,
	// the challenges that the client can fulfill in order to prove
	// possession of the identifier.  For valid authorizations, the
	// challenge that was validated.  For invalid authorizations, the
	// challenge that was attempted and failed.  Each array entry is an
	// object with parameters required to validate the challenge.  A
	// client should attempt to fulfill one of these challenges, and a
	// server should consider any one of the challenges sufficient to
	// make the authorization valid.
	Challenges []Challenge `json:"challenges"`

	// wildcard (optional, boolean):  This field MUST be present and true
	// for authorizations created as a result of a newOrder request
	// containing a DNS identifier with a value that was a wildcard
	// domain name.  For other authorizations, it MUST be absent.
	// Wildcard domain names are described in Section 7.1.3.
	Wildcard bool `json:"wildcard,omitempty"`

	// "The server allocates a new URL for this authorization and returns a
	// 201 (Created) response with the authorization URL in the Location
	// header field" §7.4.1
	//
	// We transfer the value from the header to this field for storage and
	// recall purposes.
	Location string `json:"-"`
}

Authorization "represents a server's authorization for an account to represent an identifier. In addition to the identifier, an authorization includes several metadata fields, such as the status of the authorization (e.g., 'pending', 'valid', or 'revoked') and which challenges were used to validate possession of the identifier." §7.1.4

func (Authorization) IdentifierValue

func (authz Authorization) IdentifierValue() string

IdentifierValue returns the Identifier.Value field, adjusted according to the Wildcard field.

type Certificate

type Certificate struct {
	// The certificate resource URL as provisioned by
	// the ACME server. Some ACME servers may split
	// the chain into multiple URLs that are Linked
	// together, in which case this URL represents the
	// starting point.
	URL string `json:"url"`

	// The PEM-encoded certificate chain, end-entity first.
	// It is excluded from JSON marshalling since the
	// chain is usually stored in its own file.
	ChainPEM []byte `json:"-"`

	// For convenience, the directory URL of the ACME CA that
	// issued this certificate. This field is not part of the
	// ACME spec, but it can be useful to save this along with
	// the certificate for restoring a lost ACME client config.
	CA string `json:"ca,omitempty"`
}

Certificate represents a certificate chain, which we usually refer to as "a certificate" because in practice an end-entity certificate is seldom useful/practical without a chain. This structure can be JSON-encoded and stored alongside the certificate chain to preserve potentially-useful metadata.

type Challenge

type Challenge struct {

	// type (required, string):  The type of challenge encoded in the
	// object.
	Type string `json:"type"`

	// url (required, string):  The URL to which a response can be posted.
	URL string `json:"url"`

	// status (required, string):  The status of this challenge.  Possible
	// values are "pending", "processing", "valid", and "invalid" (see
	// Section 7.1.6).
	Status string `json:"status"`

	// validated (optional, string):  The time at which the server validated
	// this challenge, encoded in the format specified in [RFC3339].
	// This field is REQUIRED if the "status" field is "valid".
	Validated string `json:"validated,omitempty"`

	// error (optional, object):  Error that occurred while the server was
	// validating the challenge, if any, structured as a problem document
	// [RFC7807].  Multiple errors can be indicated by using subproblems
	// Section 6.7.1.  A challenge object with an error MUST have status
	// equal to "invalid".
	Error *Problem `json:"error,omitempty"`

	// "The token for a challenge is a string comprised entirely of
	// characters in the URL-safe base64 alphabet." §8.1
	//
	// Used by the http-01, tls-alpn-01, and dns-01 challenges.
	Token string `json:"token,omitempty"`

	// A key authorization is a string that concatenates the token for the
	// challenge with a key fingerprint, separated by a "." character (§8.1):
	//
	//     keyAuthorization = token || '.' || base64url(Thumbprint(accountKey))
	//
	// This client package automatically assembles and sets this value for you.
	KeyAuthorization string `json:"keyAuthorization,omitempty"`

	// We attach the identifier that this challenge is associated with, which
	// may be useful information for solving a challenge. It is not part of the
	// structure as defined by the spec but is added by us to provide enough
	// information to solve the DNS-01 challenge.
	Identifier Identifier `json:"identifier,omitempty"`

	// Payload contains a JSON-marshallable value that will be sent to the CA
	// when responding to challenges. If not set, an empty JSON body "{}" will
	// be included in the POST request. This field is applicable when responding
	// to "device-attest-01" challenges.
	Payload any `json:"-"`
}

Challenge holds information about an ACME challenge.

"An ACME challenge object represents a server's offer to validate a client's possession of an identifier in a specific way. Unlike the other objects listed above, there is not a single standard structure for a challenge object. The contents of a challenge object depend on the validation method being used. The general structure of challenge objects and an initial set of validation methods are described in Section 8." §7.1.5

func (Challenge) DNS01KeyAuthorization

func (c Challenge) DNS01KeyAuthorization() string

DNS01KeyAuthorization encodes a key authorization value to be used in a TXT record for the _acme-challenge DNS record.

"A client fulfills this challenge by constructing a key authorization from the 'token' value provided in the challenge and the client's account key. The client then computes the SHA-256 digest [FIPS180-4] of the key authorization.

The record provisioned to the DNS contains the base64url encoding of this digest." §8.4

func (Challenge) DNS01TXTRecordName

func (c Challenge) DNS01TXTRecordName() string

DNS01TXTRecordName returns the name of the TXT record to create for solving the dns-01 challenge.

"The client constructs the validation domain name by prepending the label '_acme-challenge' to the domain name being validated, then provisions a TXT record with the digest value under that name." §8.4

func (Challenge) HTTP01ResourcePath

func (c Challenge) HTTP01ResourcePath() string

HTTP01ResourcePath returns the URI path for solving the http-01 challenge.

"The path at which the resource is provisioned is comprised of the fixed prefix '/.well-known/acme-challenge/', followed by the 'token' value in the challenge." §8.3

type Client

type Client struct {
	// The ACME server's directory endpoint.
	Directory string

	// Custom HTTP client.
	HTTPClient *http.Client

	// Augmentation of the User-Agent header. Please set
	// this so that CAs can troubleshoot bugs more easily.
	UserAgent string

	// Delay between poll attempts. Only used if server
	// does not supply a Retry-Afer header. Default: 250ms
	PollInterval time.Duration

	// Maximum duration for polling. Default: 5m
	PollTimeout time.Duration

	// An optional logger. Default: no logs
	Logger *zap.Logger
	// contains filtered or unexported fields
}

Client facilitates ACME client operations as defined by the spec.

Because the client is synchronized for concurrent use, it should not be copied.

Many errors that are returned by a Client are likely to be of type Problem as long as the ACME server returns a structured error response. This package wraps errors that may be of type Problem, so you can access the details using the conventional Go pattern:

var problem Problem
if errors.As(err, &problem) {
    log.Printf("Houston, we have a problem: %+v", problem)
}

All Problem errors originate from the ACME server.

func (*Client) AccountKeyRollover

func (c *Client) AccountKeyRollover(ctx context.Context, account Account, newPrivateKey crypto.Signer) (Account, error)

AccountKeyRollover changes an account's associated key.

"To change the key associated with an account, the client sends a request to the server containing signatures by both the old and new keys." §7.3.5

func (*Client) DeactivateAuthorization

func (c *Client) DeactivateAuthorization(ctx context.Context, account Account, authzURL string) (Authorization, error)

DeactivateAuthorization deactivates an authorization on the server, which is a good idea if the authorization is not going to be utilized by the client.

"If a client wishes to relinquish its authorization to issue certificates for an identifier, then it may request that the server deactivate each authorization associated with it by sending POST requests with the static object {"status": "deactivated"} to each authorization URL." §7.5.2

func (*Client) FinalizeOrder

func (c *Client) FinalizeOrder(ctx context.Context, account Account, order Order, csrASN1DER []byte) (Order, error)

FinalizeOrder finalizes the order with the server and polls under the server has updated the order status. The CSR must be in ASN.1 DER-encoded format. If this succeeds, the certificate is ready to download once this returns.

"Once the client believes it has fulfilled the server's requirements, it should send a POST request to the order resource's finalize URL." §7.4

func (*Client) GetAccount

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

GetAccount looks up an account on the ACME server.

"If a client wishes to find the URL for an existing account and does not want an account to be created if one does not already exist, then it SHOULD do so by sending a POST request to the newAccount URL with a JWS whose payload has an 'onlyReturnExisting' field set to 'true'." §7.3.1

func (*Client) GetAuthorization

func (c *Client) GetAuthorization(ctx context.Context, account Account, authzURL string) (Authorization, error)

GetAuthorization fetches an authorization object from the server.

"Authorization resources are created by the server in response to newOrder or newAuthz requests submitted by an account key holder; their URLs are provided to the client in the responses to these requests."

"When a client receives an order from the server in reply to a newOrder request, it downloads the authorization resources by sending POST-as-GET requests to the indicated URLs. If the client initiates authorization using a request to the newAuthz resource, it will have already received the pending authorization object in the response to that request." §7.5

func (*Client) GetCertificateChain

func (c *Client) GetCertificateChain(ctx context.Context, account Account, certURL string) ([]Certificate, error)

GetCertificateChain downloads all available certificate chains originating from the given certURL. This is to be done after an order is finalized.

"To download the issued certificate, the client simply sends a POST- as-GET request to the certificate URL."

"The server MAY provide one or more link relation header fields [RFC8288] with relation 'alternate'. Each such field SHOULD express an alternative certificate chain starting with the same end-entity certificate. This can be used to express paths to various trust anchors. Clients can fetch these alternates and use their own heuristics to decide which is optimal." §7.4.2

func (*Client) GetDirectory

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

GetDirectory retrieves the directory configured at c.Directory. It is NOT necessary to call this to provision the client. It is only useful if you want to access a copy of the directory yourself.

func (*Client) GetOrder added in v1.0.3

func (c *Client) GetOrder(ctx context.Context, account Account, order Order) (Order, error)

GetOrder retrieves an order from the server. The Order's Location field must be populated.

func (*Client) GetRenewalInfo added in v1.1.1

func (c *Client) GetRenewalInfo(ctx context.Context, b64CertIDSeq string) (RenewalInfo, error)

GetRenewalInfo returns the ACME Renewal Information (ARI) for the certificate represented by the "base64url-encoded [RFC4648] bytes of a DER-encoded CertID ASN.1 sequence [RFC6960]" without padding (call `CertIDSequence()` to get this value). It tacks on the Retry-After value if present.

func (*Client) InitiateChallenge

func (c *Client) InitiateChallenge(ctx context.Context, account Account, challenge Challenge) (Challenge, error)

InitiateChallenge "indicates to the server that it is ready for the challenge validation by sending an empty JSON body ('{}') carried in a POST request to the challenge URL (not the authorization URL)." §7.5.1

func (*Client) NewAccount

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

NewAccount creates a new account on the ACME server.

"A client creates a new account with the server by sending a POST request to the server's newAccount URL." §7.3

func (*Client) NewAuthorization

func (c *Client) NewAuthorization(ctx context.Context, account Account, id Identifier) (Authorization, error)

NewAuthorization creates a new authorization for an identifier using the newAuthz endpoint of the directory, if available. This function creates authzs out of the regular order flow.

"Note that because the identifier in a pre-authorization request is the exact identifier to be included in the authorization object, pre- authorization cannot be used to authorize issuance of certificates containing wildcard domain names." §7.4.1

func (*Client) NewOrder

func (c *Client) NewOrder(ctx context.Context, account Account, order Order) (Order, error)

NewOrder creates a new order with the server.

"The client begins the certificate issuance process by sending a POST request to the server's newOrder resource." §7.4

func (*Client) PollAuthorization

func (c *Client) PollAuthorization(ctx context.Context, account Account, authz Authorization) (Authorization, error)

PollAuthorization polls the authorization resource endpoint until the authorization is considered "finalized" which means that it either succeeded, failed, or was abandoned. It blocks until that happens or until the configured timeout.

"Usually, the validation process will take some time, so the client will need to poll the authorization resource to see when it is finalized."

"For challenges where the client can tell when the server has validated the challenge (e.g., by seeing an HTTP or DNS request from the server), the client SHOULD NOT begin polling until it has seen the validation request from the server." §7.5.1

func (*Client) RevokeCertificate

func (c *Client) RevokeCertificate(ctx context.Context, account Account, cert *x509.Certificate, certKey crypto.Signer, reason int) error

RevokeCertificate revokes the given certificate. If the certificate key is not provided, then the account key is used instead. See §7.6.

func (*Client) UpdateAccount

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

UpdateAccount updates account information on the ACME server.

"If the client wishes to update this information in the future, it sends a POST request with updated information to the account URL. The server MUST ignore any updates to the 'orders' field, 'termsOfServiceAgreed' field (see Section 7.3.3), the 'status' field (except as allowed by Section 7.3.6), or any other fields it does not recognize." §7.3.2

This method uses the account.Location value as the account URL.

func (*Client) UpdateRenewalInfo added in v1.1.1

func (c *Client) UpdateRenewalInfo(ctx context.Context, account Account, b64CertIDSeq string) error

UpdateRenewalInfo notifies the ACME server that the certificate represented by b64CertIDSeq has been replaced. The b64CertIDSeq string can be obtained by calling `CertIDSequence()`.

type Directory

type Directory struct {
	NewNonce    string         `json:"newNonce"`
	NewAccount  string         `json:"newAccount"`
	NewOrder    string         `json:"newOrder"`
	NewAuthz    string         `json:"newAuthz,omitempty"`
	RevokeCert  string         `json:"revokeCert"`
	KeyChange   string         `json:"keyChange"`
	RenewalInfo string         `json:"renewalInfo,omitempty"` // draft-ietf-acme-ari
	Meta        *DirectoryMeta `json:"meta,omitempty"`
}

Directory acts as an index for the ACME server as specified in the spec: "In order to help clients configure themselves with the right URLs for each ACME operation, ACME servers provide a directory object." §7.1.1

type DirectoryMeta

type DirectoryMeta struct {
	TermsOfService          string   `json:"termsOfService,omitempty"`
	Website                 string   `json:"website,omitempty"`
	CAAIdentities           []string `json:"caaIdentities,omitempty"`
	ExternalAccountRequired bool     `json:"externalAccountRequired,omitempty"`
}

DirectoryMeta is optional extra data that may be included in an ACME server directory. §7.1.1

type EAB

type EAB struct {
	// "The key identifier MUST be an ASCII string." §7.3.4
	KeyID string `json:"key_id"`

	// "The MAC key SHOULD be provided in base64url-encoded
	// form, to maximize compatibility between non-ACME
	// provisioning systems and ACME clients." §7.3.4
	MACKey string `json:"mac_key"`
}

EAB (External Account Binding) contains information necessary to bind or map an ACME account to some other account known by the CA.

External account bindings are "used to associate an ACME account with an existing account in a non-ACME system, such as a CA customer database."

"To enable ACME account binding, the CA operating the ACME server needs to provide the ACME client with a MAC key and a key identifier, using some mechanism outside of ACME." §7.3.4

type Identifier

type Identifier struct {
	// type (required, string):  The type of identifier.  This document
	// defines the "dns" identifier type.  See the registry defined in
	// Section 9.7.7 for any others.
	Type string `json:"type"`

	// value (required, string):  The identifier itself.
	Value string `json:"value"`
}

Identifier is used in order and authorization (authz) objects.

type Order

type Order struct {
	// status (required, string):  The status of this order.  Possible
	// values are "pending", "ready", "processing", "valid", and
	// "invalid".  See Section 7.1.6.
	Status string `json:"status"`

	// expires (optional, string):  The timestamp after which the server
	// will consider this order invalid, encoded in the format specified
	// in [RFC3339].  This field is REQUIRED for objects with "pending"
	// or "valid" in the status field.
	Expires time.Time `json:"expires,omitempty"`

	// identifiers (required, array of object):  An array of identifier
	// objects that the order pertains to.
	Identifiers []Identifier `json:"identifiers"`

	// notBefore (optional, string):  The requested value of the notBefore
	// field in the certificate, in the date format defined in [RFC3339].
	NotBefore *time.Time `json:"notBefore,omitempty"`

	// notAfter (optional, string):  The requested value of the notAfter
	// field in the certificate, in the date format defined in [RFC3339].
	NotAfter *time.Time `json:"notAfter,omitempty"`

	// error (optional, object):  The error that occurred while processing
	// the order, if any.  This field is structured as a problem document
	// [RFC7807].
	Error *Problem `json:"error,omitempty"`

	// authorizations (required, array of string):  For pending orders, the
	// authorizations that the client needs to complete before the
	// requested certificate can be issued (see Section 7.5), including
	// unexpired authorizations that the client has completed in the past
	// for identifiers specified in the order.  The authorizations
	// required are dictated by server policy; there may not be a 1:1
	// relationship between the order identifiers and the authorizations
	// required.  For final orders (in the "valid" or "invalid" state),
	// the authorizations that were completed.  Each entry is a URL from
	// which an authorization can be fetched with a POST-as-GET request.
	Authorizations []string `json:"authorizations"`

	// finalize (required, string):  A URL that a CSR must be POSTed to once
	// all of the order's authorizations are satisfied to finalize the
	// order.  The result of a successful finalization will be the
	// population of the certificate URL for the order.
	Finalize string `json:"finalize"`

	// certificate (optional, string):  A URL for the certificate that has
	// been issued in response to this order.
	Certificate string `json:"certificate"`

	// Similar to new-account, the server returns a 201 response with
	// the URL to the order object in the Location header.
	//
	// We transfer the value from the header to this field for
	// storage and recall purposes.
	Location string `json:"-"`
}

Order is an object that "represents a client's request for a certificate and is used to track the progress of that order through to issuance. Thus, the object contains information about the requested certificate, the authorizations that the server requires the client to complete, and any certificates that have resulted from this order." §7.1.3

type Problem

type Problem struct {
	// "type" (string) - A URI reference [RFC3986] that identifies the
	// problem type.  This specification encourages that, when
	// dereferenced, it provide human-readable documentation for the
	// problem type (e.g., using HTML [W3C.REC-html5-20141028]).  When
	// this member is not present, its value is assumed to be
	// "about:blank". §3.1
	Type string `json:"type"`

	// "title" (string) - A short, human-readable summary of the problem
	// type.  It SHOULD NOT change from occurrence to occurrence of the
	// problem, except for purposes of localization (e.g., using
	// proactive content negotiation; see [RFC7231], Section 3.4). §3.1
	Title string `json:"title,omitempty"`

	// "status" (number) - The HTTP status code ([RFC7231], Section 6)
	// generated by the origin server for this occurrence of the problem.
	// §3.1
	Status int `json:"status,omitempty"`

	// "detail" (string) - A human-readable explanation specific to this
	// occurrence of the problem. §3.1
	//
	// RFC 8555 §6.7: "Clients SHOULD display the 'detail' field of all
	// errors."
	Detail string `json:"detail,omitempty"`

	// "instance" (string) - A URI reference that identifies the specific
	// occurrence of the problem.  It may or may not yield further
	// information if dereferenced. §3.1
	Instance string `json:"instance,omitempty"`

	// "Sometimes a CA may need to return multiple errors in response to a
	// request.  Additionally, the CA may need to attribute errors to
	// specific identifiers.  For instance, a newOrder request may contain
	// multiple identifiers for which the CA cannot issue certificates.  In
	// this situation, an ACME problem document MAY contain the
	// 'subproblems' field, containing a JSON array of problem documents."
	// RFC 8555 §6.7.1
	Subproblems []Subproblem `json:"subproblems,omitempty"`

	// For convenience, we've added this field to associate with a value
	// that is related to or caused the problem. It is not part of the
	// spec, but, if a challenge fails for example, we can associate the
	// error with the problematic authz object by setting this field.
	// Challenge failures will have this set to an Authorization type.
	Resource any `json:"-"`
}

Problem carries the details of an error from HTTP APIs as defined in RFC 7807: https://tools.ietf.org/html/rfc7807 and as extended by RFC 8555 §6.7: https://tools.ietf.org/html/rfc8555#section-6.7

func (Problem) Error

func (p Problem) Error() string

func (Problem) MarshalLogObject added in v1.0.1

func (p Problem) MarshalLogObject(enc zapcore.ObjectEncoder) error

MarshalLogObject satisfies the zapcore.ObjectMarshaler interface. This allows problems to be serialized by the zap logger.

type RenewalInfo added in v1.1.1

type RenewalInfo struct {
	SuggestedWindow struct {
		Start time.Time `json:"start"`
		End   time.Time `json:"end"`
	} `json:"suggestedWindow"`
	ExplanationURL string `json:"explanationURL"`

	// This field is not part of the specified structure, but is
	// important for proper conformance to the specification,
	// so the Retry-After response header will be read and this
	// field will be populated for ACME client consideration.
	// Polling again for renewal info should not occur before
	// this time.
	RetryAfter time.Time `json:"-"`
}

RenewalInfo "is a new resource type introduced to ACME protocol. This new resource both allows clients to query the server for suggestions on when they should renew certificates, and allows clients to inform the server when they have completed renewal (or otherwise replaced the certificate to their satisfaction)."

ACME Renewal Information (ARI): https://datatracker.ietf.org/doc/draft-ietf-acme-ari/

This is a DRAFT specification and the API is subject to change.

type Subproblem

type Subproblem struct {
	Problem

	// "If present, the 'identifier' field MUST contain an ACME
	// identifier (Section 9.7.7)." §6.7.1
	Identifier Identifier `json:"identifier,omitempty"`
}

Subproblem describes a more specific error in a problem according to RFC 8555 §6.7.1: "An ACME problem document MAY contain the 'subproblems' field, containing a JSON array of problem documents, each of which MAY contain an 'identifier' field."

func (Subproblem) MarshalLogObject added in v1.0.1

func (sp Subproblem) MarshalLogObject(enc zapcore.ObjectEncoder) error

MarshalLogObject satisfies the zapcore.ObjectMarshaler interface. This allows subproblems to be serialized by the zap logger.

Jump to

Keyboard shortcuts

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