acme-mock

An ACME server implementation performing no validations

git clone https://git.8pit.net/acme-mock.git

  1// Copied from lego <https://github.com/go-acme/lego> with modifications.
  2//
  3// Copyright (c) 2015-2017 Sebastian Erhart
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to deal
  7// in the Software without restriction, including without limitation the rights
  8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9// copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in all
 13// copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 21// SOFTWARE.
 22
 23// Package acme contains all objects related the ACME endpoints.
 24// https://tools.ietf.org/html/draft-ietf-acme-acme-16
 25package acme
 26
 27import (
 28	"encoding/json"
 29	"time"
 30)
 31
 32// Challenge statuses
 33// https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-7.1.6
 34const (
 35	StatusPending     = "pending"
 36	StatusInvalid     = "invalid"
 37	StatusValid       = "valid"
 38	StatusProcessing  = "processing"
 39	StatusDeactivated = "deactivated"
 40	StatusExpired     = "expired"
 41	StatusRevoked     = "revoked"
 42)
 43
 44// Directory the ACME directory object.
 45// - https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-7.1.1
 46type Directory struct {
 47	NewNonceURL   string `json:"newNonce"`
 48	NewAccountURL string `json:"newAccount"`
 49	NewOrderURL   string `json:"newOrder"`
 50	NewAuthzURL   string `json:"newAuthz",omitempty`
 51	RevokeCertURL string `json:"revokeCert"`
 52	KeyChangeURL  string `json:"keyChange"`
 53	Meta          Meta   `json:"meta",omitempty`
 54}
 55
 56// Meta the ACME meta object (related to Directory).
 57// - https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-7.1.1
 58type Meta struct {
 59	// termsOfService (optional, string):
 60	// A URL identifying the current terms of service.
 61	TermsOfService string `json:"termsOfService"`
 62
 63	// website (optional, string):
 64	// An HTTP or HTTPS URL locating a website providing more information about the ACME server.
 65	Website string `json:"website"`
 66
 67	// caaIdentities (optional, array of string):
 68	// The hostnames that the ACME server recognizes as referring to itself
 69	// for the purposes of CAA record validation as defined in [RFC6844].
 70	// Each string MUST represent the same sequence of ASCII code points
 71	// that the server will expect to see as the "Issuer Domain Name" in a CAA issue or issuewild property tag.
 72	// This allows clients to determine the correct issuer domain name to use when configuring CAA records.
 73	CaaIdentities []string `json:"caaIdentities"`
 74
 75	// externalAccountRequired (optional, boolean):
 76	// If this field is present and set to "true",
 77	// then the CA requires that all new- account requests include an "externalAccountBinding" field
 78	// associating the new account with an external account.
 79	ExternalAccountRequired bool `json:"externalAccountRequired"`
 80}
 81
 82// ExtendedAccount a extended Account.
 83type ExtendedAccount struct {
 84	Account
 85	// Contains the value of the response header `Location`
 86	Location string `json:"-"`
 87}
 88
 89// Account the ACME account Object.
 90// - https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-7.1.2
 91// - https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-7.3
 92type Account struct {
 93	// status (required, string):
 94	// The status of this account.
 95	// Possible values are: "valid", "deactivated", and "revoked".
 96	// The value "deactivated" should be used to indicate client-initiated deactivation
 97	// whereas "revoked" should be used to indicate server- initiated deactivation. (See Section 7.1.6)
 98	Status string `json:"status,omitempty"`
 99
100	// contact (optional, array of string):
101	// An array of URLs that the server can use to contact the client for issues related to this account.
102	// For example, the server may wish to notify the client about server-initiated revocation or certificate expiration.
103	// For information on supported URL schemes, see Section 7.3
104	Contact []string `json:"contact,omitempty"`
105
106	// termsOfServiceAgreed (optional, boolean):
107	// Including this field in a new-account request,
108	// with a value of true, indicates the client's agreement with the terms of service.
109	// This field is not updateable by the client.
110	TermsOfServiceAgreed bool `json:"termsOfServiceAgreed,omitempty"`
111
112	// orders (required, string):
113	// A URL from which a list of orders submitted by this account can be fetched via a POST-as-GET request,
114	// as described in Section 7.1.2.1.
115	Orders string `json:"orders,omitempty"`
116
117	// onlyReturnExisting (optional, boolean):
118	// If this field is present with the value "true",
119	// then the server MUST NOT create a new account if one does not already exist.
120	// This allows a client to look up an account URL based on an account key (see Section 7.3.1).
121	OnlyReturnExisting bool `json:"onlyReturnExisting,omitempty"`
122
123	// externalAccountBinding (optional, object):
124	// An optional field for binding the new account with an existing non-ACME account (see Section 7.3.4).
125	ExternalAccountBinding json.RawMessage `json:"externalAccountBinding,omitempty"`
126}
127
128// ExtendedOrder a extended Order.
129type ExtendedOrder struct {
130	Order
131	// The order URL, contains the value of the response header `Location`
132	Location string `json:"-"`
133}
134
135// Order the ACME order Object.
136// - https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-7.1.3
137type Order struct {
138	// status (required, string):
139	// The status of this order.
140	// Possible values are: "pending", "ready", "processing", "valid", and "invalid".
141	Status string `json:"status,omitempty"`
142
143	// expires (optional, string):
144	// The timestamp after which the server will consider this order invalid,
145	// encoded in the format specified in RFC 3339 [RFC3339].
146	// This field is REQUIRED for objects with "pending" or "valid" in the status field.
147	Expires string `json:"expires,omitempty"`
148
149	// identifiers (required, array of object):
150	// An array of identifier objects that the order pertains to.
151	Identifiers []Identifier `json:"identifiers"`
152
153	// notBefore (optional, string):
154	// The requested value of the notBefore field in the certificate,
155	// in the date format defined in [RFC3339].
156	NotBefore string `json:"notBefore,omitempty"`
157
158	// notAfter (optional, string):
159	// The requested value of the notAfter field in the certificate,
160	// in the date format defined in [RFC3339].
161	NotAfter string `json:"notAfter,omitempty"`
162
163	// authorizations (required, array of string):
164	// For pending orders,
165	// the authorizations that the client needs to complete before the requested certificate can be issued (see Section 7.5),
166	// including unexpired authorizations that the client has completed in the past for identifiers specified in the order.
167	// The authorizations required are dictated by server policy
168	// and there may not be a 1:1 relationship between the order identifiers and the authorizations required.
169	// For final orders (in the "valid" or "invalid" state), the authorizations that were completed.
170	// Each entry is a URL from which an authorization can be fetched with a POST-as-GET request.
171	Authorizations []string `json:"authorizations"`
172
173	// finalize (required, string):
174	// A URL that a CSR must be POSTed to once all of the order's authorizations are satisfied to finalize the order.
175	// The result of a successful finalization will be the population of the certificate URL for the order.
176	Finalize string `json:"finalize,omitempty"`
177
178	// certificate (optional, string):
179	// A URL for the certificate that has been issued in response to this order
180	Certificate string `json:"certificate,omitempty"`
181}
182
183// Authorization the ACME authorization object.
184// - https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-7.1.4
185type Authorization struct {
186	// status (required, string):
187	// The status of this authorization.
188	// Possible values are: "pending", "valid", "invalid", "deactivated", "expired", and "revoked".
189	Status string `json:"status"`
190
191	// expires (optional, string):
192	// The timestamp after which the server will consider this authorization invalid,
193	// encoded in the format specified in RFC 3339 [RFC3339].
194	// This field is REQUIRED for objects with "valid" in the "status" field.
195	Expires time.Time `json:"expires,omitempty"`
196
197	// identifier (required, object):
198	// The identifier that the account is authorized to represent
199	Identifier Identifier `json:"identifier,omitempty"`
200
201	// challenges (required, array of objects):
202	// For pending authorizations, the challenges that the client can fulfill in order to prove possession of the identifier.
203	// For valid authorizations, the challenge that was validated.
204	// For invalid authorizations, the challenge that was attempted and failed.
205	// Each array entry is an object with parameters required to validate the challenge.
206	// A client should attempt to fulfill one of these challenges,
207	// and a server should consider any one of the challenges sufficient to make the authorization valid.
208	Challenges []Challenge `json:"challenges,omitempty"`
209
210	// wildcard (optional, boolean):
211	// For authorizations created as a result of a newOrder request containing a DNS identifier
212	// with a value that contained a wildcard prefix this field MUST be present, and true.
213	Wildcard bool `json:"wildcard,omitempty"`
214}
215
216// ExtendedChallenge a extended Challenge.
217type ExtendedChallenge struct {
218	Challenge
219	// Contains the value of the response header `Retry-After`
220	RetryAfter string `json:"-"`
221	// Contains the value of the response header `Link` rel="up"
222	AuthorizationURL string `json:"-"`
223}
224
225// Challenge the ACME challenge object.
226// - https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-7.1.5
227// - https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-8
228type Challenge struct {
229	// type (required, string):
230	// The type of challenge encoded in the object.
231	Type string `json:"type"`
232
233	// url (required, string):
234	// The URL to which a response can be posted.
235	URL string `json:"url"`
236
237	// status (required, string):
238	// The status of this challenge. Possible values are: "pending", "processing", "valid", and "invalid".
239	Status string `json:"status"`
240
241	// validated (optional, string):
242	// The time at which the server validated this challenge,
243	// encoded in the format specified in RFC 3339 [RFC3339].
244	// This field is REQUIRED if the "status" field is "valid".
245	Validated time.Time `json:"validated,omitempty"`
246
247	// token (required, string):
248	// A random value that uniquely identifies the challenge.
249	// This value MUST have at least 128 bits of entropy.
250	// It MUST NOT contain any characters outside the base64url alphabet,
251	// and MUST NOT include base64 padding characters ("=").
252	// See [RFC4086] for additional information on randomness requirements.
253	// https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-8.3
254	// https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-8.4
255	Token string `json:"token"`
256
257	// https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-8.1
258	KeyAuthorization string `json:"keyAuthorization"`
259}
260
261// Identifier the ACME identifier object.
262// - https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-9.7.7
263type Identifier struct {
264	Type  string `json:"type"`
265	Value string `json:"value"`
266}
267
268// CSRMessage Certificate Signing Request
269// - https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-7.4
270type CSRMessage struct {
271	// csr (required, string):
272	// A CSR encoding the parameters for the certificate being requested [RFC2986].
273	// The CSR is sent in the base64url-encoded version of the DER format.
274	// (Note: Because this field uses base64url, and does not include headers, it is different from PEM.).
275	Csr string `json:"csr"`
276}
277
278// RevokeCertMessage a certificate revocation message
279// - https://tools.ietf.org/html/draft-ietf-acme-acme-16#section-7.6
280// - https://tools.ietf.org/html/rfc5280#section-5.3.1
281type RevokeCertMessage struct {
282	// certificate (required, string):
283	// The certificate to be revoked, in the base64url-encoded version of the DER format.
284	// (Note: Because this field uses base64url, and does not include headers, it is different from PEM.)
285	Certificate string `json:"certificate"`
286
287	// reason (optional, int):
288	// One of the revocation reasonCodes defined in Section 5.3.1 of [RFC5280] to be used when generating OCSP responses and CRLs.
289	// If this field is not set the server SHOULD omit the reasonCode CRL entry extension when generating OCSP responses and CRLs.
290	// The server MAY disallow a subset of reasonCodes from being used by the user.
291	// If a request contains a disallowed reasonCode the server MUST reject it with the error type "urn:ietf:params:acme:error:badRevocationReason".
292	// The problem document detail SHOULD indicate which reasonCodes are allowed.
293	Reason *uint `json:"reason,omitempty"`
294}