...

Source file src/golang.org/x/crypto/acme/types.go

Documentation: golang.org/x/crypto/acme

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package acme
     6  
     7  import (
     8  	"crypto"
     9  	"crypto/x509"
    10  	"errors"
    11  	"fmt"
    12  	"net/http"
    13  	"strings"
    14  	"time"
    15  )
    16  
    17  // ACME status values of Account, Order, Authorization and Challenge objects.
    18  // See https://tools.ietf.org/html/rfc8555#section-7.1.6 for details.
    19  const (
    20  	StatusDeactivated = "deactivated"
    21  	StatusExpired     = "expired"
    22  	StatusInvalid     = "invalid"
    23  	StatusPending     = "pending"
    24  	StatusProcessing  = "processing"
    25  	StatusReady       = "ready"
    26  	StatusRevoked     = "revoked"
    27  	StatusUnknown     = "unknown"
    28  	StatusValid       = "valid"
    29  )
    30  
    31  // CRLReasonCode identifies the reason for a certificate revocation.
    32  type CRLReasonCode int
    33  
    34  // CRL reason codes as defined in RFC 5280.
    35  const (
    36  	CRLReasonUnspecified          CRLReasonCode = 0
    37  	CRLReasonKeyCompromise        CRLReasonCode = 1
    38  	CRLReasonCACompromise         CRLReasonCode = 2
    39  	CRLReasonAffiliationChanged   CRLReasonCode = 3
    40  	CRLReasonSuperseded           CRLReasonCode = 4
    41  	CRLReasonCessationOfOperation CRLReasonCode = 5
    42  	CRLReasonCertificateHold      CRLReasonCode = 6
    43  	CRLReasonRemoveFromCRL        CRLReasonCode = 8
    44  	CRLReasonPrivilegeWithdrawn   CRLReasonCode = 9
    45  	CRLReasonAACompromise         CRLReasonCode = 10
    46  )
    47  
    48  var (
    49  	// ErrUnsupportedKey is returned when an unsupported key type is encountered.
    50  	ErrUnsupportedKey = errors.New("acme: unknown key type; only RSA and ECDSA are supported")
    51  
    52  	// ErrAccountAlreadyExists indicates that the Client's key has already been registered
    53  	// with the CA. It is returned by Register method.
    54  	ErrAccountAlreadyExists = errors.New("acme: account already exists")
    55  
    56  	// ErrNoAccount indicates that the Client's key has not been registered with the CA.
    57  	ErrNoAccount = errors.New("acme: account does not exist")
    58  )
    59  
    60  // A Subproblem describes an ACME subproblem as reported in an Error.
    61  type Subproblem struct {
    62  	// Type is a URI reference that identifies the problem type,
    63  	// typically in a "urn:acme:error:xxx" form.
    64  	Type string
    65  	// Detail is a human-readable explanation specific to this occurrence of the problem.
    66  	Detail string
    67  	// Instance indicates a URL that the client should direct a human user to visit
    68  	// in order for instructions on how to agree to the updated Terms of Service.
    69  	// In such an event CA sets StatusCode to 403, Type to
    70  	// "urn:ietf:params:acme:error:userActionRequired", and adds a Link header with relation
    71  	// "terms-of-service" containing the latest TOS URL.
    72  	Instance string
    73  	// Identifier may contain the ACME identifier that the error is for.
    74  	Identifier *AuthzID
    75  }
    76  
    77  func (sp Subproblem) String() string {
    78  	str := fmt.Sprintf("%s: ", sp.Type)
    79  	if sp.Identifier != nil {
    80  		str += fmt.Sprintf("[%s: %s] ", sp.Identifier.Type, sp.Identifier.Value)
    81  	}
    82  	str += sp.Detail
    83  	return str
    84  }
    85  
    86  // Error is an ACME error, defined in Problem Details for HTTP APIs doc
    87  // http://tools.ietf.org/html/draft-ietf-appsawg-http-problem.
    88  type Error struct {
    89  	// StatusCode is The HTTP status code generated by the origin server.
    90  	StatusCode int
    91  	// ProblemType is a URI reference that identifies the problem type,
    92  	// typically in a "urn:acme:error:xxx" form.
    93  	ProblemType string
    94  	// Detail is a human-readable explanation specific to this occurrence of the problem.
    95  	Detail string
    96  	// Instance indicates a URL that the client should direct a human user to visit
    97  	// in order for instructions on how to agree to the updated Terms of Service.
    98  	// In such an event CA sets StatusCode to 403, ProblemType to
    99  	// "urn:ietf:params:acme:error:userActionRequired" and a Link header with relation
   100  	// "terms-of-service" containing the latest TOS URL.
   101  	Instance string
   102  	// Header is the original server error response headers.
   103  	// It may be nil.
   104  	Header http.Header
   105  	// Subproblems may contain more detailed information about the individual problems
   106  	// that caused the error. This field is only sent by RFC 8555 compatible ACME
   107  	// servers. Defined in RFC 8555 Section 6.7.1.
   108  	Subproblems []Subproblem
   109  }
   110  
   111  func (e *Error) Error() string {
   112  	str := fmt.Sprintf("%d %s: %s", e.StatusCode, e.ProblemType, e.Detail)
   113  	if len(e.Subproblems) > 0 {
   114  		str += fmt.Sprintf("; subproblems:")
   115  		for _, sp := range e.Subproblems {
   116  			str += fmt.Sprintf("\n\t%s", sp)
   117  		}
   118  	}
   119  	return str
   120  }
   121  
   122  // AuthorizationError indicates that an authorization for an identifier
   123  // did not succeed.
   124  // It contains all errors from Challenge items of the failed Authorization.
   125  type AuthorizationError struct {
   126  	// URI uniquely identifies the failed Authorization.
   127  	URI string
   128  
   129  	// Identifier is an AuthzID.Value of the failed Authorization.
   130  	Identifier string
   131  
   132  	// Errors is a collection of non-nil error values of Challenge items
   133  	// of the failed Authorization.
   134  	Errors []error
   135  }
   136  
   137  func (a *AuthorizationError) Error() string {
   138  	e := make([]string, len(a.Errors))
   139  	for i, err := range a.Errors {
   140  		e[i] = err.Error()
   141  	}
   142  
   143  	if a.Identifier != "" {
   144  		return fmt.Sprintf("acme: authorization error for %s: %s", a.Identifier, strings.Join(e, "; "))
   145  	}
   146  
   147  	return fmt.Sprintf("acme: authorization error: %s", strings.Join(e, "; "))
   148  }
   149  
   150  // OrderError is returned from Client's order related methods.
   151  // It indicates the order is unusable and the clients should start over with
   152  // AuthorizeOrder.
   153  //
   154  // The clients can still fetch the order object from CA using GetOrder
   155  // to inspect its state.
   156  type OrderError struct {
   157  	OrderURL string
   158  	Status   string
   159  }
   160  
   161  func (oe *OrderError) Error() string {
   162  	return fmt.Sprintf("acme: order %s status: %s", oe.OrderURL, oe.Status)
   163  }
   164  
   165  // RateLimit reports whether err represents a rate limit error and
   166  // any Retry-After duration returned by the server.
   167  //
   168  // See the following for more details on rate limiting:
   169  // https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-5.6
   170  func RateLimit(err error) (time.Duration, bool) {
   171  	e, ok := err.(*Error)
   172  	if !ok {
   173  		return 0, false
   174  	}
   175  	// Some CA implementations may return incorrect values.
   176  	// Use case-insensitive comparison.
   177  	if !strings.HasSuffix(strings.ToLower(e.ProblemType), ":ratelimited") {
   178  		return 0, false
   179  	}
   180  	if e.Header == nil {
   181  		return 0, true
   182  	}
   183  	return retryAfter(e.Header.Get("Retry-After")), true
   184  }
   185  
   186  // Account is a user account. It is associated with a private key.
   187  // Non-RFC 8555 fields are empty when interfacing with a compliant CA.
   188  type Account struct {
   189  	// URI is the account unique ID, which is also a URL used to retrieve
   190  	// account data from the CA.
   191  	// When interfacing with RFC 8555-compliant CAs, URI is the "kid" field
   192  	// value in JWS signed requests.
   193  	URI string
   194  
   195  	// Contact is a slice of contact info used during registration.
   196  	// See https://tools.ietf.org/html/rfc8555#section-7.3 for supported
   197  	// formats.
   198  	Contact []string
   199  
   200  	// Status indicates current account status as returned by the CA.
   201  	// Possible values are StatusValid, StatusDeactivated, and StatusRevoked.
   202  	Status string
   203  
   204  	// OrdersURL is a URL from which a list of orders submitted by this account
   205  	// can be fetched.
   206  	OrdersURL string
   207  
   208  	// The terms user has agreed to.
   209  	// A value not matching CurrentTerms indicates that the user hasn't agreed
   210  	// to the actual Terms of Service of the CA.
   211  	//
   212  	// It is non-RFC 8555 compliant. Package users can store the ToS they agree to
   213  	// during Client's Register call in the prompt callback function.
   214  	AgreedTerms string
   215  
   216  	// Actual terms of a CA.
   217  	//
   218  	// It is non-RFC 8555 compliant. Use Directory's Terms field.
   219  	// When a CA updates their terms and requires an account agreement,
   220  	// a URL at which instructions to do so is available in Error's Instance field.
   221  	CurrentTerms string
   222  
   223  	// Authz is the authorization URL used to initiate a new authz flow.
   224  	//
   225  	// It is non-RFC 8555 compliant. Use Directory's AuthzURL or OrderURL.
   226  	Authz string
   227  
   228  	// Authorizations is a URI from which a list of authorizations
   229  	// granted to this account can be fetched via a GET request.
   230  	//
   231  	// It is non-RFC 8555 compliant and is obsoleted by OrdersURL.
   232  	Authorizations string
   233  
   234  	// Certificates is a URI from which a list of certificates
   235  	// issued for this account can be fetched via a GET request.
   236  	//
   237  	// It is non-RFC 8555 compliant and is obsoleted by OrdersURL.
   238  	Certificates string
   239  
   240  	// ExternalAccountBinding represents an arbitrary binding to an account of
   241  	// the CA which the ACME server is tied to.
   242  	// See https://tools.ietf.org/html/rfc8555#section-7.3.4 for more details.
   243  	ExternalAccountBinding *ExternalAccountBinding
   244  }
   245  
   246  // ExternalAccountBinding contains the data needed to form a request with
   247  // an external account binding.
   248  // See https://tools.ietf.org/html/rfc8555#section-7.3.4 for more details.
   249  type ExternalAccountBinding struct {
   250  	// KID is the Key ID of the symmetric MAC key that the CA provides to
   251  	// identify an external account from ACME.
   252  	KID string
   253  
   254  	// Key is the bytes of the symmetric key that the CA provides to identify
   255  	// the account. Key must correspond to the KID.
   256  	Key []byte
   257  }
   258  
   259  func (e *ExternalAccountBinding) String() string {
   260  	return fmt.Sprintf("&{KID: %q, Key: redacted}", e.KID)
   261  }
   262  
   263  // Directory is ACME server discovery data.
   264  // See https://tools.ietf.org/html/rfc8555#section-7.1.1 for more details.
   265  type Directory struct {
   266  	// NonceURL indicates an endpoint where to fetch fresh nonce values from.
   267  	NonceURL string
   268  
   269  	// RegURL is an account endpoint URL, allowing for creating new accounts.
   270  	// Pre-RFC 8555 CAs also allow modifying existing accounts at this URL.
   271  	RegURL string
   272  
   273  	// OrderURL is used to initiate the certificate issuance flow
   274  	// as described in RFC 8555.
   275  	OrderURL string
   276  
   277  	// AuthzURL is used to initiate identifier pre-authorization flow.
   278  	// Empty string indicates the flow is unsupported by the CA.
   279  	AuthzURL string
   280  
   281  	// CertURL is a new certificate issuance endpoint URL.
   282  	// It is non-RFC 8555 compliant and is obsoleted by OrderURL.
   283  	CertURL string
   284  
   285  	// RevokeURL is used to initiate a certificate revocation flow.
   286  	RevokeURL string
   287  
   288  	// KeyChangeURL allows to perform account key rollover flow.
   289  	KeyChangeURL string
   290  
   291  	// Term is a URI identifying the current terms of service.
   292  	Terms string
   293  
   294  	// Website is an HTTP or HTTPS URL locating a website
   295  	// providing more information about the ACME server.
   296  	Website string
   297  
   298  	// CAA consists of lowercase hostname elements, which the ACME server
   299  	// recognises as referring to itself for the purposes of CAA record validation
   300  	// as defined in RFC 6844.
   301  	CAA []string
   302  
   303  	// ExternalAccountRequired indicates that the CA requires for all account-related
   304  	// requests to include external account binding information.
   305  	ExternalAccountRequired bool
   306  }
   307  
   308  // Order represents a client's request for a certificate.
   309  // It tracks the request flow progress through to issuance.
   310  type Order struct {
   311  	// URI uniquely identifies an order.
   312  	URI string
   313  
   314  	// Status represents the current status of the order.
   315  	// It indicates which action the client should take.
   316  	//
   317  	// Possible values are StatusPending, StatusReady, StatusProcessing, StatusValid and StatusInvalid.
   318  	// Pending means the CA does not believe that the client has fulfilled the requirements.
   319  	// Ready indicates that the client has fulfilled all the requirements and can submit a CSR
   320  	// to obtain a certificate. This is done with Client's CreateOrderCert.
   321  	// Processing means the certificate is being issued.
   322  	// Valid indicates the CA has issued the certificate. It can be downloaded
   323  	// from the Order's CertURL. This is done with Client's FetchCert.
   324  	// Invalid means the certificate will not be issued. Users should consider this order
   325  	// abandoned.
   326  	Status string
   327  
   328  	// Expires is the timestamp after which CA considers this order invalid.
   329  	Expires time.Time
   330  
   331  	// Identifiers contains all identifier objects which the order pertains to.
   332  	Identifiers []AuthzID
   333  
   334  	// NotBefore is the requested value of the notBefore field in the certificate.
   335  	NotBefore time.Time
   336  
   337  	// NotAfter is the requested value of the notAfter field in the certificate.
   338  	NotAfter time.Time
   339  
   340  	// AuthzURLs represents authorizations to complete before a certificate
   341  	// for identifiers specified in the order can be issued.
   342  	// It also contains unexpired authorizations that the client has completed
   343  	// in the past.
   344  	//
   345  	// Authorization objects can be fetched using Client's GetAuthorization method.
   346  	//
   347  	// The required authorizations are dictated by CA policies.
   348  	// There may not be a 1:1 relationship between the identifiers and required authorizations.
   349  	// Required authorizations can be identified by their StatusPending status.
   350  	//
   351  	// For orders in the StatusValid or StatusInvalid state these are the authorizations
   352  	// which were completed.
   353  	AuthzURLs []string
   354  
   355  	// FinalizeURL is the endpoint at which a CSR is submitted to obtain a certificate
   356  	// once all the authorizations are satisfied.
   357  	FinalizeURL string
   358  
   359  	// CertURL points to the certificate that has been issued in response to this order.
   360  	CertURL string
   361  
   362  	// The error that occurred while processing the order as received from a CA, if any.
   363  	Error *Error
   364  }
   365  
   366  // OrderOption allows customizing Client.AuthorizeOrder call.
   367  type OrderOption interface {
   368  	privateOrderOpt()
   369  }
   370  
   371  // WithOrderNotBefore sets order's NotBefore field.
   372  func WithOrderNotBefore(t time.Time) OrderOption {
   373  	return orderNotBeforeOpt(t)
   374  }
   375  
   376  // WithOrderNotAfter sets order's NotAfter field.
   377  func WithOrderNotAfter(t time.Time) OrderOption {
   378  	return orderNotAfterOpt(t)
   379  }
   380  
   381  type orderNotBeforeOpt time.Time
   382  
   383  func (orderNotBeforeOpt) privateOrderOpt() {}
   384  
   385  type orderNotAfterOpt time.Time
   386  
   387  func (orderNotAfterOpt) privateOrderOpt() {}
   388  
   389  // Authorization encodes an authorization response.
   390  type Authorization struct {
   391  	// URI uniquely identifies a authorization.
   392  	URI string
   393  
   394  	// Status is the current status of an authorization.
   395  	// Possible values are StatusPending, StatusValid, StatusInvalid, StatusDeactivated,
   396  	// StatusExpired and StatusRevoked.
   397  	Status string
   398  
   399  	// Identifier is what the account is authorized to represent.
   400  	Identifier AuthzID
   401  
   402  	// The timestamp after which the CA considers the authorization invalid.
   403  	Expires time.Time
   404  
   405  	// Wildcard is true for authorizations of a wildcard domain name.
   406  	Wildcard bool
   407  
   408  	// Challenges that the client needs to fulfill in order to prove possession
   409  	// of the identifier (for pending authorizations).
   410  	// For valid authorizations, the challenge that was validated.
   411  	// For invalid authorizations, the challenge that was attempted and failed.
   412  	//
   413  	// RFC 8555 compatible CAs require users to fuflfill only one of the challenges.
   414  	Challenges []*Challenge
   415  
   416  	// A collection of sets of challenges, each of which would be sufficient
   417  	// to prove possession of the identifier.
   418  	// Clients must complete a set of challenges that covers at least one set.
   419  	// Challenges are identified by their indices in the challenges array.
   420  	// If this field is empty, the client needs to complete all challenges.
   421  	//
   422  	// This field is unused in RFC 8555.
   423  	Combinations [][]int
   424  }
   425  
   426  // AuthzID is an identifier that an account is authorized to represent.
   427  type AuthzID struct {
   428  	Type  string // The type of identifier, "dns" or "ip".
   429  	Value string // The identifier itself, e.g. "example.org".
   430  }
   431  
   432  // DomainIDs creates a slice of AuthzID with "dns" identifier type.
   433  func DomainIDs(names ...string) []AuthzID {
   434  	a := make([]AuthzID, len(names))
   435  	for i, v := range names {
   436  		a[i] = AuthzID{Type: "dns", Value: v}
   437  	}
   438  	return a
   439  }
   440  
   441  // IPIDs creates a slice of AuthzID with "ip" identifier type.
   442  // Each element of addr is textual form of an address as defined
   443  // in RFC 1123 Section 2.1 for IPv4 and in RFC 5952 Section 4 for IPv6.
   444  func IPIDs(addr ...string) []AuthzID {
   445  	a := make([]AuthzID, len(addr))
   446  	for i, v := range addr {
   447  		a[i] = AuthzID{Type: "ip", Value: v}
   448  	}
   449  	return a
   450  }
   451  
   452  // wireAuthzID is ACME JSON representation of authorization identifier objects.
   453  type wireAuthzID struct {
   454  	Type  string `json:"type"`
   455  	Value string `json:"value"`
   456  }
   457  
   458  // wireAuthz is ACME JSON representation of Authorization objects.
   459  type wireAuthz struct {
   460  	Identifier   wireAuthzID
   461  	Status       string
   462  	Expires      time.Time
   463  	Wildcard     bool
   464  	Challenges   []wireChallenge
   465  	Combinations [][]int
   466  	Error        *wireError
   467  }
   468  
   469  func (z *wireAuthz) authorization(uri string) *Authorization {
   470  	a := &Authorization{
   471  		URI:          uri,
   472  		Status:       z.Status,
   473  		Identifier:   AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value},
   474  		Expires:      z.Expires,
   475  		Wildcard:     z.Wildcard,
   476  		Challenges:   make([]*Challenge, len(z.Challenges)),
   477  		Combinations: z.Combinations, // shallow copy
   478  	}
   479  	for i, v := range z.Challenges {
   480  		a.Challenges[i] = v.challenge()
   481  	}
   482  	return a
   483  }
   484  
   485  func (z *wireAuthz) error(uri string) *AuthorizationError {
   486  	err := &AuthorizationError{
   487  		URI:        uri,
   488  		Identifier: z.Identifier.Value,
   489  	}
   490  
   491  	if z.Error != nil {
   492  		err.Errors = append(err.Errors, z.Error.error(nil))
   493  	}
   494  
   495  	for _, raw := range z.Challenges {
   496  		if raw.Error != nil {
   497  			err.Errors = append(err.Errors, raw.Error.error(nil))
   498  		}
   499  	}
   500  
   501  	return err
   502  }
   503  
   504  // Challenge encodes a returned CA challenge.
   505  // Its Error field may be non-nil if the challenge is part of an Authorization
   506  // with StatusInvalid.
   507  type Challenge struct {
   508  	// Type is the challenge type, e.g. "http-01", "tls-alpn-01", "dns-01".
   509  	Type string
   510  
   511  	// URI is where a challenge response can be posted to.
   512  	URI string
   513  
   514  	// Token is a random value that uniquely identifies the challenge.
   515  	Token string
   516  
   517  	// Status identifies the status of this challenge.
   518  	// In RFC 8555, possible values are StatusPending, StatusProcessing, StatusValid,
   519  	// and StatusInvalid.
   520  	Status string
   521  
   522  	// Validated is the time at which the CA validated this challenge.
   523  	// Always zero value in pre-RFC 8555.
   524  	Validated time.Time
   525  
   526  	// Error indicates the reason for an authorization failure
   527  	// when this challenge was used.
   528  	// The type of a non-nil value is *Error.
   529  	Error error
   530  }
   531  
   532  // wireChallenge is ACME JSON challenge representation.
   533  type wireChallenge struct {
   534  	URL       string `json:"url"` // RFC
   535  	URI       string `json:"uri"` // pre-RFC
   536  	Type      string
   537  	Token     string
   538  	Status    string
   539  	Validated time.Time
   540  	Error     *wireError
   541  }
   542  
   543  func (c *wireChallenge) challenge() *Challenge {
   544  	v := &Challenge{
   545  		URI:    c.URL,
   546  		Type:   c.Type,
   547  		Token:  c.Token,
   548  		Status: c.Status,
   549  	}
   550  	if v.URI == "" {
   551  		v.URI = c.URI // c.URL was empty; use legacy
   552  	}
   553  	if v.Status == "" {
   554  		v.Status = StatusPending
   555  	}
   556  	if c.Error != nil {
   557  		v.Error = c.Error.error(nil)
   558  	}
   559  	return v
   560  }
   561  
   562  // wireError is a subset of fields of the Problem Details object
   563  // as described in https://tools.ietf.org/html/rfc7807#section-3.1.
   564  type wireError struct {
   565  	Status      int
   566  	Type        string
   567  	Detail      string
   568  	Instance    string
   569  	Subproblems []Subproblem
   570  }
   571  
   572  func (e *wireError) error(h http.Header) *Error {
   573  	err := &Error{
   574  		StatusCode:  e.Status,
   575  		ProblemType: e.Type,
   576  		Detail:      e.Detail,
   577  		Instance:    e.Instance,
   578  		Header:      h,
   579  		Subproblems: e.Subproblems,
   580  	}
   581  	return err
   582  }
   583  
   584  // CertOption is an optional argument type for the TLS ChallengeCert methods for
   585  // customizing a temporary certificate for TLS-based challenges.
   586  type CertOption interface {
   587  	privateCertOpt()
   588  }
   589  
   590  // WithKey creates an option holding a private/public key pair.
   591  // The private part signs a certificate, and the public part represents the signee.
   592  func WithKey(key crypto.Signer) CertOption {
   593  	return &certOptKey{key}
   594  }
   595  
   596  type certOptKey struct {
   597  	key crypto.Signer
   598  }
   599  
   600  func (*certOptKey) privateCertOpt() {}
   601  
   602  // WithTemplate creates an option for specifying a certificate template.
   603  // See x509.CreateCertificate for template usage details.
   604  //
   605  // In TLS ChallengeCert methods, the template is also used as parent,
   606  // resulting in a self-signed certificate.
   607  // The DNSNames field of t is always overwritten for tls-sni challenge certs.
   608  func WithTemplate(t *x509.Certificate) CertOption {
   609  	return (*certOptTemplate)(t)
   610  }
   611  
   612  type certOptTemplate x509.Certificate
   613  
   614  func (*certOptTemplate) privateCertOpt() {}
   615  

View as plain text