dsig

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2026 License: BSD-2-Clause Imports: 22 Imported by: 0

README

Digital Signature Package

This package provides a comprehensive framework for handling XML Digital Signatures, especially for Trust Status Lists (TSLs). It supports both file-based keys and PKCS#11 hardware security modules.

Interfaces

The package provides a simple, consistent interface for signing XML documents:

// XMLSigner represents an interface for signing XML documents with XML-DSIG
type XMLSigner interface {
	// Sign takes XML data and returns signed XML data
	Sign(xmlData []byte) ([]byte, error)
}

Available Signers

FileSigner

FileSigner implements XML signing using certificate and private key files:

// Create a new file signer
signer := dsig.NewFileSigner("path/to/cert.pem", "path/to/key.pem")

// Sign XML data
signedXML, err := signer.Sign(xmlData)
PKCS11Signer

PKCS11Signer implements XML signing using a PKCS#11 hardware token:

// Create a PKCS11 signer from URI
signer, err := dsig.NewPKCS11SignerFromURI(
    "pkcs11:module=/usr/lib/softhsm/libsofthsm2.so;pin=1234;slot-id=0", 
    "key-label", 
    "cert-label"
)
if err != nil {
    // Handle error
}
defer signer.Close()

// Set key ID (optional)
signer.SetKeyID("01")

// Sign XML data
signedXML, err := signer.Sign(xmlData)

Testing Utilities

The package includes testing utilities in the dsig/test subpackage to assist with testing PKCS#11 functionality using SoftHSM:

// In your test function
func TestPKCS11Signing(t *testing.T) {
    // Skip if SoftHSM is unavailable
    helper := test.SkipIfSoftHSMUnavailable(t)
    
    // Set up SoftHSM token
    err := helper.Setup()
    if err != nil {
        t.Skip("Could not set up SoftHSM token")
    }
    defer helper.Cleanup()
    
    // Generate and import test key pair
    err = helper.GenerateAndImportTestCert("test-key", "test-cert", "01")
    if err != nil {
        t.Skip("Could not import test certificate")
    }
    
    // Get PKCS11 URI for testing
    pkcs11URI := helper.GetPKCS11URI()
    
    // Create signer and run tests...
}

Documentation

Overview

Package dsig provides XML Digital Signature (XML-DSIG) functionality for signing Trust Status Lists (TSLs) and other XML documents. It supports multiple signing mechanisms including file-based keys and PKCS#11 hardware security modules.

Package dsig provides XML Digital Signature (XML-DSIG) functionality for signing and verifying Trust Status Lists (TSLs) and other XML documents.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExtractPKCS11Config

func ExtractPKCS11Config(pkcs11URI string) *crypto11.Config

ExtractPKCS11Config extracts a PKCS#11 configuration from a URI. This function parses a PKCS#11 URI according to RFC 7512 and extracts the configuration parameters for initializing a PKCS#11 module connection.

Parameters:

  • pkcs11URI: A PKCS#11 URI string in the format "pkcs11:module=/path/to/module;pin=1234;..."

Returns:

  • A crypto11.Config populated with parameters from the URI, or nil if parsing fails

func GetSigningMethodName

func GetSigningMethodName() string

GetSigningMethodName returns a string description of the default signing method. This function indicates which signature algorithm is used by the package for signing XML documents.

Returns:

  • A string identifying the algorithm, currently "rsa-sha256"

func SelfSignCertificate added in v0.7.0

func SelfSignCertificate(config *crypto11.Config, opts SelfSignedCertOptions) (*x509.Certificate, []byte, error)

SelfSignCertificate issues a self-signed CA certificate for a key pair that already exists in a PKCS#11 token, using that token to produce the signature. The private key never leaves the token.

This exists because the obvious shell recipe is wrong in a way that is hard to notice. Generating a key in a token with pkcs11-tool and then minting a certificate with "openssl req -x509 -newkey ..." produces a certificate over a brand new, unrelated key pair; loading it into the token leaves the certificate and the signing key referring to different keys. Signatures then verify against nothing, and the failure only shows up in a relying party, never at signing time.

Returns the certificate and its PEM encoding.

func SignXML

func SignXML(xmlData []byte, signer xmldsig.Signer) ([]byte, error)

SignXML signs XML data using any implementation of the xmldsig.Signer interface. It applies XML Digital Signature standards to create a signed XML document.

The function: 1. Sets up a signing context with exclusive canonicalization 2. Parses the input XML 3. Signs the document with an enveloped signature 4. Returns the signed document

Parameters:

  • xmlData: Raw XML bytes to sign
  • signer: An implementation of xmldsig.Signer to perform the signing operation

Returns:

  • The signed XML document as bytes
  • An error if parsing or signing fails

func SignXMLWithKeyStore

func SignXMLWithKeyStore(xmlData []byte, keyStore xmldsig.X509KeyStore) ([]byte, error)

SignXMLWithKeyStore signs XML data using the provided X509KeyStore. This is a convenience function that creates a signing context and applies the same canonicalization and signing process as SignXML.

Parameters:

  • xmlData: Raw XML bytes to sign
  • keyStore: An implementation of xmldsig.X509KeyStore that provides access to the private key and certificate for signing

Returns:

  • The signed XML document as bytes
  • An error if parsing or signing fails

func SignXMLWithXAdES added in v0.2.0

func SignXMLWithXAdES(xmlData []byte, signer crypto.Signer, cert *x509.Certificate) ([]byte, error)

SignXMLWithXAdES signs XML data with an enveloped XAdES-B-B signature. This creates a full XAdES-B-B signature including:

  • ds:Signature with two ds:Reference elements (document + SignedProperties)
  • ds:Object containing xades:QualifyingProperties
  • xades:SignedProperties with SigningTime, SigningCertificate, and DataObjectFormat

Parameters:

  • xmlData: Raw XML bytes to sign
  • signer: crypto.Signer for signing (e.g., *rsa.PrivateKey or PKCS#11 opaque signer)
  • cert: X.509 certificate of the signer

func VerifyXMLSignature

func VerifyXMLSignature(xmlData []byte, trustedCerts []*x509.Certificate) (*etree.Element, error)

VerifyXMLSignature verifies an XML digital signature against a certificate pool. It parses the XML, finds the enveloped signature, and validates it against the certificates in the provided pool.

Parameters:

  • xmlData: The signed XML document as bytes
  • trustedCerts: The certificates to validate the signature against

Returns:

  • The verified XML element (with signature removed)
  • An error if verification fails

func VerifyXMLSignatureWithPool

func VerifyXMLSignatureWithPool(xmlData []byte, pool *x509.CertPool, certs []*x509.Certificate) (*etree.Element, error)

VerifyXMLSignatureWithPool verifies an XML digital signature using certificates from a CertPool. This is a convenience function for cases where you have a CertPool but need to extract certificates for verification.

Note: This function requires the actual certificate slice since CertPool doesn't expose its certificates directly.

Parameters:

  • xmlData: The signed XML document as bytes
  • pool: The certificate pool (for future compatibility)
  • certs: The certificates to validate against

Returns:

  • The verified XML element
  • An error if verification fails

Types

type CertPoolStore

type CertPoolStore struct {
	// contains filtered or unexported fields
}

CertPoolStore implements xmldsig.X509CertificateStore using a crypto/x509.CertPool. This allows using a standard Go certificate pool for signature verification.

func NewCertPoolStore

func NewCertPoolStore(pool *x509.CertPool, certs []*x509.Certificate) *CertPoolStore

NewCertPoolStore creates a new CertPoolStore from a certificate pool. The pool should contain the trusted root certificates for signature verification.

func (*CertPoolStore) Certificates

func (s *CertPoolStore) Certificates() ([]*x509.Certificate, error)

Certificates returns the list of certificates in the store. Required by xmldsig.X509CertificateStore interface.

type FileSigner

type FileSigner struct {
	// CertFile is the path to the X.509 certificate file in PEM format
	CertFile string

	// KeyFile is the path to the private key file in PEM format (PKCS#1 or PKCS#8)
	KeyFile string
	// contains filtered or unexported fields
}

FileSigner implements XMLSigner using certificate and private key files. It uses file-based certificates and keys for signing XML documents. The certificate and key files should be in PEM format. By default, it produces XAdES-B-B compliant signatures.

func NewFileSigner

func NewFileSigner(certFile, keyFile string) *FileSigner

NewFileSigner creates a new FileSigner from certificate and key file paths. XAdES-B-B compliance is enabled by default.

Parameters:

  • certFile: Path to the X.509 certificate file in PEM format
  • keyFile: Path to the private key file in PEM format (PKCS#1 or PKCS#8)

Returns:

  • A new FileSigner instance configured with the provided files

func (*FileSigner) SetXAdES added in v0.2.0

func (fs *FileSigner) SetXAdES(enabled bool)

SetXAdES enables or disables XAdES-B-B compliant signatures.

func (*FileSigner) Sign

func (fs *FileSigner) Sign(xmlData []byte) ([]byte, error)

Sign implements XMLSigner.Sign using certificate and key files. This method loads the certificate and private key from files, creates an XML digital signature, and returns the signed XML document.

The method supports both PKCS#1 and PKCS#8 formatted private keys.

Parameters:

  • xmlData: Raw XML bytes to sign

Returns:

  • The signed XML document as bytes
  • An error if reading files, parsing certificates/keys, or signing fails

func (*FileSigner) ToXMLDSigSigner

func (fs *FileSigner) ToXMLDSigSigner() (xmldsig.Signer, error)

ToXMLDSigSigner converts a FileSigner to an xmldsig.Signer implementation. This method loads the certificate and private key from files and creates an xmldsig.Signer that can be used with the goxmldsig library directly.

The method supports both PKCS#1 and PKCS#8 formatted private keys and configures the signer to use SHA-256 for signatures.

Returns:

  • An xmldsig.Signer implementation using the file-based certificate and key
  • An error if reading files, parsing certificates/keys fails

type PKCS11Signer

type PKCS11Signer struct {
	// Config contains the PKCS#11 module configuration (path, PIN, etc.)
	Config *crypto11.Config
	// contains filtered or unexported fields
}

PKCS11Signer implements XMLSigner using a PKCS#11 hardware token. This type provides XML digital signature functionality using keys stored in Hardware Security Modules (HSMs) or other PKCS#11-compatible devices. By default, it produces XAdES-B-B compliant signatures.

func NewPKCS11Signer

func NewPKCS11Signer(config *crypto11.Config, keyLabel, certLabel string) *PKCS11Signer

NewPKCS11Signer creates a new PKCS11Signer from a PKCS#11 configuration and key/cert labels. XAdES-B-B compliance is enabled by default.

Parameters:

  • config: PKCS#11 module configuration (path, PIN, token label, etc.)
  • keyLabel: Label used to identify the private key in the HSM
  • certLabel: Label used to identify the certificate in the HSM

Returns:

  • A new PKCS11Signer with default key ID "01"

func NewPKCS11SignerFromURI

func NewPKCS11SignerFromURI(pkcs11URI, keyLabel, certLabel string) (*PKCS11Signer, error)

NewPKCS11SignerFromURI creates a new PKCS11Signer from a PKCS#11 URI. This convenience constructor parses a PKCS#11 URI (RFC 7512) to extract the configuration parameters for the PKCS#11 module.

Parameters:

  • pkcs11URI: A PKCS#11 URI string in the format "pkcs11:module=/path/to/module;pin=1234;..."
  • keyLabel: Label used to identify the private key in the HSM
  • certLabel: Label used to identify the certificate in the HSM

Returns:

  • A new PKCS11Signer configured based on the URI parameters
  • An error if the URI cannot be parsed or is invalid

func (*PKCS11Signer) Close

func (ps *PKCS11Signer) Close() error

Close cleans up any resources associated with the signer. This method prepares the signer for garbage collection by resetting its internal state. Note that the crypto11 context doesn't currently have an explicit Close method, but this function is provided for future-proofing.

Returns:

  • Always returns nil error (reserved for future implementations)

func (*PKCS11Signer) SetKeyID

func (ps *PKCS11Signer) SetKeyID(id string)

SetKeyID sets the ID to use for key and certificate lookups. The key ID is typically a hex string (with or without '0x' prefix) that identifies both the private key and certificate in the HSM.

Parameter:

  • id: Hex string ID to identify the key and certificate in the HSM

func (*PKCS11Signer) SetXAdES added in v0.2.0

func (ps *PKCS11Signer) SetXAdES(enabled bool)

SetXAdES enables or disables XAdES-B-B compliant signatures.

func (*PKCS11Signer) Sign

func (ps *PKCS11Signer) Sign(xmlData []byte) ([]byte, error)

Sign implements XMLSigner.Sign using PKCS#11 hardware token with goxmldsig's Signer interface. This method connects to the HSM, retrieves the private key and certificate, and uses them to create an XML digital signature.

Parameters:

  • xmlData: Raw XML bytes to sign

Returns:

  • The signed XML document as bytes
  • An error if HSM connection, key/cert retrieval, or signing fails

type SelfSignedCertOptions added in v0.7.0

type SelfSignedCertOptions struct {
	// KeyLabel and KeyID identify the existing key pair in the token. The
	// certificate is issued for whatever public key that pair holds.
	KeyLabel string
	KeyID    string

	// Subject is the distinguished name for both subject and issuer.
	Subject pkix.Name

	// Validity is how long the certificate is valid from now.
	Validity time.Duration

	// CertLabel, when non-empty, is the label to store the certificate under
	// in the token. Any existing certificate with that label and the same ID
	// is removed first, so the token never ends up with a stale one alongside.
	CertLabel string
}

SelfSignedCertOptions configures SelfSignCertificate.

type TSLSignatureVerifier

type TSLSignatureVerifier struct {
	// contains filtered or unexported fields
}

TSLSignatureVerifier verifies XML signatures on ETSI Trust Status Lists. It implements the XMLVerifier interface.

func NewTSLSignatureVerifier

func NewTSLSignatureVerifier(trustedCerts []*x509.Certificate) *TSLSignatureVerifier

NewTSLSignatureVerifier creates a verifier for TSL signatures. The trustedCerts should contain the certificates that are authorized to sign Trust Status Lists (typically EU or national scheme operators).

func (*TSLSignatureVerifier) AddTrustedCertificate

func (v *TSLSignatureVerifier) AddTrustedCertificate(cert *x509.Certificate)

AddTrustedCertificate adds a certificate to the list of trusted signers.

func (*TSLSignatureVerifier) TrustedCertificates

func (v *TSLSignatureVerifier) TrustedCertificates() []*x509.Certificate

TrustedCertificates returns the list of trusted signer certificates.

func (*TSLSignatureVerifier) Verify

func (v *TSLSignatureVerifier) Verify(xmlData []byte) (*etree.Element, error)

Verify validates the XML signature on a TSL document. Returns the verified element (signature removed) or an error.

type X509KeyStore

type X509KeyStore interface {
	// GetKeyPair retrieves the private key and certificate for signing.
	//
	// Returns:
	//   - The RSA private key for signing
	//   - The X.509 certificate bytes to include in the signature
	//   - An error if the key pair cannot be retrieved
	GetKeyPair() (*rsa.PrivateKey, []byte, error)
}

X509KeyStore defines an interface for accessing X.509 certificates and private keys. It's a wrapper around the goxmldsig X509KeyStore interface, providing access to key pairs needed for XML digital signatures.

type XAdESConfigurable added in v0.2.0

type XAdESConfigurable interface {
	SetXAdES(enabled bool)
}

XAdESConfigurable allows configuring XAdES compliance on a signer.

type XMLSigner

type XMLSigner interface {
	// Sign takes XML data as bytes and returns the signed XML data.
	// The signature is added according to the XML-DSIG standard,
	// with XAdES-B-B qualifying properties by default.
	//
	// Parameters:
	//   - xmlData: The raw XML data to sign
	//
	// Returns:
	//   - The signed XML data
	//   - An error if signing fails
	Sign(xmlData []byte) ([]byte, error)
}

XMLSigner defines the interface for XML document signing operations. Implementations include FileSigner and PKCS11Signer for different key storage mechanisms.

type XMLVerifier

type XMLVerifier interface {
	// Verify validates the XML signature and returns the verified element.
	// Returns an error if verification fails.
	Verify(xmlData []byte) (*etree.Element, error)
}

XMLVerifier defines the interface for XML signature verification operations.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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