pki

package
v0.0.0-...-e8682ef Latest Latest
Warning

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

Go to latest
Published: Oct 3, 2024 License: MPL-2.0 Imports: 63 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DNSChallengePrefix = "_acme-challenge."
	ALPNProtocol       = "acme-tls/1"
)
View Source
const (
	ErrorPrefix      = "urn:ietf:params:acme:error:"
	ErrorContentType = "application/problem+json"
)

Error prefix; see RFC 8555 Section 6.7. Errors.

View Source
const (
	IssuerRefNotFound = issuerID("not-found")
	KeyRefNotFound    = keyID("not-found")
)
View Source
const (
	ReadOnlyUsage    issuerUsage = iota
	IssuanceUsage    issuerUsage = 1 << iota
	CRLSigningUsage  issuerUsage = 1 << iota
	OCSPSigningUsage issuerUsage = 1 << iota

	// When adding a new usage in the future, we'll need to create a usage
	// mask field on the IssuerEntry and handle migrations to a newer mask,
	// inferring a value for the new bits.
	AllIssuerUsages = ReadOnlyUsage | IssuanceUsage | CRLSigningUsage | OCSPSigningUsage
)
View Source
const ChallengeAttemptFailedMsg = "" /* 140-byte string literal not displayed */
View Source
const MaxRetryAttempts = 5
View Source
const SecretCertsType = "pki"

SecretCertsType is the name used to identify this type

Variables

View Source
var (
	ErrAlreadyRevoked          = errors.New("The request specified a certificate to be revoked that has already been revoked")
	ErrBadCSR                  = errors.New("The CSR is unacceptable")
	ErrBadNonce                = errors.New("The client sent an unacceptable anti-replay nonce")
	ErrBadPublicKey            = errors.New("The JWS was signed by a public key the server does not support")
	ErrBadRevocationReason     = errors.New("The revocation reason provided is not allowed by the server")
	ErrBadSignatureAlgorithm   = errors.New("The JWS was signed with an algorithm the server does not support")
	ErrCAA                     = errors.New("Certification Authority Authorization (CAA) records forbid the CA from issuing a certificate")
	ErrCompound                = errors.New("Specific error conditions are indicated in the 'subproblems' array")
	ErrConnection              = errors.New("The server could not connect to validation target")
	ErrDNS                     = errors.New("There was a problem with a DNS query during identifier validation")
	ErrExternalAccountRequired = errors.New("The request must include a value for the 'externalAccountBinding' field")
	ErrIncorrectResponse       = errors.New("Response received didn't match the challenge's requirements")
	ErrInvalidContact          = errors.New("A contact URL for an account was invalid")
	ErrMalformed               = errors.New("The request message was malformed")
	ErrOrderNotReady           = errors.New("The request attempted to finalize an order that is not ready to be finalized")
	ErrRateLimited             = errors.New("The request exceeds a rate limit")
	ErrRejectedIdentifier      = errors.New("The server will not issue certificates for the identifier")
	ErrServerInternal          = errors.New("The server experienced an internal error")
	ErrTLS                     = errors.New("The server received a TLS error during validation")
	ErrUnauthorized            = errors.New("The client lacks sufficient authorization")
	ErrUnsupportedContact      = errors.New("A contact URL for an account used an unsupported protocol scheme")
	ErrUnsupportedIdentifier   = errors.New("An identifier is of an unsupported type")
	ErrUserActionRequired      = errors.New("Visit the 'instance' URL and take actions specified there")
)
View Source
var (
	OcspUnauthorizedResponse = &logical.Response{
		Data: map[string]interface{}{
			logical.HTTPContentType: ocspResponseContentType,
			logical.HTTPStatusCode:  http.StatusUnauthorized,
			logical.HTTPRawBody:     ocsp.UnauthorizedErrorResponse,
		},
	}
	OcspMalformedResponse = &logical.Response{
		Data: map[string]interface{}{
			logical.HTTPContentType: ocspResponseContentType,
			logical.HTTPStatusCode:  http.StatusBadRequest,
			logical.HTTPRawBody:     ocsp.MalformedRequestErrorResponse,
		},
	}
	OcspInternalErrorResponse = &logical.Response{
		Data: map[string]interface{}{
			logical.HTTPContentType: ocspResponseContentType,
			logical.HTTPStatusCode:  http.StatusInternalServerError,
			logical.HTTPRawBody:     ocsp.InternalErrorErrorResponse,
		},
	}

	ErrMissingOcspUsage = errors.New("issuer entry did not have the OCSPSigning usage")
	ErrIssuerHasNoKey   = errors.New("issuer has no key")
	ErrUnknownIssuer    = errors.New("unknown issuer")
)

These response variables should not be mutated, instead treat them as constants

View Source
var ALPNPort = "443"

While this should be a constant, there's no way to do a low-level test of ValidateTLSALPN01Challenge without spinning up a complicated Docker instance to build a custom responder. Because we already have a local toolchain, it is far easier to drive this through Go tests with a custom (high) port, rather than requiring permission to bind to port 443 (root-run tests are even worse).

View Source
var AllowedEabJWSTypes = map[string]interface{}{
	"HS256": true,
	"HS384": true,
	"HS512": true,
}
View Source
var AllowedOuterJWSTypes = map[string]interface{}{
	"RS256":  true,
	"RS384":  true,
	"RS512":  true,
	"PS256":  true,
	"PS384":  true,
	"PS512":  true,
	"ES256":  true,
	"ES384":  true,
	"ES512":  true,
	"EdDSA2": true,
}
View Source
var ErrAccountDoesNotExist = errors.New("The request specified an account that does not exist")

See RFC 8555 Section 6.7. Errors.

View Source
var ErrAcmeDisabled = errors.New("ACME feature is disabled")
View Source
var ErrStorageItemNotFound = errors.New("storage item not found")
View Source
var MaxChallengeTimeout = 1 * time.Minute
View Source
var OIDACMEIdentifier = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 31}

OID of the acmeIdentifier X.509 Certificate Extension.

Functions

func Backend

func Backend(conf *logical.BackendConfig) *backend

Backend returns a new Backend framework struct

func CBDelete

func CBDelete(b *backend, s logical.Storage, path string) (*logical.Response, error)

func CBHeader

func CBHeader(b *backend, s logical.Storage, path string) (*logical.Response, error)

func CBList

func CBList(b *backend, s logical.Storage, path string) (*logical.Response, error)

func CBPaginatedList

func CBPaginatedList(b *backend, s logical.Storage, path string, after string, limit int) (*logical.Response, error)

func CBPatch

func CBPatch(b *backend, s logical.Storage, path string, data map[string]interface{}) (*logical.Response, error)

func CBRead

func CBRead(b *backend, s logical.Storage, path string) (*logical.Response, error)

func CBReq

func CBReq(b *backend, s logical.Storage, operation logical.Operation, path string, data map[string]interface{}) (*logical.Response, error)

Direct storage backend helpers (b, s := createBackendWithStorage(t)) which are mostly compatible with client.Logical() operations. The main difference is that the JSON round-tripping hasn't occurred, so values are as the backend returns them (e.g., []string instead of []interface{}).

func CBWrite

func CBWrite(b *backend, s logical.Storage, path string, data map[string]interface{}) (*logical.Response, error)

func CreateBackendWithStorage

func CreateBackendWithStorage(t testing.TB) (*backend, logical.Storage)

Setup helpers

func Factory

func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error)

Factory creates a new backend implementing the logical.Backend interface

func FindType

func FindType(given error) (err error, id string, code int, found bool)

func NewACMEState

func NewACMEState() *acmeState

func NewIssuerUsageFromNames

func NewIssuerUsageFromNames(names []string) (issuerUsage, error)

func TranslateError

func TranslateError(given error) (*logical.Response, error)

func UnmarshalEabJwsJson

func UnmarshalEabJwsJson(eabBytes []byte) (*jwsCtx, error)

func ValidateDNS01Challenge

func ValidateDNS01Challenge(domain string, token string, thumbprint string, config *acmeConfigEntry) (bool, error)

func ValidateHTTP01Challenge

func ValidateHTTP01Challenge(domain string, token string, thumbprint string, config *acmeConfigEntry) (bool, error)

Validates a given ACME http-01 challenge against the specified domain, per RFC 8555.

We attempt to be defensive here against timeouts, extra redirects, &c.

func ValidateKeyAuthorization

func ValidateKeyAuthorization(keyAuthz string, token string, thumbprint string) (bool, error)

ValidateKeyAuthorization validates that the given keyAuthz from a challenge matches our expectation, returning (true, nil) if so, or (false, err) if not.

func ValidateRawSHA256KeyAuthorization

func ValidateRawSHA256KeyAuthorization(keyAuthz []byte, token string, thumbprint string) (bool, error)

ValidateRawSHA256KeyAuthorization validates that the given keyAuthz from a challenge matches our expectation, returning (true, nil) if so, or (false, err) if not.

This is for use with TLS challenges, which require the raw hash output.

func ValidateSHA256KeyAuthorization

func ValidateSHA256KeyAuthorization(keyAuthz string, token string, thumbprint string) (bool, error)

ValidateSHA256KeyAuthorization validates that the given keyAuthz from a challenge matches our expectation, returning (true, nil) if so, or (false, err) if not.

This is for use with DNS challenges, which require base64 encoding.

func ValidateTLSALPN01Challenge

func ValidateTLSALPN01Challenge(domain string, token string, thumbprint string, config *acmeConfigEntry) (bool, error)

Types

type ACMEAccountStatus

type ACMEAccountStatus string
const (
	AccountStatusValid       ACMEAccountStatus = "valid"
	AccountStatusDeactivated ACMEAccountStatus = "deactivated"
	AccountStatusRevoked     ACMEAccountStatus = "revoked"
)

func (ACMEAccountStatus) String

func (aas ACMEAccountStatus) String() string

type ACMEAuthorization

type ACMEAuthorization struct {
	Id        string `json:"id"`
	AccountId string `json:"account_id"`

	Identifier *ACMEIdentifier             `json:"identifier"`
	Status     ACMEAuthorizationStatusType `json:"status"`

	// Per RFC 8555 Section 7.1.4. Authorization Objects:
	//
	// > This field is REQUIRED for objects with "valid" in the "status"
	// > field.
	Expires string `json:"expires,optional"`

	Challenges []*ACMEChallenge `json:"challenges"`
	Wildcard   bool             `json:"wildcard"`
}

func (*ACMEAuthorization) GetExpires

func (aa *ACMEAuthorization) GetExpires() (time.Time, error)

func (*ACMEAuthorization) NetworkMarshal

func (aa *ACMEAuthorization) NetworkMarshal(acmeCtx *acmeContext) map[string]interface{}

type ACMEAuthorizationStatusType

type ACMEAuthorizationStatusType string
const (
	ACMEAuthorizationPending     ACMEAuthorizationStatusType = "pending"
	ACMEAuthorizationValid       ACMEAuthorizationStatusType = "valid"
	ACMEAuthorizationInvalid     ACMEAuthorizationStatusType = "invalid"
	ACMEAuthorizationDeactivated ACMEAuthorizationStatusType = "deactivated"
	ACMEAuthorizationExpired     ACMEAuthorizationStatusType = "expired"
	ACMEAuthorizationRevoked     ACMEAuthorizationStatusType = "revoked"
)

type ACMEChallenge

type ACMEChallenge struct {
	Type            ACMEChallengeType       `json:"type"`
	Status          ACMEChallengeStatusType `json:"status"`
	Validated       string                  `json:"validated,optional"`
	Error           map[string]interface{}  `json:"error,optional"`
	ChallengeFields map[string]interface{}  `json:"challenge_fields"`
}

func (*ACMEChallenge) NetworkMarshal

func (ac *ACMEChallenge) NetworkMarshal(acmeCtx *acmeContext, authId string) map[string]interface{}

type ACMEChallengeEngine

type ACMEChallengeEngine struct {
	NumWorkers int

	ValidationLock sync.Mutex
	NewValidation  chan string
	Closing        chan struct{}
	Validations    *list.List
}

func NewACMEChallengeEngine

func NewACMEChallengeEngine() *ACMEChallengeEngine

func (*ACMEChallengeEngine) AcceptChallenge

func (ace *ACMEChallengeEngine) AcceptChallenge(sc *storageContext, account string, authz *ACMEAuthorization, challenge *ACMEChallenge, thumbprint string) error

func (*ACMEChallengeEngine) LoadFromStorage

func (ace *ACMEChallengeEngine) LoadFromStorage(b *backend, sc *storageContext) error

func (*ACMEChallengeEngine) Run

func (ace *ACMEChallengeEngine) Run(b *backend, state *acmeState, sc *storageContext)

func (*ACMEChallengeEngine) VerifyChallenge

func (ace *ACMEChallengeEngine) VerifyChallenge(runnerSc *storageContext, id string, validationQueueRetries int, finished chan bool, config *acmeConfigEntry)

type ACMEChallengeStatusType

type ACMEChallengeStatusType string
const (
	ACMEChallengePending    ACMEChallengeStatusType = "pending"
	ACMEChallengeProcessing ACMEChallengeStatusType = "processing"
	ACMEChallengeValid      ACMEChallengeStatusType = "valid"
	ACMEChallengeInvalid    ACMEChallengeStatusType = "invalid"
)

type ACMEChallengeType

type ACMEChallengeType string
const (
	ACMEHTTPChallenge ACMEChallengeType = "http-01"
	ACMEDNSChallenge  ACMEChallengeType = "dns-01"
	ACMEALPNChallenge ACMEChallengeType = "tls-alpn-01"
)

type ACMEIdentifier

type ACMEIdentifier struct {
	Type          ACMEIdentifierType `json:"type"`
	Value         string             `json:"value"`
	OriginalValue string             `json:"original_value"`
	IsWildcard    bool               `json:"is_wildcard"`
}

func (*ACMEIdentifier) MaybeParseWildcard

func (ai *ACMEIdentifier) MaybeParseWildcard() (bool, string, error)

func (*ACMEIdentifier) NetworkMarshal

func (ai *ACMEIdentifier) NetworkMarshal(useOriginalValue bool) map[string]interface{}

type ACMEIdentifierType

type ACMEIdentifierType string
const (
	ACMEDNSIdentifier ACMEIdentifierType = "dns"
	ACMEIPIdentifier  ACMEIdentifierType = "ip"
)

type ACMEOrderStatusType

type ACMEOrderStatusType string
const (
	ACMEOrderPending    ACMEOrderStatusType = "pending"
	ACMEOrderProcessing ACMEOrderStatusType = "processing"
	ACMEOrderValid      ACMEOrderStatusType = "valid"
	ACMEOrderInvalid    ACMEOrderStatusType = "invalid"
	ACMEOrderReady      ACMEOrderStatusType = "ready"
)

type ChallengeQueueEntry

type ChallengeQueueEntry struct {
	Identifier string
	RetryAfter time.Time
	NumRetries int // Track if we are spinning on a corrupted challenge
}

type ChallengeValidation

type ChallengeValidation struct {
	// Account KID that this validation attempt is recorded under.
	Account string `json:"account"`

	// The authorization ID that this validation attempt is for.
	Authorization string            `json:"authorization"`
	ChallengeType ACMEChallengeType `json:"challenge_type"`

	// The token of this challenge and the JWS thumbprint of the account
	// we're validating against.
	Token      string `json:"token"`
	Thumbprint string `json:"thumbprint"`

	Initiated       time.Time `json:"initiated"`
	FirstValidation time.Time `json:"first_validation,omitempty"`
	RetryCount      int       `json:"retry_count,omitempty"`
	LastRetry       time.Time `json:"last_retry,omitempty"`
	RetryAfter      time.Time `json:"retry_after,omitempty"`
}

type DefaultDirectoryPolicyType

type DefaultDirectoryPolicyType int
const (
	Forbid DefaultDirectoryPolicyType = iota
	SignVerbatim
	Role
)

type EabPolicy

type EabPolicy struct {
	Name EabPolicyName
}

func (EabPolicy) EnforceForExistingAccount

func (ep EabPolicy) EnforceForExistingAccount(account *acmeAccount) error

EnforceForExistingAccount for all operations within ACME, does the account being used require an EAB attached to it.

func (EabPolicy) EnforceForNewAccount

func (ep EabPolicy) EnforceForNewAccount(eabData *eabType) error

EnforceForNewAccount for new account creations, should we require an EAB.

func (EabPolicy) IsExternalAccountRequired

func (ep EabPolicy) IsExternalAccountRequired() bool

IsExternalAccountRequired for new accounts incoming does is an EAB required

func (EabPolicy) OverrideEnvDisablingPublicAcme

func (ep EabPolicy) OverrideEnvDisablingPublicAcme() bool

OverrideEnvDisablingPublicAcme determines if ACME is enabled but the OS environment variable has said to disable public acme support, if we can override that environment variable to turn on ACME support

type EabPolicyName

type EabPolicyName string

type ErrorResponse

type ErrorResponse struct {
	StatusCode  int              `json:"-"`
	Type        string           `json:"type"`
	Detail      string           `json:"detail"`
	Subproblems []*ErrorResponse `json:"subproblems"`
}

func TranslateErrorToErrorResponse

func TranslateErrorToErrorResponse(given error) ErrorResponse

func (*ErrorResponse) Marshal

func (e *ErrorResponse) Marshal() (*logical.Response, error)

func (*ErrorResponse) MarshalForStorage

func (e *ErrorResponse) MarshalForStorage() map[string]interface{}

type IfModifiedSinceHelper

type IfModifiedSinceHelper struct {
	// contains filtered or unexported fields
}

Directories

Path Synopsis
cmd
pki

Jump to

Keyboard shortcuts

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