Documentation
¶
Overview ¶
Package sign attaches a PKCS#7 detached signature to a kardec-rendered PDF, producing a document Adobe Acrobat (and every other PDF reader that respects signatures) reports as "Signed by <X>".
The package implements PDF 1.7 §12.8 "Digital Signatures": a /AcroForm with one /Sig field, a /SubFilter /adbe.pkcs7.detached /Contents holding the PKCS#7 SignedData blob, and a /ByteRange covering the entire file except the /Contents value. The blob itself is built via github.com/digitorus/pkcs7 — a maintained fork of mozilla-services/pkcs7 — so the ASN.1 stays correct without reinventing CMS encoding.
Typical usage:
priv, cert := loadKeyAndCert(...) // crypto/x509 + crypto/rsa
doc.Render("contract.pdf") // emit the unsigned PDF
raw, _ := os.ReadFile("contract.pdf")
signed, err := sign.Apply(raw, sign.Options{
PrivateKey: priv,
Certificate: cert,
Reason: "I agree",
Location: "São Paulo, BR",
SignerName: "Arthur Carvalho",
})
os.WriteFile("contract-signed.pdf", signed, 0644)
The signed file's bytes are NOT byte-reproducible — every signature carries a fresh signing timestamp and PKCS#7 nonce per the spec. The unsigned-render reprocheck still holds; the signature step is the layer that adds randomness.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
Apply attaches a PKCS#7 detached signature to pdfBytes and returns the signed PDF. The input must already be a valid kardec-rendered PDF; the output is byte-for-byte identical to the input EXCEPT the appended signature-field objects, AcroForm catalog entry, and updated xref. Acrobat will report the signature as covering "the entire document".
Errors come from malformed input, missing PrivateKey / Certificate, or PKCS#7 build failures. None of these can leak the private key bytes — failure modes drop the operation entirely rather than emitting a partial signature.
Types ¶
type Options ¶
type Options struct {
// PrivateKey signs the document. Today only RSA is supported;
// ECDSA / Ed25519 land if real ICP-Brasil HSMs surface them.
PrivateKey *rsa.PrivateKey
// Certificate is the signer's X.509 cert. Embedded in the
// PKCS#7 blob so verifiers can check the chain without
// out-of-band lookups.
Certificate *x509.Certificate
// CertChain holds intermediate CA certificates. Optional but
// recommended — without them, readers that don't have the CA
// pre-installed warn the user "signature valid but chain
// untrusted".
CertChain []*x509.Certificate
// Reason, Location, SignerName populate the /Reason,
// /Location, /Name fields of the /Sig dict. Acrobat surfaces
// them in the signature-panel detail view.
Reason string
Location string
SignerName string
// SigningTime overrides the timestamp baked into the PKCS#7
// signedAttrs. Defaults to time.Now when zero — pass a fixed
// value when reproducible output is needed (the signature
// itself still won't be reproducible because the RSA
// signature carries random padding, but the timestamp at
// least becomes deterministic).
SigningTime time.Time
}
Options configures the signature operation. PrivateKey + Certificate are required; everything else is optional and shows up in the /Sig dict.