DEV Community

SybilGambleyyu
SybilGambleyyu

Posted on • Originally published at sybilgambleyyu.github.io

An OPC signature has only three transform algorithms

An OPC signature has only three transform algorithms

Generic XMLDSIG is extensible: a Reference can describe arbitrary transform
algorithms. OPC deliberately narrows that freedom for package signatures. A
recognized OPC Signature can use its Relationship Transform or either of its two
XML Canonicalization variants. No other XMLDSIG
Transform/@Algorithm belongs in the Signature.

DocFence 0.56.0
now rejects every XMLDSIG ds:Transform in a recognized package
signature whose Algorithm is missing or outside that set.

One rule for the whole Signature

ECMA-376 Open Packaging Conventions
§10.5.8.1 restricts the transform algorithm set to three values:

XML Canonicalization
XML Canonicalization with Comments
OPC Relationship Transform
~~~

The check is global: it applies before the bounded static package-coverage audit
and includes transform lists on References that audit does not otherwise follow.

That distinction matters because the broader [XML Signature Core
specification](https://www.w3.org/TR/xmldsig-core/) describes transforms as
ordered processing steps selected by the signer; OPC is the package-specific
layer that removes the open-ended choice.

## Coverage cannot hide an unsupported transform

The regression starts with a fully declared synthetic package signature and adds
one same-document <code>SignedInfo</code> Reference carrying an unsupported
transform URI. Version 0.55 accepted that package and still reported declared
package coverage. Version 0.56 rejects it structurally. An allowed
canonicalization transform on the same extra Reference remains accepted.

The same rule now rejects an unsupported transform in the package-object binding
or a manifest package-part declaration. Those locations no longer degrade only
to an unsupported coverage count: their containing recognized Signature is
malformed.

## No transform engine

DocFence compares stored element and attribute values only. It does not resolve
or execute a transform, interpret transform parameters, canonicalize XML,
recompute a digest, verify XMLDSIG, validate certificates, establish trust, or
predict an Office client. Its public output continues to withhold signatures,
URIs, selectors, algorithms, digest material, and document contents.

~~~yaml
version: 1
rules:
  require_complete_package_signature_coverage: true
  no_package_signature_coverage_changes: true
~~~

## Evidence and use

The 69-test suite covers unsupported and missing transform algorithms on
additional <code>SignedInfo</code> References, plus unsupported transforms in
the bounded coverage paths and a positive non-coverage canonicalization case.
Across the 29 DOCX fixtures in the public [OOXML Signature Security
artifacts](https://github.com/RUB-NDS/OOXML_Signature_Security), 22 XML
signature parts are present and 21 parse successfully. They contain 38 OPC
Relationship Transforms and 63 XML Canonicalization Transforms, with no other
transform algorithms. Every aggregate profile is byte-identical to 0.55.

Main and tagged CI passed on Python 3.11 and 3.13. Fresh wheel and
source-distribution installations reject both missing and unsupported transform
algorithms while accepting the permitted canonicalization case. Two independent
tagged builds were byte-identical, and the public release downloads were
byte-compared with that build.

~~~bash
python -m pip install https://github.com/SybilGambleyyu/docfence/releases/download/v0.56.0/docfence-0.56.0-py3-none-any.whl

docfence check approved.docx candidate.docx --policy docfence.yml --format sarif --output docfence.sarif
~~~

Read the canonical [DocFence 0.56 release note](https://sybilgambleyyu.github.io/posts/docfence-560.html)
for the exact policy, threat-model, and validation boundaries.
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
merbayerp profile image
Mustafa ERBAY

A good example of why “being permissive” isn’t always the right engineering choice. Restricting accepted transforms to the OPC-defined set makes the validator deterministic and aligned with the specification instead of relying on implementation-specific behavior.

I also like that you clearly separate structural validation from cryptographic verification. Keeping those trust boundaries explicit makes the tool’s guarantees much easier to understand and audit.