mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-31 14:31:02 +00:00 
			
		
		
		
	* use certmagic for more extensible/robust ACME cert handling * accept TOS based on config option Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: Lauris BH <lauris@nix.lv>
		
			
				
	
	
		
			136 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			136 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| // Copyright 2020 Matthew Holt
 | |
| //
 | |
| // Licensed under the Apache License, Version 2.0 (the "License");
 | |
| // you may not use this file except in compliance with the License.
 | |
| // You may obtain a copy of the License at
 | |
| //
 | |
| //     http://www.apache.org/licenses/LICENSE-2.0
 | |
| //
 | |
| // Unless required by applicable law or agreed to in writing, software
 | |
| // distributed under the License is distributed on an "AS IS" BASIS,
 | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| // See the License for the specific language governing permissions and
 | |
| // limitations under the License.
 | |
| 
 | |
| package acme
 | |
| 
 | |
| import "fmt"
 | |
| 
 | |
| // 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
 | |
| 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 interface{} `json:"-"`
 | |
| }
 | |
| 
 | |
| func (p Problem) Error() string {
 | |
| 	// TODO: 7.3.3: Handle changes to Terms of Service (notice it uses the Instance field and Link header)
 | |
| 
 | |
| 	// RFC 8555 §6.7: "Clients SHOULD display the 'detail' field of all errors."
 | |
| 	s := fmt.Sprintf("HTTP %d %s - %s", p.Status, p.Type, p.Detail)
 | |
| 	if len(p.Subproblems) > 0 {
 | |
| 		for _, v := range p.Subproblems {
 | |
| 			s += fmt.Sprintf(", problem %q: %s", v.Type, v.Detail)
 | |
| 		}
 | |
| 	}
 | |
| 	if p.Instance != "" {
 | |
| 		s += ", url: " + p.Instance
 | |
| 	}
 | |
| 	return s
 | |
| }
 | |
| 
 | |
| // 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."
 | |
| 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"`
 | |
| }
 | |
| 
 | |
| // 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."
 | |
| 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"
 | |
| )
 |