[xmlsec] Manifest References
Aleksey Sanin
aleksey at aleksey.com
Fri Jun 2 09:28:36 PDT 2017
Let me try to explain using the example from the spec
(https://www.w3.org/TR/xmldsig-core/#sec-o-Manifest):
[ ] ...
[m01] <Reference URI="#MyFirstManifest"
[m02] Type="http://www.w3.org/2000/09/xmldsig#Manifest">
[m03] <Transforms>
[m04] <Transform
Algorithm="http://www.w3.org/2006/12/xml-c14n11"/>
[m05] </Transforms>
[m06] <DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
[m07]
<DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmUK...=</DigestValue>
[m08] </Reference>
[ ] ...
[m09] <Object>
[m10] <Manifest Id="MyFirstManifest">
[m11] <Reference>
[m12] ...
[m13] </Reference>
[m14] <Reference>
[m15] ...
[m16] </Reference>
[m17] </Manifest>
[m18] </Object>
What is happening here is the following:
1) The Reference element (m01) refers to the same document and the
digest is calculated/validated against the Manifest node (m10) according
to the usual XMLDsig rules. The signature validation fails if there
is a digest mismatch.
2) Separately, the Object element (m09) is processed and digests are
calculated/validated but this does not impact the signature validation.
The xmlsec library returns the status of the validation in
xmlSecDSigCtx::manifestReferences list.
In the code, xmlSecDSigReferenceCtxProcessNode() fails with an error
only if there is a real processing error (e.g. malformed Reference
object). The digest mismatch results in dsigRefCtx->status to be set
to xmlSecDSigStatusInvalid. The xmlSecDSigCtxProcessManifestNode()
DOES NOT check dsigRefCtx->status (in comparison
xmlSecDSigCtxProcessReferences() DOES and fails if it is not
xmlSecDSigStatusSucceeded).
There are tests for this (e.g.
tests/merlin-xmldsig-twenty-three/signature.xml).
Best,
Aleksey
Aleksey
On 6/2/17 2:22 AM, Dan Seguin wrote:
> Greetings,
>
> I have a question about signing and validating Signatures where Manifest
> blocks are present.
>
> My understanding (if correct) from the XMLDSIG spec is that References
> within Manifest blocks can fail the digest operation or de-referencing
> of an URI, and not be considered a failure for signing or validation.
>
> In cases where the Manifest block is Reference'd from a SignedInfo
> Reference, the whole block is digested (with whatever is in there)
> whether or not the digesting occurred on the internal Manifest Reference
> entries.
>
> I'm seeing that xmlsec functions throw an error that halts the signing
> or verification if the References inside a Manifest block can't be
> processed.
>
> Is this correct?
>
> From xmldsig.c, function xmlSecDSigCtxProcessManifestNode, there is this
> snippet:
>
>> /* calculate references */
>> cur = xmlSecGetNextElementNode(node->children);
>> while((cur != NULL) && (xmlSecCheckNodeName(cur,
>> xmlSecNodeReference, xmlSecDSigNs))) {
>> /* create reference */
>> dsigRefCtx = xmlSecDSigReferenceCtxCreate(dsigCtx,
>> xmlSecDSigReferenceOriginManifest);
>> if(dsigRefCtx == NULL) {
>> xmlSecError(XMLSEC_ERRORS_HERE,
>> NULL,
>> "xmlSecDSigReferenceCtxCreate",
>> XMLSEC_ERRORS_R_XMLSEC_FAILED,
>> XMLSEC_ERRORS_NO_MESSAGE);
>> return(-1);
>> }
>>
>> /* add to the list */
>> ret = xmlSecPtrListAdd(&(dsigCtx->manifestReferences),
>> dsigRefCtx);
>> if(ret < 0) {
>> xmlSecError(XMLSEC_ERRORS_HERE,
>> NULL,
>> "xmlSecPtrListAdd",
>> XMLSEC_ERRORS_R_XMLSEC_FAILED,
>> XMLSEC_ERRORS_NO_MESSAGE);
>> xmlSecDSigReferenceCtxDestroy(dsigRefCtx);
>> return(-1);
>> }
>>
>> /* process */
>> ret = xmlSecDSigReferenceCtxProcessNode(dsigRefCtx, cur);
>> if(ret < 0) {
>> xmlSecError(XMLSEC_ERRORS_HERE,
>> NULL,
>> "xmlSecDSigReferenceCtxProcessNode",
>> XMLSEC_ERRORS_R_XMLSEC_FAILED,
>> "node=%s",
>> xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
>> return(-1);
>> }
>>
>> /* we don;t care if Reference processing failed because
>> * it's Manifest node */
>> cur = xmlSecGetNextElementNode(cur->next);
>
> The call to xmlSecDSigReferenceCtxProcessNode exits
> xmlSecDSigCtxProcessManifestNode if there's a failure, sending the error
> upstream.
>
> For producing a Signature (from template) with a Manifest block (with
> pre-calculated Digest from an application and populated with an URI that
> is NOT processable) this isn't a problem if setting dsigCtx->flags |=
> XMLSEC_DSIG_FLAGS_IGNORE_MANIFESTS.
>
> However, for ingesting Signatures from external entities, Manifest
> blocks may have to be processed to verify (reference) digests before
> verifying signature. On failure, I'd assume that whatever digests are
> there are then used for signature validation.
>
> I would rather not use the IGNORE flag on validation.
>
> Guidance?
>
> Cheers.
>
>
>
>
>
>
>
>
>
>
> _______________________________________________
> xmlsec mailing list
> xmlsec at aleksey.com
> http://www.aleksey.com/mailman/listinfo/xmlsec
>
More information about the xmlsec
mailing list