Relyra.Security.XML.PureBeam (relyra v1.2.0)

Copy Markdown View Source

Pure-BEAM baseline adapter for XML seam enforcement.

Phase 28 (D-04): a single hardened parser path. parse_safely/2 runs the pre-parse byte guards (DOCTYPE / ENTITY / size) on the raw binary BEFORE any parse (XXE-before-verify invariant, D-09), then routes the well-formed arm to Relyra.Security.XML.SaxyTree and re-derives EVERY downstream protocol field from the resulting parse tree in one pass — the regex extractors are retired so no parser/canonicalization differential exists (D-04, threat T-28-11).

The flat parsed_doc key contract is preserved additively (D-08): every legacy key downstream readers (Relyra.Security.Signature, Relyra.Protocol.ValidationPipeline) consume is reproduced, and the parse tree is attached as a NEW :parse_tree key. The selected handle binds the EXACT tree node canonicalize/2 serializes (D-10, anti-XSW), and canonicalize/2 delegates to the Relyra.Security.XML.C14N exclusive-C14N engine on that node while failing closed (:canonicalization_failed) for any non-bindable handle (Pitfall 9, threat T-28-12).

Summary

Functions

Pre-parse a SAML metadata document and produce a metadata-root-shaped parsed_doc for the signed-metadata trust path (SIGV-04, D-13).

Functions

parse_metadata_root_safely(xml, opts \\ [])

@spec parse_metadata_root_safely(
  binary(),
  keyword()
) :: {:ok, map()} | {:error, Relyra.Error.t()}

Pre-parse a SAML metadata document and produce a metadata-root-shaped parsed_doc for the signed-metadata trust path (SIGV-04, D-13).

This is the metadata sibling of parse_safely/2: it runs the SAME pre-parse byte guards (DOCTYPE / ENTITY / size) on the raw binary BEFORE any parse (XXE-before-verify, D-09), routes the well-formed arm to the SAME SaxyTree parser (D-04, one trust path — no regex, no second parser), and emits the SAME canonical signed-candidate shape signed_candidates/1 emits (carrying the D-02 crypto inputs :signed_info_node / :digest_value_b64 / :signature_value_b64 plus the bound :node), but rooted at the metadata envelope (<EntityDescriptor> / <EntitiesDescriptor>) instead of an <Assertion>.

Returns {:ok, parsed_doc} whose single :signed_candidates entry binds the EXACT metadata-root tree node canonicalize/2 serializes (anti-XSW), plus :signature_method / :digest_method (from the SignedInfo), :key_info_trust and :duplicate_ids (tree-derived) so the shared do_verify/4 gates inherit to the metadata path. Returns {:error, %Error{type: :missing_signature}} when no signed <EntityDescriptor> / <EntitiesDescriptor> root is present (fail closed), or the same byte-guard / :malformed_xml errors parse_safely/2 returns.