mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 18:51:32 +00:00
21aeed4f4e
Phase 0 closure (Path B2, post-rewrite):
addlicense sweep — adds the canonical certctl LLC copyright + BUSL-1.1
SPDX header to every production Go file. Template:
// Copyright 2026 certctl LLC. All rights reserved.
// SPDX-License-Identifier: BUSL-1.1
Coverage: 338 / 338 production Go files (cmd/ + internal/, excluding
*_test.go and **/testdata/**). Pre-sweep coverage was 22 / 338 (6.5%);
post-sweep is 338 / 338 (100%).
Normalized 22 pre-existing legacy headers (`// Copyright (c) certctl`
+ `// SPDX-License-Identifier: BSL-1.1`) and 1 file using a
`Certctl Contributors` attribution. The legacy SPDX ID `BSL-1.1`
is non-standard; the official SPDX identifier for Business Source
License 1.1 is `BUSL-1.1` (capital U). All 338 files now share the
canonical form.
Generated via:
addlicense -c "certctl LLC" -y 2026 \
-f cowork/legal/copyright-header.tpl \
-ignore '**/testdata/**' -ignore '**/*_test.go' \
cmd/ internal/
Verification:
find cmd internal -name '*.go' -not -name '*_test.go' \
-not -path '*/testdata/*' \
-exec grep -L '^// Copyright 2026 certctl LLC' {} \; | wc -l
Returns: 0
gofmt clean. Header additions are comments only, no compile impact.
Closes: cowork/certctl-architecture-diligence-audit.html#fix-RED-4
102 lines
5.0 KiB
Go
102 lines
5.0 KiB
Go
// Copyright 2026 certctl LLC. All rights reserved.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package domain
|
|
|
|
// SCEPEnrollResult holds the result of a SCEP (RFC 8894) enrollment operation.
|
|
type SCEPEnrollResult struct {
|
|
CertPEM string `json:"cert_pem"` // PEM-encoded signed certificate
|
|
ChainPEM string `json:"chain_pem"` // PEM-encoded CA chain
|
|
}
|
|
|
|
// SCEPMessageType identifies the type of SCEP PKI message.
|
|
type SCEPMessageType int
|
|
|
|
const (
|
|
// SCEPMessageTypeCertRep is the server's response to PKCSReq / RenewalReq /
|
|
// GetCertInitial. RFC 8894 §3.3.2. Wire-encoded as the messageType
|
|
// authenticated attribute on the outbound CertRep PKIMessage; clients pivot
|
|
// on this value to decide whether to extract a cert from the EnvelopedData
|
|
// (Status=Success), surface a failInfo (Status=Failure), or poll
|
|
// (Status=Pending).
|
|
SCEPMessageTypeCertRep SCEPMessageType = 3
|
|
// SCEPMessageTypeRenewalReq is re-enrollment with an existing valid cert.
|
|
// RFC 8894 §3.3.1.2. Distinct from PKCSReq because the signerInfo is signed
|
|
// by the existing cert (proving possession), not by a transient self-signed
|
|
// device key. The service-side handler must verify the signing cert chains
|
|
// to a trusted CA and is not yet revoked or expired.
|
|
SCEPMessageTypeRenewalReq SCEPMessageType = 17
|
|
// SCEPMessageTypePKCSReq is a PKCS#10 certificate request (initial enrollment).
|
|
// RFC 8894 §3.3.1.
|
|
SCEPMessageTypePKCSReq SCEPMessageType = 19
|
|
// SCEPMessageTypeGetCertInitial is a polling request for a pending certificate.
|
|
// RFC 8894 §3.3.3. Used when the prior PKCSReq returned Status=Pending and
|
|
// the client is checking whether the request has been approved.
|
|
SCEPMessageTypeGetCertInitial SCEPMessageType = 20
|
|
)
|
|
|
|
// SCEPPKIStatus represents the status of a SCEP PKI operation.
|
|
type SCEPPKIStatus string
|
|
|
|
const (
|
|
// SCEPStatusSuccess indicates the request was granted.
|
|
SCEPStatusSuccess SCEPPKIStatus = "0"
|
|
// SCEPStatusFailure indicates the request was rejected.
|
|
SCEPStatusFailure SCEPPKIStatus = "2"
|
|
// SCEPStatusPending indicates the request is pending manual approval.
|
|
SCEPStatusPending SCEPPKIStatus = "3"
|
|
)
|
|
|
|
// SCEPFailInfo represents the reason for a SCEP failure.
|
|
type SCEPFailInfo string
|
|
|
|
const (
|
|
SCEPFailBadAlg SCEPFailInfo = "0" // Unrecognized or unsupported algorithm
|
|
SCEPFailBadMessageCheck SCEPFailInfo = "1" // Integrity check failed
|
|
SCEPFailBadRequest SCEPFailInfo = "2" // Transaction not permitted or supported
|
|
SCEPFailBadTime SCEPFailInfo = "3" // Message time field was not sufficiently close to system time
|
|
SCEPFailBadCertID SCEPFailInfo = "4" // No certificate could be identified matching the provided criteria
|
|
)
|
|
|
|
// SCEPRequestEnvelope carries the parsed RFC 8894 PKIMessage authenticated
|
|
// attributes from the inbound signerInfo (RFC 8894 §3.2.1.2). Populated by
|
|
// the handler when a request comes in over the new RFC-8894 path; consumed
|
|
// by the service to thread transactionID + nonces through to the CertRep
|
|
// response and the audit trail.
|
|
//
|
|
// Fields mirror the SCEP attributes RFC 8894 §3.2.1.2 enumerates:
|
|
// - messageType: which SCEP operation (PKCSReq / RenewalReq / GetCertInitial)
|
|
// - transactionID: client-chosen identifier; server MUST echo verbatim in CertRep
|
|
// - senderNonce: 16-byte client nonce; server MUST echo as recipientNonce
|
|
// - signerCert: the device's transient self-signed cert (PKCSReq) or its
|
|
// existing valid cert (RenewalReq) — the public key in this cert is what
|
|
// the server encrypts the CertRep EnvelopedData to.
|
|
//
|
|
// The MVP fall-through path (handler::extractCSRFromPKCS7) does not populate
|
|
// this struct; it stays nil and the service layer routes to the legacy
|
|
// PKCSReq method that synthesizes a transactionID from the CSR's CommonName.
|
|
type SCEPRequestEnvelope struct {
|
|
MessageType SCEPMessageType // PKCSReq (19), RenewalReq (17), GetCertInitial (20)
|
|
TransactionID string // client-chosen ID; echoed verbatim in CertRep response
|
|
SenderNonce []byte // 16-byte client nonce; echoed as recipientNonce
|
|
SignerCert []byte // DER of the device's signing cert (for CertRep encryption)
|
|
}
|
|
|
|
// SCEPResponseEnvelope is what the service hands back to the handler so the
|
|
// handler can build the CertRep PKIMessage. The handler is responsible for
|
|
// computing the new senderNonce and signing the response with the RA cert/key
|
|
// loaded at startup (see SCEPConfig.RACertPath / RAKeyPath).
|
|
//
|
|
// Status semantics (RFC 8894 §3.3.2.1):
|
|
// - SCEPStatusSuccess: Result is non-nil and contains the issued cert + chain
|
|
// - SCEPStatusFailure: FailInfo identifies the rejection reason; Result is nil
|
|
// - SCEPStatusPending: request is queued for manual approval; Result is nil
|
|
// (client polls via GetCertInitial)
|
|
type SCEPResponseEnvelope struct {
|
|
Status SCEPPKIStatus
|
|
FailInfo SCEPFailInfo // populated only when Status == SCEPStatusFailure
|
|
TransactionID string // echo of request.TransactionID
|
|
RecipientNonce []byte // echo of request.SenderNonce
|
|
Result *SCEPEnrollResult // populated only when Status == SCEPStatusSuccess
|
|
}
|