xml-sec 0.1.13

Pure Rust XML Security: XMLDSig, XMLEnc, C14N. Drop-in replacement for libxmlsec1.
Documentation
//! XPath Filter 2.0 canonicalization vectors derived from Merlin's suite.

use xml_sec::xmldsig::{NodeSet, TransformData, execute_transforms, parse_transforms};

const MERLIN_SIGN_SPEC_SUBSET: &str =
    include_str!("fixtures/xmldsig/merlin-xpath-filter2/sign-spec-subset.xml");

#[test]
fn merlin_filter2_sign_spec_produces_exact_canonical_octets() {
    // This is Merlin's first sign-spec reference input and operation chain.
    // The expected bytes are the donor's sign-spec-c14n-0.txt, not output
    // generated by this implementation.
    let document = roxmltree::Document::parse(MERLIN_SIGN_SPEC_SUBSET)
        .expect("trimmed Merlin Filter 2.0 fixture must parse");
    let transforms_node = document
        .descendants()
        .find(|node| node.has_tag_name(("http://www.w3.org/2000/09/xmldsig#", "Transforms")))
        .expect("fixture must contain Transforms");
    let transforms = parse_transforms(transforms_node).expect("Merlin transforms must parse");
    let output = execute_transforms(
        document.root_element(),
        TransformData::NodeSet(
            NodeSet::entire_document_without_comments(&document)
                .expect("donor fixture must fit the node-set materialization budget"),
        ),
        &transforms,
    )
    .expect("Merlin Filter 2.0 operations must execute");
    let expected = concat!(
        "<ToBeSigned>\n",
        "    \n",
        "    <Data></Data>\n",
        "    <ReallyToBeSigned>\n",
        "        \n",
        "        <Data></Data>\n",
        "      </ReallyToBeSigned>\n",
        "  </ToBeSigned><ToBeSigned>\n",
        "    <Data></Data>\n",
        "    \n",
        "  </ToBeSigned>",
    );

    assert_eq!(output, expected.as_bytes());
}