go-asice

module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Sep 24, 2026 License: MIT

README

asice

ASiC-E container tool for the XML XAdES form (TS 102 918 / BDOC 2.1.2 shape): create and self-verify containers in the BES and TS profiles.

Security Notice

This codebase was scanned on 2026-09-01 with deepsec (an AI-assisted security scanner) against a project threat model covering hostile .asice containers, operator-supplied key/PEM inputs, and an attacker-influenced TSA endpoint. Every exported finding was triaged and resolved: the confirmed defects were fixed with regression tests, and the one remaining finding was verified as a false positive and pinned by a regression test so the behavior is preserved.

That scan is a point-in-time audit, not a security certification. This library creates and verifies cryptographic containers: before relying on it in production, review the code, validate its behavior against your threat model, and test with your own certificates, TSA endpoints, and containers.

Verification

  • Self-verification — the repo's own checks: container structure, file digests, the signature, the certificate chain at signing time, and — for the TS profile — the embedded TST and OCSP values. The verify command runs these.
  • Interop — the design target is the reference implementation: containers produced here must verify under it. Interoperability is enforced by an external acceptance harness (maintained outside this repo) that verifies CLI-produced containers against the reference implementation. In-repo, behavior is pinned by the hermetic test PKI and the golden-file fixtures in test/samples/.

Layout

Path Contents Purpose
xades/ XAdES property builders (SignedProperties, UnsignedProperties) builds the XAdES SP/USP in the signature document
asic/ container writer, BES/TS signing, Create orchestration, self-verify the core ASiC-E create and verify path
tsa/ RFC 3161 codecs + HTTP client + validator (+ exported test TSA server) parse and verify TSTs (issue them in tests)
ocsp/ RFC 6960 request/response codecs, AIA resolution, HTTP fetch the ocsp fetch command (fresh stored OCSP)
testutil/ exported hermetic test PKI incl. OCSP/TST generation (test support) deterministic, test PKI
test/samples/ hermetic fixtures, generated — see that README self-consistency pins for the golden tests
cmd/asice the CLI (below) the user-facing entry point
docs/adr/ design decisions records why design decisions were made
asic/spec ASiC spec pointers (TS 102 918, TS 103 174) normative reference for the ASiC profile
xades/spec XAdES spec pointers (TS 101 903, TS 103 171) normative reference for XAdES
bdoc/spec BDOC spec pointer (2.1.2:2014) normative reference for the container format

The XML-DSig engine is the public module github.com/isri-pqc/go-xmlsig (dependency in go.mod); this repo has no xmlsig/ submodule.

Build & test

Requires Go 1.25+.

go build ./...
go vet ./...
go test ./... -count=1

CLI

asice create -o out.asice --cert signer.pem --key signer.key [--chain chain.pem]
    [--profile bes|ts] [--ocsp-file ocsp.der] [--tst <tsa-url>]
    [--tst-signers tsa.pem] [--tsdelay <duration>]
    [--signing-time <RFC3339>] doc1 [doc2 ...]

asice verify in.asice --roots roots.pem [--intermediates int.pem]
    [--tst-signers tsa.pem] [--ocsp-responders ocsp-responder.pem]
    [--profile bes|ts] [--tsdelay <duration>]

asice ocsp fetch --cert signer.pem --out ocsp.der
    [--issuer issuer.pem | --chain chain.pem] [--url <responder-url>]
    [--timeout 10s]

Exit codes: 0 ok, 1 create/verify failure, 2 usage error. asice --help prints this usage. The CLI is built on cobra + fang and also provides --version, a completion command (shell completions), and a hidden man command (manpage generation).

create
  • -o — output container path (required).
  • --cert — signer file: PEM with the signer CERTIFICATE block. It may also hold the private key block (PRIVATE KEY / RSA PRIVATE KEY / EC PRIVATE KEY) (required).
  • --key — signer private key file: PEM (or DER) private key block. If omitted, the key must be a block inside --cert; if given, --cert is read as the certificate file only.
  • --profile — bes (default) or ts.
  • --chain — ts profile: PEM with exactly two certificates, the OCSP responder first and the CA second (embedded in xades:CertificateValues); ignored for bes.
  • --ocsp-file — ts profile: DER basic OCSP response for the signer certificate.
  • --tst — ts profile: RFC 3161 TSA endpoint URL (HTTP).
  • --tst-signers — ts profile: PEM with the TSA signing certificate(s) (the TSA client identifies and validates the token signer against these).
  • --tsdelay — ts profile: explicit TSDelayTime bound (0 <= OCSP producedAt − TST genTime <= --tsdelay). When omitted the bound is taken from the TST's TSA policy; with neither source create fails before writing the container.
  • --signing-time — RFC 3339 signing time; default: now (UTC). For the ts profile use one consistent time: signing time = OCSP producedAt = TST genTime.
  • doc1 [doc2 ...] — one or more document paths (flat names; media types guessed from the extension, else application/octet-stream).
verify
  • container path — the single positional argument; flags may be placed before or after it.
  • --roots — PEM trust anchor(s) (required).
  • --intermediates — PEM intermediate CA(s).
  • --tst-signers — required for ts: PEM TSA signing certificate(s).
  • --ocsp-responders — ts, optional: PEM configured OCSP responder(s); when absent the embedded responder is matched against the signer's issuer instead.
  • --profile — bes (default) or ts.
  • --tsdelay — ts profile: explicit TSDelayTime bound (0 <= OCSP producedAt − TST genTime <= --tsdelay). When omitted the bound is taken from the TST's TSA policy; with neither source verification fails.

Prints a human-readable report (data files, per-signature status with signer and signing time, and actionable errors).

ocsp fetch

Fetches a fresh stored OCSP response for a signer certificate — the --ocsp-file input for the ts profile. Builds the RFC 6960 request from the signer certificate and writes the full OCSPResponse DER (byte-exact) to the output path.

  • --cert — the signer certificate, a single PEM (required).
  • --out — output path for the OCSPResponse DER (required).
  • --issuer — the signer's issuer certificate, a single PEM; wins over --chain.
  • --chain — PEM chain; the certificate whose subject matches the signer's issuer name is the issuer.
  • --url — OCSP responder URL; default: the signer's AIA id-ad-ocsp entry.
  • --timeout — HTTP client timeout (default 10s).

The responder must answer successful with a good status for the signer. A 400 on the canonical request first triggers the wrapped-shape retry below; any other status, or a non-200 after the retry, is a failure (exit 1).

Request wire compatibility. The request is sent first in the canonical RFC 6960 section 2.2 shape. Some responder deployments (the reference implementation's) accept only the canonical body wrapped in one extra SEQUENCE and reject the bare canonical body with HTTP 400 (invalid OCSPRequest); Fetch therefore retries once with the wrapped shape on a 400. Both shapes carry the identical CertID, so the response handling is unchanged. See TestFetchWrappedShapeFallback in ocsp/ocsp_test.go.

Examples

BES (minimal):

asice create -o out.asice --cert signer.pem --key signer.key --profile bes contract.pdf
asice verify out.asice --roots root.pem --intermediates issuer.pem --profile bes

TS (against a live TSA and OCSP responder; one consistent time — here the OCSP response's producedAt — for --signing-time):

asice ocsp fetch --cert signer.pem --chain ocsp-responder-then-ca.pem \
    --out ocsp.der
asice create -o out.asice --cert signer.pem --key signer.key --profile ts \
    --chain ocsp-responder-then-ca.pem --ocsp-file ocsp.der \
    --tst https://tsa.example/tsp --tst-signers tsa.pem \
    --signing-time 2026-08-28T10:00:00Z contract.pdf
asice verify out.asice --roots root.pem --intermediates issuer.pem \
    --profile ts --tst-signers tsa.pem --ocsp-responders ocsp-responder.pem

Crypto agility

Every cryptographic operation sits behind a small per-domain module interface (ADR 0004); the domain code performs no direct crypto primitives and holds no keys of its own.

  • asic/crypto — the certificate chain walk (issuer-match at signing time, ContentCommitment key usage on the leaf), embedded-OCSP response verification, TST verification, plus the XML-DSig signer/verifier modules of the xmlsig engine.
  • tsa/crypto — OID-keyed message digests, CMS SignerInfo signature verification, and TSA chain building with key/extended-key usage gating.
  • ocsp/crypto — the RFC 6960 CertID message digests (SHA-1; the algorithm the standard fixes for the certificate identifier).

The standard-library implementations (NewStd* constructors) cover RSA PKCS#1 v1.5 and ECDSA P-256/384/521. The XML-DSig signature value is encoded per W3C XML Signature 1.1 section 6.4.3 — ECDSA as raw r‖s (fixed-width big-endian halves, RFC 4050 section 3.3 / IEEE 1363 E3.1), RSA as PKCS#1 v1.5 DER. The public API takes the modules as parameters with no global defaults: a zero-value module is a hard error at the operation entry point. An alternative backend (HSM, soft token, or a post-quantum scheme — the xmlsig engine registers the ML-DSA-44/65/87 algorithm URIs, with implementations supplied as custom modules) is plugged in by implementing the same interfaces and injecting them; the container and signature layout is algorithm-agnostic (the algorithm ID lives in ds:SignatureMethod).

Byte-level rules

The container, canonicalization, and TS-profile rules are locked down by the ADRs in docs/adr/ (0001: canonicalization and container layout — inclusive C14N 1.1, ZIP magic/manifest/entry layout, base64 wrapping; 0002: multi-file / multi-signature BES contract; 0003: TS-profile TST and OCSP embedding, single-time-T pattern; 0004: crypto agility — crypto behind per-domain interfaces; 0005: signature XML layout is house style) and pinned by the golden tests against test/samples/, which holds the hermetic fixtures. Interoperability with the reference implementation is the design target and is enforced by the external acceptance harness maintained outside this repo.

Dependencies

Module License Role
github.com/isri-pqc/go-xmlsig Apache-2.0 the XML-DSig engine: C14N 1.1 canonicalization, digest/signature primitives, signature builder
github.com/beevik/etree BSD-2-Clause XML document tree handling
github.com/spf13/cobra Apache-2.0 CLI command framework
github.com/charmbracelet/fang MIT CLI UX (completions, manpage generation)

This project is licensed under the MIT License (see LICENSE).

Directories

Path Synopsis
Container-level API of the asic package: build a complete ASiC-E container (magic entry, ODF manifest, signature files, data files) from in-memory content.
Container-level API of the asic package: build a complete ASiC-E container (magic entry, ODF manifest, signature files, data files) from in-memory content.
crypto
Package crypto — the asic-domain crypto backend boundary (ADR 0004).
Package crypto — the asic-domain crypto backend boundary (ADR 0004).
cmd
asice command
cli.go: the cobra command tree, wired through fang, and the exit code mapping (0 ok, 1 create/verify failure, 2 usage error).
cli.go: the cobra command tree, wired through fang, and the exit code mapping (0 ok, 1 create/verify failure, 2 usage error).
Package ocsp implements the OCSP client flow behind asice ocsp fetch: the RFC 6960 section 4.1.1 CertID of a signer certificate, the section 2.2 request wire format, the HTTP exchange, and the full-response decode.
Package ocsp implements the OCSP client flow behind asice ocsp fetch: the RFC 6960 section 4.1.1 CertID of a signer certificate, the section 2.2 request wire format, the HTTP exchange, and the full-response decode.
crypto
Package crypto holds the per-domain crypto module interfaces and the standard-library implementations of the ocsp domain (ADR 0004): the domain code performs no direct crypto primitives — the RFC 6960 CertID digests go through the injected DigestModule.
Package crypto holds the per-domain crypto module interfaces and the standard-library implementations of the ocsp domain (ADR 0004): the domain code performs no direct crypto primitives — the RFC 6960 CertID digests go through the injected DigestModule.
test
samples/gen command
Command gen regenerates the hermetic test fixtures under test/samples from this repo's own testutil PKI + asic packages: the ASiC-E containers, the extracted EID signature XML, and the canonicalized SignedInfo golden.
Command gen regenerates the hermetic test fixtures under test/samples from this repo's own testutil PKI + asic packages: the ASiC-E containers, the extracted EID signature XML, and the canonicalized SignedInfo golden.
Package testutil is a test-SUPPORT package: a hermetic (wall-clock-free) test PKI plus the OCSP and time-stamp token generation that the repo's tests and the companion interop acceptance harness (module the companion asice-compat harness) use to build ASiC-E containers and the TST/OCSP artifacts embedded in them.
Package testutil is a test-SUPPORT package: a hermetic (wall-clock-free) test PKI plus the OCSP and time-stamp token generation that the repo's tests and the companion interop acceptance harness (module the companion asice-compat harness) use to build ASiC-E containers and the TST/OCSP artifacts embedded in them.
tsa
In-process RFC 3161 test TSA server.
In-process RFC 3161 test TSA server.
crypto
Package crypto — the tsa-domain crypto backend boundary (ADR 0004): the digest, CMS signature, and certificate chain operations the tsa package's code paths actually invoke, behind per-domain interfaces.
Package crypto — the tsa-domain crypto backend boundary (ADR 0004): the digest, CMS signature, and certificate chain operations the tsa package's code paths actually invoke, behind per-domain interfaces.
Package xades builds the XAdES property XML of ASiC-E signature documents (PLAN.md §1.2) in the XAdES TS 101 893 v1.3.2 namespace as etree elements.
Package xades builds the XAdES property XML of ASiC-E signature documents (PLAN.md §1.2) in the XAdES TS 101 893 v1.3.2 namespace as etree elements.

Jump to

Keyboard shortcuts

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