Bug 63011

Summary: Multiple digital signature in excel file broke first signature
Product: POI Reporter: Martin <martin.klima>
Component: POIFSAssignee: POI Developers List <dev>
Status: RESOLVED FIXED    
Severity: normal CC: martin.klima
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: All   
Attachments: Blank Excel file which I need to sign
File signed with apache POI first time
File signed with apache POI second time - this removes previous sign from file
First key used for first signing of excel document
Second key used for second signing of excel document
Excel sheet signed twice with MS tool
Example of using a custom facet for additional properties
Example of using a custom facet for additional properties

Description Martin 2018-12-14 09:48:56 UTC
Created attachment 36325 [details]
Blank Excel file which I need to sign

Hi guys,

I am trying to use apache POI library to sign Excel file. I need to sign it multiple times with different certificates (keys) to verify identity of all signers. 

With example from apache POI encryption page I am able to sign file exactly once. The signature is valid but when I do it again, with different key the previous sign is removed and the excel file is signed only with the last key that I used.

Is there any option how to sign Excel file and keep previous digital signatues?

Thanks,
Martin
Comment 1 Martin 2018-12-14 09:49:26 UTC
Created attachment 36326 [details]
File signed with apache POI first time
Comment 2 Martin 2018-12-14 09:50:24 UTC
Created attachment 36327 [details]
File signed with apache POI second time - this removes previous sign from file

This removes previous sign from file - i need to keep both digital signatures on that file and the desired result should be append the digital signature to that file.
Comment 3 Andreas Beeker 2018-12-14 09:59:07 UTC
Since I've adapted the eID applet code, I received once or twice the request to provide multiple signing, but it usually got stuck when requesting the test certs/keys.
I would prefer to work with real keys (instead of junit generated ones) so I can compare the resulting signed document better.

Please send me your test keys (hopefully from a Test CA).

Andi
Comment 4 Martin 2018-12-14 10:12:24 UTC
Hi,

thanks for response, I got these two keys generated and I usually store them in java keystore (if you wish I can provide it too). The keys are not verified by CA, for digital signature is needed only private key so it should be enough.

I will append them to attachment.
Comment 5 Martin 2018-12-14 10:12:57 UTC
Created attachment 36328 [details]
First key used for first signing of excel document
Comment 6 Martin 2018-12-14 10:13:21 UTC
Created attachment 36329 [details]
Second key used for second signing of excel document
Comment 7 Andreas Beeker 2018-12-14 11:53:57 UTC
I'll try to sign the file twice via Excel, to have a base for comparision - but maybe you can add your expected resulting file too?
Comment 8 Martin 2018-12-14 12:22:26 UTC
Created attachment 36330 [details]
Excel sheet signed twice with MS tool

This is document which was signed twice - you can open it in Excel and see two signatures are visible in the panel on the right side. The keys are the same as I already submited before.
Comment 9 Andreas Beeker 2018-12-15 00:59:56 UTC
Applied via r1848974.

There's a new config property in SignatureConfig.setAllowMultipleSignatures(true) to allow adding of signatures, which is by default false to stay backward compatible. Actually I'm now removing any other signatures if this is false, which was more lazy handled before.

You can fetch the jars from the nightly [1] if the build [2] #596 and later are successful.

Please leave a comment, if it works for you.

[1] https://builds.apache.org/view/P/view/POI/job/POI-DSL-1.8/lastSuccessfulBuild/artifact/build/dist/

[2] https://builds.apache.org/view/P/view/POI/job/POI-DSL-1.8/
Comment 10 Martin 2018-12-15 14:17:28 UTC
Hi,

thanks for the quick update! I will try if it works. Just theoretically, what will result of this two use-cases:

A) Excel is first signed by MS Excel GUI and then by Apache POI - will it keep both signatures?
B) Apache POI sign document first and then it's opened and signed again with MS Excel. Will it break the first signature?

I am gonna test it soon but is that theoretically possible?

Thanks,
Martin
Comment 11 Andreas Beeker 2018-12-15 16:11:23 UTC
(In reply to Martin from comment #10)
> I am gonna test it soon but is that theoretically possible?

I guess so, at least I've added a junit test which closes/opens the file and add another signature. So after your test, we know if it's also practically possible ;)

I've only tested if Excel accepts your keys, which I imported previously as accepted trust authority.

I've seen that in your test file, you also have still-to-be-approved/signed entries in - I actually don't know (but also haven't searched for) how to add them via Excel 2016. so I might need to extend the implementation to remove those wish-list entries, when I've signed it.
Comment 12 Martin 2018-12-17 09:06:18 UTC
Hi,

I tested the new version of library and it seems to work very well. Great job!

Just when I already dig into that I got two questions, is there possibility to setup some of the properties which are support by MS Excel?

There is short example: https://www.pastiebin.com/5c17658b89434 

And secondly I'm using the example code for encryption which is provided in public Apache POI website, I noticed that even when I save the file into new file the original file is also changed and its modified. Is there any possibility to keep original file untouched and save result as new file?

Example of code: https://www.pastiebin.com/5c1766b3b2a37

Thanks for help,
Martin
Comment 13 Andreas Beeker 2018-12-17 10:15:38 UTC
I'll have a look at those properties and see how I can fit them in. For signed properties, they probably have to be in the SignatureConfig - for unsigned properties, the signature document could be left for editing - either via DOM or with the help of the JAXB-annotated classes.

The writing on close() is documented in #59287 and although I also like it to be solved, I'm not so sure if this should be also applied to signing for same reason as mentioned in website - so for the time being you need to work around with either copying the file first or using the in-memory variant, i.e. loading via InputStream.
Comment 14 Andreas Beeker 2018-12-17 22:12:19 UTC
Created attachment 36332 [details]
Example of using a custom facet for additional properties

There's no need to change the POI implementation - you can add those additional properties yourself - have a look at the example attachment.
Comment 15 Martin 2019-01-02 09:17:38 UTC
Hi Andreas,

thanks for the example, it's very nice. I was able to add custom information to the signature. I tried to search but I don't know, how to access and setup information for object "idOfficeObject". Can you point me somewhere or extend the example to show, how to add information like this?

    <Object Id="idOfficeObject">
        <SignatureProperties>
            <SignatureProperty Id="idOfficeV1Details" Target="#idPackageSignature">
                <SignatureInfoV1 xmlns="http://schemas.microsoft.com/office/2006/digsig">
                    <SetupID></SetupID>
                    <SignatureText></SignatureText>
                    <SignatureImage/>
                    <SignatureComments>my signature comment</SignatureComments>
                    <WindowsVersion>6.1</WindowsVersion>
                    <OfficeVersion>16.0</OfficeVersion>
                    <ApplicationVersion>16.0</ApplicationVersion>
                    <Monitors>1</Monitors>
                    <HorizontalResolution>1920</HorizontalResolution>
                    <VerticalResolution>1200</VerticalResolution>
                    <ColorDepth>32</ColorDepth>
                    <SignatureProviderId>{00000000-0000-0000-0000-000000000000}</SignatureProviderId>
                    <SignatureProviderUrl></SignatureProviderUrl>
                    <SignatureProviderDetails>9</SignatureProviderDetails>
                    <SignatureType>1</SignatureType>
                </SignatureInfoV1>
                <SignatureInfoV2 xmlns="http://schemas.microsoft.com/office/2006/digsig">
                    <Address1>My cool address 1</Address1>
                    <Address2>My cool address 2</Address2>
                </SignatureInfoV2>
            </SignatureProperty>
        </SignatureProperties>
    </Object>
Comment 16 Andreas Beeker 2019-01-19 22:05:55 UTC
Created attachment 36382 [details]
Example of using a custom facet for additional properties

I've updated my example to also modify the idOfficeObject part.
Maybe its noteworthy, that you don't need a cursor for adding arbitrary text, but you can also use XmlString.