Documentation
¶
Overview ¶
Package pdfsign provides tools for signing and verifying PDF documents. It supports PAdES, C2PA, and JAdES signature formats with configurable visual appearances, form filling, and PDF/A compliance.
Basic usage:
doc, err := pdf.OpenFile("document.pdf")
if err != nil {
log.Fatal(err)
}
doc.Sign(signer, cert).
Reason("Approved").
Location("Amsterdam")
result, err := doc.Write(output)
See https://www.etsi.org/deliver/etsi_en/319100_319199/31914201/ for PAdES specification.
Example (VerifyStrict) ¶
Example_verifyStrict demonstrates strict verification mode.
package main
import (
"fmt"
"log"
"github.com/digitorus/pdfsign"
)
func main() {
doc, err := pdfsign.OpenFile("testfiles/testfile_multi.pdf")
if err != nil {
log.Fatal(err)
}
// Strict() enables all security checks
result := doc.Verify().Strict()
fmt.Printf("Found %d signatures\n", result.Count())
fmt.Printf("All valid: %v\n", result.Valid())
}
Output: Found 3 signatures All valid: false
Index ¶
- Constants
- type Appearance
- func (a *Appearance) Background(r, g, b uint8) *Appearance
- func (a *Appearance) Border(width float64, r, g, b uint8) *Appearance
- func (a *Appearance) Circle(cx, cy, r float64) *ShapeBuilder
- func (a *Appearance) DrawRect(x, y, width, height float64) *ShapeBuilder
- func (a *Appearance) Height() float64
- func (a *Appearance) Image(img *Image) *ImageBuilder
- func (a *Appearance) Line(x1, y1, x2, y2 float64) *LineBuilder
- func (a *Appearance) PDFObject(data []byte) *PDFObjectBuilder
- func (a *Appearance) RenderInfo() *render.AppearanceInfo
- func (a *Appearance) Standard() *Appearance
- func (a *Appearance) Text(content string) *TextBuilder
- func (a *Appearance) Width() float64
- type Color
- type Compliance
- type Document
- func (d *Document) AddFont(name string, data []byte) *Font
- func (d *Document) AddImage(name string, data []byte) *Image
- func (d *Document) AddInitials(appearance *Appearance) *initials.Builder
- func (d *Document) Font(name string) *Font
- func (d *Document) Fonts() []*Font
- func (d *Document) FormFields() []FormField
- func (d *Document) Image(name string) *Image
- func (d *Document) Images() []*Image
- func (d *Document) Reader() *pdflib.Reader
- func (d *Document) SetCompliance(c Compliance)
- func (d *Document) SetCompression(level int)
- func (d *Document) SetField(name string, value any) error
- func (d *Document) SetFields(fields map[string]any) error
- func (d *Document) SetUnit(u float64)
- func (d *Document) Sign(signer crypto.Signer, cert *x509.Certificate, ...) *SignBuilder
- func (d *Document) Signatures() iter.Seq2[*Signature, error]
- func (d *Document) Timestamp(tsaURL string) *SignBuilder
- func (d *Document) UseFont(name string, data []byte) *Font
- func (d *Document) Verify() *VerifyBuilder
- func (d *Document) Write(output io.Writer) (*Result, error)
- type DocumentInfo
- type Font
- type FontMetrics
- type FormField
- type Format
- type Image
- type ImageBuilder
- type ImageScale
- type InitialsBuilder
- type InitialsConfig
- type LineBuilder
- type PDFObjectBuilder
- type Permission
- type Position
- type Result
- type ShapeBuilder
- type SignBuilder
- func (b *SignBuilder) Appearance(a *Appearance, x, y float64) *SignBuilder
- func (b *SignBuilder) C2PAClaimGenerator(generator string) *SignBuilder
- func (b *SignBuilder) C2PACreator(creator string) *SignBuilder
- func (b *SignBuilder) CertificateChains(chains [][]*x509.Certificate) *SignBuilder
- func (b *SignBuilder) Contact(contact string) *SignBuilder
- func (b *SignBuilder) Context(ctx context.Context) *SignBuilder
- func (b *SignBuilder) Digest(hash crypto.Hash) *SignBuilder
- func (b *SignBuilder) Format(f Format) *SignBuilder
- func (b *SignBuilder) Location(location string) *SignBuilder
- func (b *SignBuilder) Page(page int) *SignBuilder
- func (b *SignBuilder) Permission(p Permission) *SignBuilder
- func (b *SignBuilder) PreferCRL(prefer bool) *SignBuilder
- func (b *SignBuilder) Reason(reason string) *SignBuilder
- func (b *SignBuilder) RevocationCache(cache sign.RevocationCache) *SignBuilder
- func (b *SignBuilder) RevocationFunction(fn sign.RevocationFunction) *SignBuilder
- func (b *SignBuilder) SignerName(name string) *SignBuilder
- func (b *SignBuilder) Timestamp(url string) *SignBuilder
- func (b *SignBuilder) TimestampAuth(username, password string) *SignBuilder
- func (b *SignBuilder) Type(t SignatureType) *SignBuilder
- func (b *SignBuilder) Unit(u float64) *SignBuilder
- type Signature
- type SignatureInfo
- type SignatureType
- type SignatureVerifyResult
- type StandardFontType
- type TextAlign
- type TextBuilder
- func (b *TextBuilder) Align(align TextAlign) *TextBuilder
- func (b *TextBuilder) AutoScale() *TextBuilder
- func (b *TextBuilder) Center() *TextBuilder
- func (b *TextBuilder) Font(font *Font, size float64) *TextBuilder
- func (b *TextBuilder) Position(x, y float64) *TextBuilder
- func (tb *TextBuilder) SetColor(r, g, b uint8) *TextBuilder
- type TimestampInfo
- type VerifyBuilder
- func (b *VerifyBuilder) AllowedAlgorithms(algos ...x509.PublicKeyAlgorithm) *VerifyBuilder
- func (b *VerifyBuilder) AllowedEKUs(ekus ...x509.ExtKeyUsage) *VerifyBuilder
- func (b *VerifyBuilder) AtTime(t time.Time) *VerifyBuilder
- func (b *VerifyBuilder) Context(ctx context.Context) *VerifyBuilder
- func (b *VerifyBuilder) Count() int
- func (b *VerifyBuilder) Document() DocumentInfo
- func (b *VerifyBuilder) Err() error
- func (b *VerifyBuilder) ExternalChecks(enable bool) *VerifyBuilder
- func (b *VerifyBuilder) HTTPTimeout(d time.Duration) *VerifyBuilder
- func (b *VerifyBuilder) MinECDSAKeySize(bits int) *VerifyBuilder
- func (b *VerifyBuilder) MinRSAKeySize(bits int) *VerifyBuilder
- func (b *VerifyBuilder) RequireDigitalSignature(require bool) *VerifyBuilder
- func (b *VerifyBuilder) RequireNonRepudiation(require bool) *VerifyBuilder
- func (b *VerifyBuilder) Signatures() []SignatureVerifyResult
- func (b *VerifyBuilder) SkipCRL(skip bool) *VerifyBuilder
- func (b *VerifyBuilder) SkipOCSP(skip bool) *VerifyBuilder
- func (b *VerifyBuilder) SkipRevocationCheck(skip bool) *VerifyBuilder
- func (b *VerifyBuilder) Strict() *VerifyBuilder
- func (b *VerifyBuilder) TrustSelfSigned(trust bool) *VerifyBuilder
- func (b *VerifyBuilder) TrustSignatureTime(trust bool) *VerifyBuilder
- func (b *VerifyBuilder) TrustedRoots(pool *x509.CertPool) *VerifyBuilder
- func (b *VerifyBuilder) Valid() bool
- func (b *VerifyBuilder) ValidateFullChain(validate bool) *VerifyBuilder
- func (b *VerifyBuilder) ValidateTimestampCertificates(validate bool) *VerifyBuilder
Examples ¶
Constants ¶
const ( // AlignLeft aligns text to the left. AlignLeft = render.AlignLeft // AlignCenter aligns text to the center. AlignCenter = render.AlignCenter // AlignRight aligns text to the right. AlignRight = render.AlignRight // ScaleStretch stretches the image to fill the rectangle. ScaleStretch = render.ScaleStretch // ScaleFit proportionally scales the image to fit within the rectangle. ScaleFit = render.ScaleFit // ScaleFill proportionally scales the image to fill the rectangle (may crop). ScaleFill = render.ScaleFill )
const ( // TopLeft positions at top-left corner. TopLeft = initials.TopLeft // TopRight positions at top-right corner. TopRight = initials.TopRight // BottomLeft positions at bottom-left corner. BottomLeft = initials.BottomLeft // BottomRight positions at bottom-right corner. BottomRight = initials.BottomRight )
const ( // Millimeter represents the number of PDF user space units in one millimeter. Millimeter = 72.0 / 25.4 // Centimeter represents the number of PDF user space units in one centimeter. Centimeter = 72.0 / 2.54 // Inch represents the number of PDF user space units in one inch. Inch = 72.0 )
const ( // Helvetica is the standard Helvetica font. Helvetica = fonts.Helvetica // HelveticaBold is bold Helvetica. HelveticaBold = fonts.HelveticaBold // HelveticaOblique is oblique Helvetica. HelveticaOblique = fonts.HelveticaOblique // TimesRoman is Times Roman font. TimesRoman = fonts.TimesRoman // TimesBold is bold Times Roman. TimesBold = fonts.TimesBold // Courier is Courier font. Courier = fonts.Courier // CourierBold is bold Courier. CourierBold = fonts.CourierBold )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Appearance ¶
type Appearance struct {
// contains filtered or unexported fields
}
Appearance represents the visual elements of a signature widget (text, images, shapes). All dimensions and coordinates within an Appearance are in PDF user space units (typically 1/72 inch).
Example (Advanced) ¶
ExampleAppearance_advanced demonstrates building a complex visual signature and verifying it.
package main
import (
"bytes"
"fmt"
"log"
"github.com/digitorus/pdfsign"
"github.com/digitorus/pdfsign/internal/testpki"
)
func main() {
// Setup: Create a PKI environment
pki := testpki.NewTestPKI(nil)
pki.StartCRLServer()
defer pki.Close()
key, cert := pki.IssueLeaf("Advanced Signer")
// Open a PDF to sign
docToSign, _ := pdfsign.OpenFile("testfiles/testfile_form.pdf")
// Create appearance with 300x100 dimensions
app := pdfsign.NewAppearance(300, 100)
// 1. Add Background and Border
app.Background(240, 240, 240) // Light Gray
app.Border(1.0, 100, 100, 100) // Dark Gray Border
// 2. Add styled text
app.Text("Digitally Signed").
Font(nil, 10). // Standard font (Helvetica)
SetColor(50, 50, 50).
Position(10, 80)
// 3. Add dynamic variables
app.Text("{{Name}}").
Font(pdfsign.StandardFont(pdfsign.HelveticaBold), 14).
SetColor(0, 0, 0).
Position(10, 60)
app.Text("Date: {{Date}}").
Font(nil, 9).
Position(10, 40)
// 4. Add a "Seal" (simulated with text here)
app.Text("[ SEAL ]").
Font(pdfsign.StandardFont(pdfsign.Courier), 12).
SetColor(0, 0, 128).
Position(220, 40)
// Sign the document with this appearance
docToSign.Sign(key, cert, pki.Chain()...).Appearance(app, 100, 300)
// Write signature
var signedBuffer bytes.Buffer
if _, err := docToSign.Write(&signedBuffer); err != nil {
log.Fatal(err)
}
// Verify the result
doc, err := pdfsign.Open(bytes.NewReader(signedBuffer.Bytes()), int64(signedBuffer.Len()))
if err != nil {
log.Fatal(err)
}
result := doc.Verify().TrustSelfSigned(true) // Trust our test PKI
fmt.Printf("Signature valid: %v\n", result.Valid())
fmt.Printf("Signer: %s\n", result.Signatures()[0].SignerName)
}
Output: Signature valid: true Signer: Advanced Signer
func NewAppearance ¶
func NewAppearance(width, height float64) *Appearance
NewAppearance initializes a new signature appearance box with the given width and height. Dimensions are in PDF user space units (typically 1/72 inch). You can use the Millimeter or Centimeter constants for conversion (e.g., pdfsign.Millimeter * 50).
Example ¶
ExampleNewAppearance demonstrates creating a basic appearance.
package main
import (
"fmt"
"github.com/digitorus/pdfsign"
)
func main() {
app := pdfsign.NewAppearance(200, 80)
app.Text("Digitally Signed").Position(10, 40)
fmt.Printf("Appearance: %gx%g\n", app.Width(), app.Height())
}
Output: Appearance: 200x80
func (*Appearance) Background ¶
func (a *Appearance) Background(r, g, b uint8) *Appearance
Background sets the fill color for the signature widget background.
func (*Appearance) Border ¶
func (a *Appearance) Border(width float64, r, g, b uint8) *Appearance
Border draws a rectangular border around the signature widget with the specified width and RGB color.
func (*Appearance) Circle ¶
func (a *Appearance) Circle(cx, cy, r float64) *ShapeBuilder
Circle adds a circle centered at (cx, cy) with radius r. Style with Fill(), Stroke(), StrokeWidth() - order doesn't matter.
func (*Appearance) DrawRect ¶
func (a *Appearance) DrawRect(x, y, width, height float64) *ShapeBuilder
DrawRect adds a rectangle at (x, y) with given dimensions. Style with Fill(), Stroke(), StrokeWidth() - order doesn't matter.
func (*Appearance) Height ¶
func (a *Appearance) Height() float64
Height returns the appearance height.
func (*Appearance) Image ¶
func (a *Appearance) Image(img *Image) *ImageBuilder
Image adds a raster image element (JPEG, PNG) to the appearance. Returns an ImageBuilder to configure position, size, and scaling.
func (*Appearance) Line ¶
func (a *Appearance) Line(x1, y1, x2, y2 float64) *LineBuilder
Line adds a line from (x1,y1) to (x2,y2).
func (*Appearance) PDFObject ¶
func (a *Appearance) PDFObject(data []byte) *PDFObjectBuilder
PDFObject adds a PDF page as a vector graphic element (Form XObject). This is useful for embedding vector graphics, logos, or other PDF content. The first page (page 1) is used by default.
func (*Appearance) RenderInfo ¶
func (a *Appearance) RenderInfo() *render.AppearanceInfo
RenderInfo returns the internal representation of the appearance for rendering.
func (*Appearance) Standard ¶
func (a *Appearance) Standard() *Appearance
Standard populates the appearance with a professional signature layout. It displays the signer's name prominently, followed by the reason, location, and signing date.
Template variables ({{Name}}, {{Reason}}, {{Location}}, {{Date}}) are automatically expanded with the values from the SignBuilder.
Example:
app := pdf.NewAppearance(300, 100).Standard()
Example ¶
ExampleAppearance_Standard demonstrates using the built-in standard appearance.
package main
import (
"bytes"
"fmt"
"github.com/digitorus/pdfsign"
"github.com/digitorus/pdfsign/internal/testpki"
)
func main() {
// Create a standard appearance with professional metadata layout
app := pdfsign.NewAppearance(300, 100).Standard()
// The Standard() method pre-populates the appearance with:
// - {{Name}} - Signer name (larger font)
// - Reason: {{Reason}}
// - Location: {{Location}}
// - Date: {{Date}}
// These template variables are automatically expanded when the signature
// is rendered, using values from SignBuilder's SignerName(), Reason(), Location().
fmt.Printf("Standard appearance with dimensions %gx%g\n", app.Width(), app.Height())
// Demonstrate actual usage
pki := testpki.NewTestPKI(nil)
pki.StartCRLServer()
defer pki.Close()
key, cert := pki.IssueLeaf("Standard Signer")
docToSign, _ := pdfsign.OpenFile("testfiles/testfile_form.pdf")
docToSign.Sign(key, cert).Appearance(app, 100, 100)
var buf bytes.Buffer
_, _ = docToSign.Write(&buf)
// Verify
signedDoc, _ := pdfsign.Open(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
if signedDoc.Verify().TrustSelfSigned(true).Valid() {
fmt.Println("Successfully signed and verified with standard appearance")
}
}
Output: Standard appearance with dimensions 300x100 Successfully signed and verified with standard appearance
func (*Appearance) Text ¶
func (a *Appearance) Text(content string) *TextBuilder
Text adds a text string to the appearance and returns a TextBuilder for configuration. Supports template variables which are expanded at signing time.
type Color ¶
Color is an alias for render.Color for backward compatibility. Deprecated: Use render.Color directly.
type Compliance ¶
type Compliance int
Compliance represents PDF/A compliance levels.
const ( // DefaultCompliance means no specific compliance enforcement (default). // The library will produce a valid PDF signature but will not strictly enforce all PDF/A constraints. DefaultCompliance Compliance = iota // PDFA_1B is not yet enforced. PDFA_1B // PDFA_2B is not yet enforced. PDFA_2B // PDFA_3B is not yet enforced. PDFA_3B )
type Document ¶
type Document struct {
// contains filtered or unexported fields
}
Document represents a PDF document that can be signed, verified, or modified.
Concurrency: a Document (and the SignBuilder(s) returned by Sign) is a sequential staging area, not safe for concurrent use - build it up from a single goroutine, then call Write. This differs from VerifyBuilder (see its doc comment), which is safe to query concurrently once configured; staging signing operations is inherently a mutable, ordered process (each Sign call appends to the document's pending operations), so unlike verification there's no natural "configure once, read many times from many goroutines" use case to make safe.
func Open ¶
Open initializes a PDF Document from an io.ReaderAt (e.g., an open file or memory buffer). The size parameter must be the total size of the PDF in bytes. Encrypted documents can only be opened if the user password is empty; use OpenWithPassword otherwise.
func OpenFileWithPassword ¶
OpenFileWithPassword is a convenience method to initialize a PDF Document from an encrypted file on disk, see OpenWithPassword.
func OpenWithPassword ¶
OpenWithPassword initializes a PDF Document like Open, using password (the user or owner password) to open an encrypted document. Objects added to an encrypted document, such as signatures, are encrypted with the document's key, and the document stays encrypted.
func (*Document) AddFont ¶
AddFont registers a new font with the document. If a font with the same name already exists, the existing font is returned. If data is provided, it will be parsed for metrics (for accurate text measurement).
Example ¶
ExampleDocument_AddFont demonstrates usage of custom fonts for signing and initials.
package main
import (
"bytes"
"fmt"
"log"
"os"
"github.com/digitorus/pdfsign"
"github.com/digitorus/pdfsign/internal/testpki"
)
func main() {
testFile := "testfiles/testfile20.pdf"
// Ensure test file and font exist
if _, err := os.Stat(testFile); os.IsNotExist(err) {
fmt.Println("Test file not found")
return
}
fontFile := "testfiles/fonts/GreatVibes-Regular.ttf"
fontData, err := os.ReadFile(fontFile)
if err != nil {
// Fallback for example if file missing in some envs
fmt.Println("Font file not found")
return
}
doc, err := pdfsign.OpenFile(testFile)
if err != nil {
fmt.Printf("Error opening file: %v\n", err)
return
}
// 1. Register the custom font
// This embeds the font subset in the PDF when used.
customFont := doc.AddFont("GreatVibes", fontData)
// 2. Use the font in an appearance
appearance := pdfsign.NewAppearance(200, 50)
appearance.Text("Signed with Style").
Font(customFont, 24).
Position(10, 15)
// 3. Or use for Initials
initials := pdfsign.NewAppearance(50, 30)
initials.Text("JD").Font(customFont, 20).Center()
// ... sign and write ...
pki := testpki.NewTestPKI(nil)
pki.StartCRLServer()
defer pki.Close()
key, cert := pki.IssueLeaf("Custom Font Signer")
doc.Sign(key, cert).Appearance(appearance, 100, 100)
var buf bytes.Buffer
if _, err := doc.Write(&buf); err != nil {
log.Fatal(err)
}
// Verify
signedDoc, _ := pdfsign.Open(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
if signedDoc.Verify().TrustSelfSigned(true).Valid() {
fmt.Println("Successfully signed and verified with custom font")
}
}
Output: Successfully signed and verified with custom font
func (*Document) AddImage ¶
AddImage registers an image with the document. If an image with the same name already exists, the existing image is returned.
func (*Document) AddInitials ¶
func (d *Document) AddInitials(appearance *Appearance) *initials.Builder
AddInitials adds initials to all pages.
Example ¶
ExampleDocument_AddInitials demonstrates adding initials to pages.
package main
import (
"bytes"
"fmt"
"os"
"github.com/digitorus/pdfsign"
"github.com/digitorus/pdfsign/internal/testpki"
)
func main() {
testFile := "testfiles/testfile20.pdf"
if _, err := os.Stat(testFile); os.IsNotExist(err) {
fmt.Println("Test file not found")
return
}
doc, err := pdfsign.OpenFile(testFile)
if err != nil {
fmt.Printf("Error opening file: %v\n", err)
return
}
pki := testpki.NewTestPKI(nil)
pki.StartCRLServer()
defer pki.Close()
key, cert := pki.IssueLeaf("Initials Signer")
// Define initials appearance
initials := pdfsign.NewAppearance(40, 20)
initials.Text("{{Initials}}").Center()
// Apply initials
doc.AddInitials(initials).
Position(pdfsign.BottomRight, 30, 30).
ExcludePages(1) // Don't put initials on cover page
// We create a temporary output file for the example
outputFile, _ := os.CreateTemp("", "initials-example-*.pdf")
defer func() { _ = os.Remove(outputFile.Name()) }()
defer func() { _ = outputFile.Close() }()
// Sign to finalize
doc.Sign(key, cert).SignerName("Initials Signer")
var buf bytes.Buffer
if _, err := doc.Write(&buf); err != nil {
fmt.Printf("Error writing: %v\n", err)
return
}
// Verify
signedDoc, _ := pdfsign.Open(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
if signedDoc.Verify().TrustSelfSigned(true).Valid() {
fmt.Printf("Successfully added initials and verified: %s\n", signedDoc.Verify().Signatures()[0].SignerName)
}
}
Output: Successfully added initials and verified: Initials Signer
func (*Document) FormFields ¶
FormFields returns all form fields in the document.
func (*Document) Reader ¶
Reader returns the low-level PDF reader, allowing direct access to the PDF Cross-Reference (XRef) table and objects.
func (*Document) SetCompliance ¶
func (d *Document) SetCompliance(c Compliance)
SetCompliance sets the PDF/A compliance level.
WARNING: This method is currently a placeholder and does not enforce PDF/A compliance. It is preserved for future implementation.
func (*Document) SetCompression ¶
SetCompression configures the zlib compression level for new objects added to the PDF. Supported levels are zlib.NoCompression, zlib.BestSpeed, zlib.BestCompression, or zlib.DefaultCompression.
Example ¶
ExampleDocument_SetCompression demonstrates how to configure compression levels.
package main
import (
"bytes"
"fmt"
"log"
"os"
"github.com/digitorus/pdfsign"
"github.com/digitorus/pdfsign/internal/testpki"
)
func main() {
testFile := "testfiles/testfile20.pdf"
if _, err := os.Stat(testFile); os.IsNotExist(err) {
fmt.Println("Test file not found")
return
}
doc, err := pdfsign.OpenFile(testFile)
if err != nil {
fmt.Printf("Error opening file: %v\n", err)
return
}
// ... continue with signing ...
pki := testpki.NewTestPKI(nil)
pki.StartCRLServer()
defer pki.Close()
key, cert := pki.IssueLeaf("Compressed Signer")
doc.Sign(key, cert).Reason("Compression Test")
var buf bytes.Buffer
if _, err := doc.Write(&buf); err != nil {
log.Fatal(err)
}
// Verify
signedDoc, _ := pdfsign.Open(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
if signedDoc.Verify().TrustSelfSigned(true).Valid() {
fmt.Println("Signed and verified with BestCompression")
}
}
Output: Signed and verified with BestCompression
func (*Document) SetUnit ¶
SetUnit sets the default coordinate system scale for all subsequent operations on this document (e.g., signing appearances). By default, the unit is 1.0 (one PDF point = 1/72 inch).
func (*Document) Sign ¶
func (d *Document) Sign(signer crypto.Signer, cert *x509.Certificate, intermediates ...*x509.Certificate) *SignBuilder
Sign begins the process of adding a digital signature to the document. It returns a SignBuilder for fluent configuration of the signature properties. The signature is only finalized and written to the document when doc.Write() is called.
- signer: The private key used for signing.
- cert: The signer's public certificate.
- intermediates: Optional intermediate certificates to include in the certificate chain.
Example ¶
ExampleDocument_Sign demonstrates the flow for signing a document.
package main
import (
"bytes"
"fmt"
"log"
"github.com/digitorus/pdfsign"
"github.com/digitorus/pdfsign/internal/testpki"
)
func main() {
// 1. Open Document
doc, err := pdfsign.OpenFile("testfiles/testfile_form.pdf")
if err != nil {
log.Fatal(err)
}
// 2. Prepare visual appearance
appearance := pdfsign.NewAppearance(200, 80)
appearance.Text("Digitally Signed").Position(10, 40)
// 3. Load Certificate and Private Key using test PKI
pki := testpki.NewTestPKI(nil)
pki.StartCRLServer()
defer pki.Close()
key, cert := pki.IssueLeaf("Example Signer")
// 4. Create Output
var buf bytes.Buffer
// 5. Sign with fluent API
doc.Sign(key, cert, pki.Chain()...).
Reason("Contract Agreement").
Location("New York").
Appearance(appearance, 100, 100)
_, err = doc.Write(&buf)
if err != nil {
log.Fatal(err)
}
// 6. Verify the signed document
signedDoc, _ := pdfsign.Open(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
result := signedDoc.Verify().TrustSelfSigned(true)
if result.Valid() {
fmt.Printf("Successfully signed and verified: %s\n", result.Signatures()[0].SignerName)
}
}
Output: Successfully signed and verified: Example Signer
Example (Multiple) ¶
ExampleDocument_Sign_multiple demonstrates staging more than one signature on the same document. Each call to Sign() stages an independent signing operation; nothing is executed yet. Write() then applies every staged signature in the order Sign() was called, each one an incremental update chained on top of the previous signature's output - the same as an approver countersigning a document someone else already signed.
package main
import (
"bytes"
"fmt"
"log"
"github.com/digitorus/pdfsign"
"github.com/digitorus/pdfsign/internal/testpki"
)
func main() {
doc, err := pdfsign.OpenFile("testfiles/testfile_form.pdf")
if err != nil {
log.Fatal(err)
}
pki := testpki.NewTestPKI(nil)
pki.StartCRLServer()
defer pki.Close()
aliceKey, aliceCert := pki.IssueLeaf("Alice")
bobKey, bobCert := pki.IssueLeaf("Bob")
// Stage Alice's signature, then Bob's. Order matters: Bob's signature
// will be applied on top of Alice's, not the other way around.
doc.Sign(aliceKey, aliceCert, pki.Chain()...).Reason("First approval")
doc.Sign(bobKey, bobCert, pki.Chain()...).Reason("Second approval")
var buf bytes.Buffer
if _, err := doc.Write(&buf); err != nil {
log.Fatal(err)
}
signedDoc, _ := pdfsign.Open(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
result := signedDoc.Verify().TrustSelfSigned(true)
fmt.Printf("Found %d signatures, all valid: %v\n", result.Count(), result.Valid())
for _, sig := range result.Signatures() {
fmt.Printf("Signed by: %s\n", sig.SignerName)
}
}
Output: Found 2 signatures, all valid: true Signed by: Alice Signed by: Bob
Example (PostQuantumOnly) ¶
ExampleDocument_Sign_postQuantumOnly signs and validates a PAdES B-T PDF without introducing a classical public-key signature in the signer, CA, revocation, or timestamp paths.
package main
import (
"bytes"
"crypto"
"crypto/x509"
"fmt"
"log"
"github.com/digitorus/pdfsign"
"github.com/digitorus/pdfsign/internal/testpki"
)
func main() {
doc, err := pdfsign.OpenFile("testfiles/testfile12.pdf")
if err != nil {
log.Fatal(err)
}
pki := testpki.NewTestPKIWithConfig(nil, testpki.TestPKIConfig{
Profile: testpki.MLDSA_65,
IntermediateCAs: 1,
})
pki.StartCRLServer()
defer pki.Close()
privateKey, certificate := pki.IssueLeaf("PQC PDF Signer")
tsaURL := pki.StartMockTSA()
doc.Sign(privateKey, certificate, pki.Chain()...).
Format(pdfsign.PAdES_B_T).
Digest(crypto.SHA512).
Timestamp(tsaURL).
Reason("Post-quantum approval")
var output bytes.Buffer
if _, err := doc.Write(&output); err != nil {
log.Fatal(err)
}
signed, err := pdfsign.Open(bytes.NewReader(output.Bytes()), int64(output.Len()))
if err != nil {
log.Fatal(err)
}
result := signed.Verify().
TrustedRoots(pki.RootPool()).
AllowedAlgorithms(x509.MLDSA).
ValidateFullChain(true).
ValidateTimestampCertificates(true).
ExternalChecks(true)
signature := result.Signatures()[0]
pqcSignerAndTSA := signature.Certificate.PublicKeyAlgorithm == x509.MLDSA &&
signature.Timestamp != nil && signature.Timestamp.Certificate.PublicKeyAlgorithm == x509.MLDSA
fmt.Printf("ML-DSA signer and TSA: %t\n", pqcSignerAndTSA)
fmt.Printf("OCSP and CRL checked: %t\n", pki.OCSPRequests > 0 && pki.Requests > 0)
fmt.Printf("Signature and timestamp valid: %t\n", result.Valid() && signature.TimestampValid)
}
Output: ML-DSA signer and TSA: true OCSP and CRL checked: true Signature and timestamp valid: true
func (*Document) Signatures ¶
Signatures returns an iterator over all signature dictionaries in the document.
func (*Document) Timestamp ¶
func (d *Document) Timestamp(tsaURL string) *SignBuilder
Timestamp adds a document-level timestamp signature.
func (*Document) Verify ¶
func (d *Document) Verify() *VerifyBuilder
Verify initializes a VerifyBuilder to configure and execute signature verification. The verification process is lazy and only executes when you access the results (e.g., via Valid() or Signatures()).
Example ¶
ExampleDocument_Verify demonstrates how to verify a signed PDF with the fluent API.
package main
import (
"bytes"
"crypto/x509"
"fmt"
"log"
"github.com/digitorus/pdfsign"
"github.com/digitorus/pdfsign/internal/testpki"
)
func main() {
// Setup: Create a signed PDF in memory to verify
pki := testpki.NewTestPKI(nil) // Use nil for examples (uses log.Fatal on error)
pki.StartCRLServer()
defer pki.Close()
key, cert := pki.IssueLeaf("Example Signer")
docToSign, _ := pdfsign.OpenFile("testfiles/testfile_form.pdf")
appearance := pdfsign.NewAppearance(200, 80)
appearance.Text("Digitally Signed").Position(10, 40)
docToSign.Sign(key, cert, pki.Chain()...).Appearance(appearance, 100, 100)
var signedBuffer bytes.Buffer
if _, err := docToSign.Write(&signedBuffer); err != nil {
log.Fatal(err)
}
// --- Verification with Fluent API ---
doc, err := pdfsign.Open(bytes.NewReader(signedBuffer.Bytes()), int64(signedBuffer.Len()))
if err != nil {
log.Fatal(err)
}
// Configure verification with chainable methods
// Access .Valid() triggers lazy execution
// TrustedRoots is used here (rather than the TrustSelfSigned(true)
// escape hatch) to exercise real chain-of-trust validation against the
// example's test CA root, the way a caller with a real private root CA
// would.
result := doc.Verify().
TrustedRoots(pki.RootPool()).
TrustSignatureTime(true).
MinRSAKeySize(2048).
AllowedAlgorithms(x509.ECDSA)
// Check validity (this triggers the actual verification)
if result.Valid() {
fmt.Println("Document is valid")
for _, sig := range result.Signatures() {
fmt.Printf("Signed by: %s\n", sig.SignerName)
}
} else {
fmt.Println("Document has invalid signatures")
if result.Err() != nil {
fmt.Printf("Error: %v\n", result.Err())
}
}
}
Output: Document is valid Signed by: Example Signer
func (*Document) Write ¶
Write finalizes the document by executing all staged operations (signatures, form filling, initials). It performs incremental updates to the PDF and writes the resulting bytes to the provided writer.
Calling Sign() more than once before Write() stages multiple signatures; each is applied in the order Sign() was called, as an incremental update chained on top of the previous signature's output (e.g. an approver countersigning a document someone else already signed). See ExampleDocument_Sign_multiple.
type DocumentInfo ¶
type DocumentInfo struct {
Author string
Creator string
Title string
Subject string
Producer string
Pages int
CreationDate time.Time
ModDate time.Time
}
DocumentInfo contains information about the PDF document.
type Font ¶
Font is an alias for fonts.Font for backward compatibility. Deprecated: Use fonts.Font directly.
func StandardFont ¶
func StandardFont(ft StandardFontType) *Font
StandardFont returns a Font for a standard PDF font. Deprecated: Use fonts.Standard directly.
type FontMetrics ¶
FontMetrics is an alias for fonts.Metrics for backward compatibility. Deprecated: Use fonts.Metrics directly.
func ParseTTFMetrics ¶
func ParseTTFMetrics(data []byte) (*FontMetrics, error)
ParseTTFMetrics parses a TrueType font file and extracts glyph metrics. Deprecated: Use fonts.ParseTTFMetrics directly.
type FormField ¶
FormField is an alias for forms.FormField for backward compatibility. Deprecated: Use forms.FormField directly.
type Format ¶
type Format int
Format represents the signature format.
const ( // DefaultFormat keeps the legacy /adbe.pkcs7.detached profile with embedded // revocation info (OCSP/CRL). It is not PAdES: it carries a CMS signing-time // attribute, which the baseline profiles forbid. DefaultFormat Format = iota // PAdES_B (PAdES Baseline B-B) selects the supported ETSI signature // construction rules. It does not by itself establish certificate trust, // legal qualification, or compliance of caller-controlled inputs. // It does not embed revocation information. PAdES_B // PAdES_B_T (Baseline-Timestamp) extends PAdES-B-B by requiring a timestamp from a // Time Stamp Authority (TSA). The response is cryptographically checked and // bound to the request, but callers remain responsible for selecting a TSA // whose certificate and policy they trust. Requires a TSA URL to be configured. PAdES_B_T // PAdES_B_LT (Baseline-Long-Term) extends PAdES-B-T by embedding validation material // (OCSP responses and/or CRLs) into the signature. This allows the signature to be validated // even if the original CA services are offline or the certificate has expired (provided // the revocation data was valid at signing time). // // Not yet supported: rejected until the DSS dictionary it requires is written. PAdES_B_LT // PAdES_B_LTA (Baseline-Long-Term-Availability) is not yet supported. // It would add document-level timestamps to protect the LTV data over time. PAdES_B_LTA // C2PA is Content Authenticity signature format (not yet supported). C2PA // JAdES_B_T is JAdES Baseline B-T level (not yet supported). JAdES_B_T // PAdES_B_B is the standards-aligned name for PAdES_B. PAdES_B is retained // for source compatibility. PAdES_B_B = PAdES_B )
type Image ¶
Image is an alias for images.Image for backward compatibility. Deprecated: Use images.Image directly.
type ImageBuilder ¶
type ImageBuilder struct {
// contains filtered or unexported fields
}
ImageBuilder builds an image element within an appearance.
func (*ImageBuilder) Opacity ¶
func (b *ImageBuilder) Opacity(percent float64) *ImageBuilder
Opacity sets the image opacity as a percentage from 0 (fully transparent) to 100 (fully opaque).
func (*ImageBuilder) Rect ¶
func (b *ImageBuilder) Rect(x, y, width, height float64) *ImageBuilder
Rect sets the position and size of the image.
func (*ImageBuilder) ScaleFit ¶
func (b *ImageBuilder) ScaleFit() *ImageBuilder
ScaleFit sets the scaling to fit within bounds.
func (*ImageBuilder) ScaleStretch ¶
func (b *ImageBuilder) ScaleStretch() *ImageBuilder
ScaleStretch sets the scaling to stretch to fill bounds.
type ImageScale ¶
type ImageScale = render.ImageScale
ImageScale is an alias for render.ImageScale for backward compatibility. Deprecated: Use render.ImageScale directly.
type InitialsBuilder ¶
InitialsBuilder is an alias for initials.Builder for backward compatibility. Deprecated: Use initials.Builder directly.
type InitialsConfig ¶
InitialsConfig is an alias for initials.Config for backward compatibility. Deprecated: Use initials.Config directly.
type LineBuilder ¶
type LineBuilder struct {
// contains filtered or unexported fields
}
LineBuilder builds a line element.
func (*LineBuilder) Stroke ¶
func (b *LineBuilder) Stroke(r, g, b_ uint8) *LineBuilder
Stroke sets the line color.
func (*LineBuilder) Width ¶
func (b *LineBuilder) Width(w float64) *LineBuilder
Width sets the line width.
type PDFObjectBuilder ¶
type PDFObjectBuilder struct {
// contains filtered or unexported fields
}
PDFObjectBuilder builds a PDF Form XObject element from an embedded PDF.
func (*PDFObjectBuilder) Page ¶
func (b *PDFObjectBuilder) Page(p int) *PDFObjectBuilder
Page sets which page of the PDF to use (1-indexed).
func (*PDFObjectBuilder) Rect ¶
func (b *PDFObjectBuilder) Rect(x, y, width, height float64) *PDFObjectBuilder
Rect sets the position and size of the PDF object.
type Permission ¶
type Permission int
Permission represents document modification permissions for certification signatures.
const ( // NoChanges guarantees that the document has not been modified in any way. // Any subsequent change will invalidate the signature. NoChanges Permission = iota + 1 // AllowFormFilling permits the user to fill in form fields and sign the document, // but not to add comments or annotations. AllowFormFilling // AllowFormFillingAndAnnotations permits the user to fill forms, sign, and add // comments or annotations (e.g., sticky notes). AllowFormFillingAndAnnotations )
type Position ¶
Position is an alias for initials.Position for backward compatibility. Deprecated: Use initials.Position directly.
type Result ¶
type Result struct {
Signatures []SignatureInfo
Document *Document
}
Result contains the result of a Write operation.
type ShapeBuilder ¶
type ShapeBuilder struct {
// contains filtered or unexported fields
}
ShapeBuilder builds rect and circle elements.
func (*ShapeBuilder) Fill ¶
func (b *ShapeBuilder) Fill(r, g, b_ uint8) *ShapeBuilder
Fill sets the fill color.
func (*ShapeBuilder) IsElement ¶
func (*ShapeBuilder) IsElement()
func (*ShapeBuilder) Stroke ¶
func (b *ShapeBuilder) Stroke(r, g, b_ uint8) *ShapeBuilder
Stroke sets the stroke color.
func (*ShapeBuilder) StrokeWidth ¶
func (b *ShapeBuilder) StrokeWidth(w float64) *ShapeBuilder
StrokeWidth sets the stroke width.
type SignBuilder ¶
type SignBuilder struct {
// contains filtered or unexported fields
}
SignBuilder builds a signature configuration.
func (*SignBuilder) Appearance ¶
func (b *SignBuilder) Appearance(a *Appearance, x, y float64) *SignBuilder
Appearance sets the visual appearance of the signature widget and its position on the page. The appearance can include text, images, or graphics.
- x, y: The coordinates in the current Unit (default is PDF points). (0, 0) is usually the bottom-left corner of the page.
Placed on page 1 by default; use Page to place it on a different page.
func (*SignBuilder) C2PAClaimGenerator ¶
func (b *SignBuilder) C2PAClaimGenerator(generator string) *SignBuilder
C2PAClaimGenerator sets the C2PA claim generator.
func (*SignBuilder) C2PACreator ¶
func (b *SignBuilder) C2PACreator(creator string) *SignBuilder
C2PACreator sets the C2PA creator tool name.
func (*SignBuilder) CertificateChains ¶
func (b *SignBuilder) CertificateChains(chains [][]*x509.Certificate) *SignBuilder
CertificateChains sets the certificate chains for the signature. Deprecated: Use the variadic arguments in `doc.Sign` instead to provide intermediate certificates.
func (*SignBuilder) Contact ¶
func (b *SignBuilder) Contact(contact string) *SignBuilder
Contact provides contact information for the signer (e.g., email address or phone number) to allow recipients to verify the signature.
func (*SignBuilder) Context ¶
func (b *SignBuilder) Context(ctx context.Context) *SignBuilder
Context bounds external HTTP requests made while signing: TSA requests from Timestamp() and OCSP/CRL requests made by the builder's default revocation handler. Cancelling ctx aborts an in-flight request immediately. Use this to tie signing to a caller's own deadline or cancellation signal (e.g. an incoming HTTP request's context, or os/signal.NotifyContext). If not set, requests run under context.Background(), bounded by an internal default timeout. A custom RevocationFunction remains responsible for its own context.
func (*SignBuilder) Digest ¶
func (b *SignBuilder) Digest(hash crypto.Hash) *SignBuilder
Digest sets the CMS content digest and PDF /DigestMethod. The default is SHA-256 for classical signers and SHA-512 for ML-DSA signers. ML-DSA callers must use SHA-512 because that is the RFC 9882 digest emitted by the PKCS#7 implementation.
func (*SignBuilder) Format ¶
func (b *SignBuilder) Format(f Format) *SignBuilder
Format configures the signature format (e.g., PAdES_B). This determines whether revocation info is embedded (LTV) and other compliance features. DefaultFormat (revocation embedded) is used if not specified.
Example ¶
ExampleSignBuilder_Format creates a PAdES B-B signature (ETSI EN 319 142-1) with Format(PAdES_B). The unsupported levels PAdES_B_LT and PAdES_B_LTA are rejected by Write until DSS support is implemented.
package main
import (
"bytes"
"fmt"
"log"
"github.com/digitorus/pdfsign"
"github.com/digitorus/pdfsign/internal/testpki"
)
func main() {
doc, err := pdfsign.OpenFile("testfiles/testfile_form.pdf")
if err != nil {
log.Fatal(err)
}
pki := testpki.NewTestPKI(nil)
pki.StartCRLServer()
defer pki.Close()
key, cert := pki.IssueLeaf("Example Signer")
doc.Sign(key, cert, pki.Chain()...).Format(pdfsign.PAdES_B)
var buf bytes.Buffer
if _, err := doc.Write(&buf); err != nil {
log.Fatal(err)
}
signedDoc, _ := pdfsign.Open(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
result := signedDoc.Verify().TrustSelfSigned(true)
fmt.Printf("valid: %t, PAdES: %t\n", result.Valid(),
bytes.Contains(buf.Bytes(), []byte("/SubFilter /ETSI.CAdES.detached")))
}
Output: valid: true, PAdES: true
Example (PadesBT) ¶
ExampleSignBuilder_Format_padesBT creates a PAdES B-T signature: B-B plus a signature-time-stamp from the TSA that Format(PAdES_B_T) requires.
package main
import (
"bytes"
"fmt"
"log"
"github.com/digitorus/pdfsign"
"github.com/digitorus/pdfsign/internal/testpki"
)
func main() {
doc, err := pdfsign.OpenFile("testfiles/testfile_form.pdf")
if err != nil {
log.Fatal(err)
}
pki := testpki.NewTestPKI(nil)
pki.StartCRLServer()
defer pki.Close()
key, cert := pki.IssueLeaf("Example Signer")
tsaURL := testpki.StartMockTSA(nil) // replace with your TSA URL
doc.Sign(key, cert, pki.Chain()...).Format(pdfsign.PAdES_B_T).Timestamp(tsaURL)
var buf bytes.Buffer
if _, err := doc.Write(&buf); err != nil {
log.Fatal(err)
}
signedDoc, _ := pdfsign.Open(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
result := signedDoc.Verify().TrustSelfSigned(true)
fmt.Printf("valid: %t, PAdES: %t\n", result.Valid(),
bytes.Contains(buf.Bytes(), []byte("/SubFilter /ETSI.CAdES.detached")))
}
Output: valid: true, PAdES: true
func (*SignBuilder) Location ¶
func (b *SignBuilder) Location(location string) *SignBuilder
Location specifies the physical location of the signer (e.g., "New York, USA").
func (*SignBuilder) Page ¶
func (b *SignBuilder) Page(page int) *SignBuilder
Page sets the page number (starting from 1 for the first page) that the appearance configured via Appearance is placed on. Defaults to 1 if not called. Can be chained before or after Appearance.
Example ¶
ExampleSignBuilder_Page demonstrates placing signature appearances on specific pages of a multi-page document: an explicit fixed page, and the last page computed dynamically via Reader().NumPage() so it still works if pages are added or removed.
package main
import (
"bytes"
"fmt"
"log"
"github.com/digitorus/pdfsign"
"github.com/digitorus/pdfsign/internal/testpki"
)
func main() {
doc, err := pdfsign.OpenFile("testfiles/testfile12.pdf")
if err != nil {
log.Fatal(err)
}
pki := testpki.NewTestPKI(nil)
pki.StartCRLServer()
defer pki.Close()
authorKey, authorCert := pki.IssueLeaf("Author")
approverKey, approverCert := pki.IssueLeaf("Approver")
appearance := pdfsign.NewAppearance(200, 80)
appearance.Text("Signed").Position(10, 40)
lastPage := doc.Reader().NumPage()
// Sign the first page explicitly.
doc.Sign(authorKey, authorCert, pki.Chain()...).
Reason("Drafted").
Appearance(appearance, 100, 100).
Page(1)
// Sign the last page, whatever it currently is.
doc.Sign(approverKey, approverCert, pki.Chain()...).
Reason("Approved").
Appearance(appearance, 100, 100).
Page(lastPage)
var buf bytes.Buffer
if _, err := doc.Write(&buf); err != nil {
log.Fatal(err)
}
signedDoc, _ := pdfsign.Open(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
result := signedDoc.Verify().TrustSelfSigned(true)
fmt.Printf("Document has %d pages, both signatures valid: %v\n", lastPage, result.Valid())
}
Output: Document has 2 pages, both signatures valid: true
func (*SignBuilder) Permission ¶
func (b *SignBuilder) Permission(p Permission) *SignBuilder
Permission limits what changes are allowed to the document after signing. This is only applicable for CertificationSignatures. Default is AllowFormFilling if not specified for certification.
func (*SignBuilder) PreferCRL ¶
func (b *SignBuilder) PreferCRL(prefer bool) *SignBuilder
PreferCRL sets whether the legacy DefaultFormat handler prefers CRL over OCSP for revocation checks. By default, it prefers OCSP (if available) as it produces smaller signatures. PAdES_B and PAdES_B_T do not fetch or embed revocation data by default.
func (*SignBuilder) Reason ¶
func (b *SignBuilder) Reason(reason string) *SignBuilder
Reason sets the signing reason (e.g., "I agree to the terms", "I am the author"). This text appears in the signature widget and signature properties.
func (*SignBuilder) RevocationCache ¶
func (b *SignBuilder) RevocationCache(cache sign.RevocationCache) *SignBuilder
RevocationCache sets the cache for revocation data (CRL/OCSP) used by the legacy DefaultFormat handler. PAdES_B and PAdES_B_T do not fetch or embed revocation data by default.
func (*SignBuilder) RevocationFunction ¶
func (b *SignBuilder) RevocationFunction(fn sign.RevocationFunction) *SignBuilder
RevocationFunction sets a custom function to handle revocation fetching (CRL/OCSP). If not set, the library uses its built-in handler. PAdES_B and PAdES_B_T reject functions that add Adobe revocation information to the CMS; PAdES validation material belongs in the PDF DSS dictionary at B-LT or later.
func (*SignBuilder) SignerName ¶
func (b *SignBuilder) SignerName(name string) *SignBuilder
SignerName sets the visual name of the signer. Ideally this matches the Common Name (CN) in the signing certificate, but it can be customized.
func (*SignBuilder) Timestamp ¶
func (b *SignBuilder) Timestamp(url string) *SignBuilder
Timestamp enables RFC 3161 timestamping using the provided Time Stamp Authority (TSA) URL. The response signature and request binding are checked; selecting and trusting the TSA and its policy remain caller responsibilities. The timestamp is embedded in the signature to provide evidence of signing time.
func (*SignBuilder) TimestampAuth ¶
func (b *SignBuilder) TimestampAuth(username, password string) *SignBuilder
TimestampAuth sets TSA authentication credentials.
func (*SignBuilder) Type ¶
func (b *SignBuilder) Type(t SignatureType) *SignBuilder
Type specifies the type of signature (Approval, Certification, or Timestamp). Default is ApprovalSignature if not specified. Certification signatures must be the first signature in the document.
func (*SignBuilder) Unit ¶
func (b *SignBuilder) Unit(u float64) *SignBuilder
Unit sets the coordinate system scale for subsequent calls to Appearance. By default, the unit is 1.0 (one PDF point = 1/72 inch).
Example:
// Place signature at (20mm, 50mm) builder.Unit(pdfsign.Millimeter).Appearance(app, 20, 50)
type Signature ¶
Signature is an alias for extract.Signature for backward compatibility. Deprecated: Use extract.Signature directly.
type SignatureInfo ¶
type SignatureInfo struct {
SignerName string
SigningTime time.Time
Reason string
Location string
Contact string
Certificate *x509.Certificate
Timestamp *TimestampInfo
ByteRange [4]int64
Format Format
}
SignatureInfo contains information about a signature.
type SignatureType ¶
type SignatureType int
SignatureType represents the type of signature.
const ( // ApprovalSignature indicates that the signer approves the content of the document. // This is the most common type of signature. ApprovalSignature SignatureType = iota // CertificationSignature indicates that the signer is the author of the document // and specifies what changes are permitted after signing. CertificationSignature // DocumentTimestamp is a document-level timestamp that proves the document existed // at a specific time without certifying authorship. DocumentTimestamp )
type SignatureVerifyResult ¶
type SignatureVerifyResult struct {
SignatureInfo
Valid bool
TrustedChain bool
Revoked bool
TimestampValid bool
Errors []error
Warnings []error
}
SignatureVerifyResult contains verification result for a single signature.
type StandardFontType ¶
type StandardFontType = fonts.StandardType
StandardFontType is an alias for fonts.StandardType for backward compatibility. Deprecated: Use fonts.StandardType directly.
type TextAlign ¶
TextAlign is an alias for render.TextAlign for backward compatibility. Deprecated: Use render.TextAlign directly.
type TextBuilder ¶
type TextBuilder struct {
// contains filtered or unexported fields
}
TextBuilder builds a text element within an appearance.
func (*TextBuilder) Align ¶
func (b *TextBuilder) Align(align TextAlign) *TextBuilder
Align sets the text alignment.
func (*TextBuilder) AutoScale ¶
func (b *TextBuilder) AutoScale() *TextBuilder
AutoScale enables automatic font resizing to fit the text within the appearance bounds.
func (*TextBuilder) Center ¶
func (b *TextBuilder) Center() *TextBuilder
Center centers the text in the appearance.
func (*TextBuilder) Font ¶
func (b *TextBuilder) Font(font *Font, size float64) *TextBuilder
Font sets the font for the text.
func (*TextBuilder) Position ¶
func (b *TextBuilder) Position(x, y float64) *TextBuilder
Position sets the position of the text.
func (*TextBuilder) SetColor ¶
func (tb *TextBuilder) SetColor(r, g, b uint8) *TextBuilder
SetColor sets the text color.
type TimestampInfo ¶
type TimestampInfo struct {
Time time.Time
Authority string
Certificate *x509.Certificate
}
TimestampInfo contains information about a timestamp.
type VerifyBuilder ¶
type VerifyBuilder struct {
// contains filtered or unexported fields
}
VerifyBuilder provides a fluent API for configuring and executing PDF signature verification. Verification is performed lazily when result accessor methods (Valid, Signatures, Err) are called.
Concurrency: configure a VerifyBuilder from a single goroutine, the same way you would build up any other value. Once configuration is done, the result accessor methods (Valid, Signatures, Document, Err, Count) are safe to call concurrently from multiple goroutines - verification runs exactly once no matter how many goroutines call them, and every caller observes the same completed result. Calling a configuration method (TrustedRoots, TrustSelfSigned, Strict, ...) concurrently with another call, or after an accessor has already triggered verification, is not safe and has no effect on a verification that has already run.
func (*VerifyBuilder) AllowedAlgorithms ¶
func (b *VerifyBuilder) AllowedAlgorithms(algos ...x509.PublicKeyAlgorithm) *VerifyBuilder
AllowedAlgorithms restricts the permitted public key algorithms (e.g. x509.RSA, x509.ECDSA).
func (*VerifyBuilder) AllowedEKUs ¶
func (b *VerifyBuilder) AllowedEKUs(ekus ...x509.ExtKeyUsage) *VerifyBuilder
AllowedEKUs sets the allowed Extended Key Usages.
func (*VerifyBuilder) AtTime ¶
func (b *VerifyBuilder) AtTime(t time.Time) *VerifyBuilder
AtTime sets the point in time at which the certificate chain's validity should be checked. By default, certificates are checked against the current system time.
func (*VerifyBuilder) Context ¶
func (b *VerifyBuilder) Context(ctx context.Context) *VerifyBuilder
Context bounds external OCSP/CRL requests made when ExternalChecks is enabled: cancelling ctx aborts an in-flight request immediately, in addition to whatever HTTPTimeout applies. Use this to tie verification to a caller's own deadline or cancellation signal (e.g. an incoming HTTP request's context, or os/signal.NotifyContext). If not set, requests run under context.Background() and are bounded only by HTTPTimeout.
func (*VerifyBuilder) Count ¶
func (b *VerifyBuilder) Count() int
Count returns the number of signatures found. Triggers verification if not already executed.
func (*VerifyBuilder) Document ¶
func (b *VerifyBuilder) Document() DocumentInfo
Document returns document metadata. Triggers verification if not already executed.
func (*VerifyBuilder) Err ¶
func (b *VerifyBuilder) Err() error
Err returns any error that occurred during verification. Triggers verification if not already executed.
func (*VerifyBuilder) ExternalChecks ¶
func (b *VerifyBuilder) ExternalChecks(enable bool) *VerifyBuilder
ExternalChecks enables or disables network access to fetch revocation data from the web. If enabled, the library will attempt to contact OCSP responders and download CRLs from distribution points specified in the certificates.
func (*VerifyBuilder) HTTPTimeout ¶
func (b *VerifyBuilder) HTTPTimeout(d time.Duration) *VerifyBuilder
HTTPTimeout sets the timeout for external HTTP requests (OCSP/CRL checks) made when ExternalChecks is enabled. If not set, a default of 10 seconds is used.
func (*VerifyBuilder) MinECDSAKeySize ¶
func (b *VerifyBuilder) MinECDSAKeySize(bits int) *VerifyBuilder
MinECDSAKeySize constrains the minimum curve size for ECDSA keys.
func (*VerifyBuilder) MinRSAKeySize ¶
func (b *VerifyBuilder) MinRSAKeySize(bits int) *VerifyBuilder
MinRSAKeySize constrains the minimum bit size for RSA keys.
func (*VerifyBuilder) RequireDigitalSignature ¶
func (b *VerifyBuilder) RequireDigitalSignature(require bool) *VerifyBuilder
RequireDigitalSignature requires the Digital Signature key usage bit.
func (*VerifyBuilder) RequireNonRepudiation ¶
func (b *VerifyBuilder) RequireNonRepudiation(require bool) *VerifyBuilder
RequireNonRepudiation requires the Non-Repudiation key usage bit.
func (*VerifyBuilder) Signatures ¶
func (b *VerifyBuilder) Signatures() []SignatureVerifyResult
Signatures returns the verification results for each signature. Triggers verification if not already executed.
func (*VerifyBuilder) SkipCRL ¶
func (b *VerifyBuilder) SkipCRL(skip bool) *VerifyBuilder
SkipCRL disables CRL (embedded or external) as a revocation source.
func (*VerifyBuilder) SkipOCSP ¶
func (b *VerifyBuilder) SkipOCSP(skip bool) *VerifyBuilder
SkipOCSP disables OCSP (embedded or external) as a revocation source.
func (*VerifyBuilder) SkipRevocationCheck ¶
func (b *VerifyBuilder) SkipRevocationCheck(skip bool) *VerifyBuilder
SkipRevocationCheck disables all revocation checks (OCSP and CRL, both embedded and external).
func (*VerifyBuilder) Strict ¶
func (b *VerifyBuilder) Strict() *VerifyBuilder
Strict is a convenience method that enables all security and revocation checks. Revocation checking against embedded data is already on by default; Strict additionally sets:
- `ExternalChecks(true)`
- `ValidateFullChain(true)`
- `RequireDigitalSignature(true)`
- `RequireNonRepudiation(true)`
- `TrustSelfSigned(false)`
func (*VerifyBuilder) TrustSelfSigned ¶
func (b *VerifyBuilder) TrustSelfSigned(trust bool) *VerifyBuilder
TrustSelfSigned allows verification to succeed even if the certificate is self-signed or not signed by a CA in the TrustedRoots pool.
WARNING: Enabling this bypasses certificate chain trust validation and should only be used for testing or internal environments where certificates are manually trusted.
func (*VerifyBuilder) TrustSignatureTime ¶
func (b *VerifyBuilder) TrustSignatureTime(trust bool) *VerifyBuilder
TrustSignatureTime determines whether to use the time specified in the PDF signature dictionary as the validation time, rather than the current system time. Note: This time is provided by the signer and should only be trusted if verified by a TSA.
func (*VerifyBuilder) TrustedRoots ¶
func (b *VerifyBuilder) TrustedRoots(pool *x509.CertPool) *VerifyBuilder
TrustedRoots sets the pool of root certificates that are trusted to verify the signer's certificate chain. If not set, verification will fail unless TrustSelfSigned(true) is enabled.
func (*VerifyBuilder) Valid ¶
func (b *VerifyBuilder) Valid() bool
Valid returns true if all signatures are valid. Triggers verification if not already executed.
func (*VerifyBuilder) ValidateFullChain ¶
func (b *VerifyBuilder) ValidateFullChain(validate bool) *VerifyBuilder
ValidateFullChain sets whether to enforce cryptographic policy constraints (key size, algorithms) on the entire chain.
By default (false), these constraints are only enforced on the leaf (signer) certificate. Revocation and standard trust verification are always performed on the full chain.
func (*VerifyBuilder) ValidateTimestampCertificates ¶
func (b *VerifyBuilder) ValidateTimestampCertificates(validate bool) *VerifyBuilder
ValidateTimestampCertificates when true, validates the timestamp token's signing certificate. Only a successfully validated timestamp can supply historical validation time. Validation is enabled by default; disabling it retains timestamp metadata.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package fonts provides font resources and metrics for PDF documents.
|
Package fonts provides font resources and metrics for PDF documents. |
|
Package images provides image resources for PDF documents.
|
Package images provides image resources for PDF documents. |
|
internal
|
|
|
acroform
Package acroform walks the interactive form field tree of a document (ISO 32000-1 12.7.3, "Field dictionaries").
|
Package acroform walks the interactive form field tree of a document (ISO 32000-1 12.7.3, "Field dictionaries"). |
|
ocspx
Package ocspx adds ML-DSA response support around golang.org/x/crypto/ocsp.
|
Package ocspx adds ML-DSA response support around golang.org/x/crypto/ocsp. |
|
testdss
Package testdss provides test-only integration with the EU Digital Signature Services (DSS) validation API.
|
Package testdss provides test-only integration with the EU Digital Signature Services (DSS) validation API. |
|
testpdf
Package testpdf builds small PDF files for tests.
|
Package testpdf builds small PDF files for tests. |
|
signers
|
|
|
aws
module
|
|
|
csc
module
|
|
|
pkcs11
module
|
|