Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Manifest #226

Closed
start780 opened this issue May 14, 2021 · 6 comments
Closed

Support for Manifest #226

start780 opened this issue May 14, 2021 · 6 comments
Milestone

Comments

@start780
Copy link

Hello,

I want to create a signature file like this :

<ds:Signature ...>
	<ds:SignedInfo>
		...
		<ds:Reference Type="http://www.w3.org/2000/09/xmldsig#Manifest" URI="#signedManifest">
			<ds:Transforms>
				<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
			</ds:Transforms>
			<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
			<ds:DigestValue>vWfsUvMyksFGeH3Qy+YsucuOjQw9r7nmFPRYr1uWjZs=</ds:DigestValue>
		</ds:Reference>
		...
	</ds:SignedInfo>
	...
	<ds:Object Id="manifestObject">
		<ds:Manifest Id="signedManifest">
			<ds:Reference Id="xxxx.pdf-Id" URI="xxxx.pdf">
				<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
				<ds:DigestValue>ke4lYqspZlL63pqG7rVj/+TRx4a7WTR+/kEbvWGCmIk=</ds:DigestValue>
			</ds:Reference>
		</ds:Manifest>
	</ds:Object>
</ds:Signature>

With that snipet, I'm able to create something that looks very close :

SignerEPES signer = (SignerEPES)new XadesEpesSigningProfile(SignerTestBase.keyingProviderNist, policyInfoProvider).newSigner()
DataObjectDesc obj = new EnvelopedXmlObject(manifest)
	.withTransform(new ExclusiveCanonicalXMLWithoutComments());
;
signer.sign(
	new SignedDataObjects(obj)
		.withBaseUri(base_uri)
	, doc
);

The result :

<ds:Signature ...>
	<ds:SignedInfo>
		...
		<ds:Reference Id="xmldsig-ab774bed-0f7c-4d64-a344-4ac202382981-ref0" Type="http://www.w3.org/2000/09/xmldsig#Object" URI="#xmldsig-ab774bed-0f7c-4d64-a344-4ac202382981-object0">
			<ds:Transforms>
				<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
			</ds:Transforms>
			<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
			<ds:DigestValue>OyPt7LhDGPUKdab1LOuzaFeaMuxETLlv/OkO+Qrn4sA=</ds:DigestValue>
		</ds:Reference>		
		...
	</ds:SignedInfo>
	...
	<ds:Object Id="xmldsig-ab774bed-0f7c-4d64-a344-4ac202382981-object0">
		<ns2:Manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:ManifestType" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#">
			<ns2:Reference Id="xxxx.pdf" URI="xxxx.pdf">
				<ns2:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
				<ns2:DigestValue>ke4lYqspZlL63pqG7rVj/+TRx4a7WTR+/kEbvWGCmIk=</ns2:DigestValue>
			</ns2:Reference>
		</ns2:Manifest>
	</ds:Object>
</ds:Signature>

My result have two problems :

  • the Reference URI point to the Object, instead of the Manifest.
  • the Reference Type is Object instead of Manifest.

It looks like there is some manifest support in xades4j, but for verification only.
Is it possible with xades4j to generate the signature in the format I want, (even with a quick dirty hack) ?

Thanks, Bernard.

@luisgoncalves
Copy link
Owner

Hi Bernard,

Right, xades4j has no builtin support to add a signed data object that is a Manifest and it isn't possible to explicitly control the Type (because these details are meant to be handled internally. This is the first time such a requirement comes up, so I guess it isn't a common thing.

I'm afraid there isn't a quick hack. It would probably require adding a new DataObjectDesc-derived type and updating SignedDataObjectsProcessor. I'm not sure how that would look like, though, as the manifest can be placed anywhere in the XML document...

I can have a look at options, but I'm not very convinced that this would be a good addition.

@start780
Copy link
Author

Hello Luis,

First, thank you for your reply.

The modifications you suggest were the ones I tried.
It was easy to change the reference type, but adding the refUri into the manifest is useless, because it's not recognized by the signing code.
Also removing the xmlObj.setId(refUri); makes the code failing, the signing code can't find the xml part to sign.
So, I'm stuck, I don't have the knowledge to change the signed portion of the xml properly.

The code I inserted in SignedDataObjectsProcessor

                //bbe
                else if (dataObjDesc instanceof EnvelopedXmlObject_for_manifest)
                {
                    // If the data object info is a EnvelopedXmlObject we need to create a
                    // XMLObject to embed it. The Reference uri will refer the new
                    // XMLObject's id.
                	EnvelopedXmlObject_for_manifest manifest = (EnvelopedXmlObject_for_manifest) dataObjDesc;
                    refUri = String.format("%s-object%d", xmlSignature.getId(), xmlSignature.getObjectLength());
                    refType = Reference.MANIFEST_URI;	// change ref type, ok.

                    ObjectContainer xmlObj = new ObjectContainer(xmlSignature.getDocument());
                    
                    Node content = manifest.getContent(); 
                    Attr attr = content.getOwnerDocument().createAttribute("Id");
                    attr.setValue(refUri);
                    content.getAttributes().setNamedItem(attr);	// inject Id in manifest ok, but useless.
                    
                    xmlObj.setId(refUri);		// cannot remove this, otherwise object to sign not found ! 
                    xmlObj.appendChild(manifest.getContent());
                    xmlObj.setMimeType(manifest.getMimeType());
                    xmlObj.setEncoding(manifest.getEncoding());
                    xmlSignature.appendObject(xmlObj);

                    refUri = '#' + refUri;
                } // bbe

I have no idea if this is a common thing, because I have no experience in signing, if you are interested, here is the policy I'm trying to implement : http://www.banque-france.fr/igc/signature/ps/ps_1_2_250_1_115_200_301_1.pdf § 4.2. Caractéristiques des signatures

Also, I don't see the problem about the placing of the manifest, from what I understand, it's the only child of an Object node we add, so we should have full control.

Thanks, Bernard.

@luisgoncalves
Copy link
Owner

Hi Bernard,

I'll see if I can find some time during this week to try out your code and other approaches.

How are you creating the manifest content, namely the digest calculation? Also, how do the References inside the manifest look like? I'm thinking how to model this; perhaps a manifest is could be a composite DataObjectDesc...

What I meant by the placement of the Manifest is: your policy requires it to be inside an Object element, but as far as I can tell, the XML-DSIG spec doesn't mandate anything about the location of Manifests within the XML resource. The library API shouldn't be very coupled to one use case. But having a Manifest inside an Object does make sense.

@start780
Copy link
Author

Hi Luis,

Again, thank you for taking time to look at this question.

I'm able to make my code functional, just by adding some blessing on the Id attribute with content.setIdAttributeNode(attr, true);
The References in the Manifest are exactly as in my first xml snippet in my first message :

<ds:Object Id="manifestObject">
	<ds:Manifest Id="signedManifest">
		<ds:Reference Id="xxxx.pdf-Id" URI="xxxx.pdf">
			<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
			<ds:DigestValue>ke4lYqspZlL63pqG7rVj/+TRx4a7WTR+/kEbvWGCmIk=</ds:DigestValue>
		</ds:Reference>
	</ds:Manifest>
</ds:Object>

In fact, the policy implies that there is only one reference in the manifest, but it looks exactly as normal References in SignedInfo

Actually, the manifest content is just hard coded, but I should calculate it, I will look at it now.

I totally agree that the library shouldn't be closely coupled to particular policies, but of course, if you can provide a clean approach to implement this, I'm interested.

Thanks, Bernard.

@luisgoncalves luisgoncalves added this to the vNext milestone May 23, 2021
@luisgoncalves luisgoncalves changed the title Manifest support ? Support for Manifest May 23, 2021
@luisgoncalves
Copy link
Owner

Hi Bernard,

I've written a PoC for the user case we've been discussing. After a bit more thought, I think having a new DataObjectDesc type does make sense.

The code still has a lot of TODOs but it is functional. The idea is that the manifest is also defined using DataObjectDesc types (only DataObjectReference for now) and the library handles the calculation of the manifest content.

It's pushed to https://github.com/luisgoncalves/xades4j/tree/iss-256. Can you have a look, namely at the test I added and the resulting signed document? Let me know what you think.

@luisgoncalves
Copy link
Owner

Hi Bernard

I've pushed the final solution for this. Hope you can use it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants