cms

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package cms signs and verifies attached and detached CMS signatures used by Apple device management.

Design

Detached signatures authenticate Mdm-Signature request bodies; attached signatures carry configuration-profile content. Verification requires one signer and supports explicit trust roots, an injected clock and configured signing-time tolerance. The tolerant path still validates digest, attributes, signature and chain.

A valid signature proves key possession, not authorization for an enrollment. HTTP certificate extraction and service pinning apply that separate policy. Callers select trust roots and whether profile parsing requires a signature.

References

Index

Constants

View Source
const HeaderName = "Mdm-Signature"

HeaderName is the HTTP header Apple devices use.

Variables

View Source
var (
	ErrHeader          = errors.New("cms: malformed Mdm-Signature header")
	ErrParse           = errors.New("cms: malformed CMS structure")
	ErrNoSigner        = errors.New("cms: no signer")
	ErrMultipleSigners = errors.New("cms: more than one signer")
	ErrSignature       = errors.New("cms: signature verification failed")
	ErrSigningTime     = errors.New("cms: signing time outside certificate validity")
	ErrChain           = errors.New("cms: certificate chain verification failed")
	ErrAlgorithm       = errors.New("cms: unsupported algorithm")
	ErrSign            = errors.New("cms: signing failed")
)

Errors returned by this package.

Functions

func DecodeHeader

func DecodeHeader(header string) ([]byte, error)

DecodeHeader parses an Mdm-Signature header value.

func EncodeHeader

func EncodeHeader(der []byte) string

EncodeHeader renders a DER signature as the Mdm-Signature header value.

func Fingerprint

func Fingerprint(cert *x509.Certificate) string

Fingerprint is the lower-case hex SHA-256 of the certificate's DER, the value stored for identity pinning.

func IsSigned

func IsSigned(data []byte) bool

IsSigned reports whether data looks like a DER CMS structure rather than a plain plist, so callers can accept both signed and unsigned profiles.

func Sign

func Sign(content []byte, cert *x509.Certificate, key crypto.Signer) ([]byte, error)

Sign produces a detached, DER-encoded CMS SignedData over content with SHA-256, signed by key and carrying cert.

func SignAttached

func SignAttached(content []byte, cert *x509.Certificate, key crypto.Signer) ([]byte, error)

SignAttached produces a CMS SignedData with the content embedded, which is what signed configuration profiles are (a .mobileconfig whose bytes are the DER structure).

func Verify

func Verify(der, content []byte, o VerifyOptions) (*x509.Certificate, error)

Verify checks a detached signature over content and returns the signer certificate.

func VerifyAttached

func VerifyAttached(der []byte, o VerifyOptions) ([]byte, *x509.Certificate, error)

VerifyAttached checks an attached signature and returns the embedded content and the signer certificate. The same trust and skew options as Verify apply.

func VerifyAttachedWith

func VerifyAttachedWith(der []byte, o VerifyAttachedOptions) ([]byte, *x509.Certificate, error)

VerifyAttachedWith verifies an attached SignedData the way Apple device identities sign MachineInfo: exactly one signer whose certificate is in the bundle; when authenticated attributes are present the signature covers their DER SET and the messageDigest attribute must equal the digest of the content while contentType must be id-data, otherwise the signature covers the content; digest and signature algorithms are taken from the SignerInfo. It returns the embedded content and the signer.

func VerifyHeader

func VerifyHeader(header string, body []byte, o VerifyOptions) (*x509.Certificate, error)

VerifyHeader verifies an Mdm-Signature header against the request body.

Types

type VerifyAttachedOptions

type VerifyAttachedOptions struct {
	VerifyOptions
	// IgnoreValidity builds the certificate path by name and signature
	// alone, without applying validity windows. Apple device identities
	// chain through the Apple iPhone Device CA, which expired in 2014 and
	// still issues current leaves, so stock chain verification cannot
	// accept them. SHA-1 signatures are tolerated on this path because the
	// chain uses them.
	IgnoreValidity bool
	// Anchors are trust anchors matched by identity: the path is accepted
	// when it reaches a certificate issued (by name and signature) by one
	// of them, or one of them itself. They are the trust store for
	// IgnoreValidity, since a CertPool cannot be walked; when
	// IgnoreValidity is false they are added to Roots. Nil Anchors and nil
	// Roots skip chain verification, as in Verify.
	Anchors []*x509.Certificate
}

VerifyAttachedOptions control VerifyAttachedWith.

type VerifyOptions

type VerifyOptions struct {
	// Roots, when set, requires the signer certificate to chain to one of
	// them (intermediates from the CMS structure are used). Nil skips chain
	// verification and only checks the signature itself.
	Roots *x509.CertPool
	// Now supplies the verification time; defaults to time.Now.
	Now func() time.Time
	// ClockSkew tolerates a signing time this far outside the signer
	// certificate's validity. Zero means no tolerance.
	ClockSkew time.Duration
}

VerifyOptions control Verify.

Jump to

Keyboard shortcuts

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