sign

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: May 10, 2026 License: MIT Imports: 13 Imported by: 0

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

func Apply(pdfBytes []byte, opts Options) ([]byte, error)

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.

Jump to

Keyboard shortcuts

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