123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692 |
- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ==================================================================== */
-
- /* ====================================================================
- This product contains an ASLv2 licensed version of the OOXML signer
- package from the eID Applet project
- http://code.google.com/p/eid-applet/source/browse/trunk/README.txt
- Copyright (C) 2008-2014 FedICT.
- ================================================================= */
- package org.apache.poi.poifs.crypt;
-
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertFalse;
- import static org.junit.Assert.assertNotNull;
- import static org.junit.Assert.assertTrue;
-
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.ConnectException;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
- import java.security.Key;
- import java.security.KeyPair;
- import java.security.KeyStore;
- import java.security.PrivateKey;
- import java.security.cert.Certificate;
- import java.security.cert.X509CRL;
- import java.security.cert.X509Certificate;
- import java.util.ArrayList;
- import java.util.Calendar;
- import java.util.Collections;
- import java.util.Date;
- import java.util.Iterator;
- import java.util.List;
-
- import org.apache.poi.POIDataSamples;
- import org.apache.poi.POITestCase;
- import org.apache.poi.openxml4j.opc.OPCPackage;
- import org.apache.poi.openxml4j.opc.PackageAccess;
- import org.apache.poi.poifs.crypt.dsig.DigestInfo;
- import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
- import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
- import org.apache.poi.poifs.crypt.dsig.SignatureInfo.SignaturePart;
- import org.apache.poi.poifs.crypt.dsig.facets.EnvelopedSignatureFacet;
- import org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet;
- import org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet;
- import org.apache.poi.poifs.crypt.dsig.facets.XAdESXLSignatureFacet;
- import org.apache.poi.poifs.crypt.dsig.services.RevocationData;
- import org.apache.poi.poifs.crypt.dsig.services.RevocationDataService;
- import org.apache.poi.poifs.crypt.dsig.services.TimeStampService;
- import org.apache.poi.poifs.crypt.dsig.services.TimeStampServiceValidator;
- import org.apache.poi.ss.usermodel.WorkbookFactory;
- import org.apache.poi.util.DocumentHelper;
- import org.apache.poi.util.IOUtils;
- import org.apache.poi.util.LocaleUtil;
- import org.apache.poi.util.POILogFactory;
- import org.apache.poi.util.POILogger;
- import org.apache.poi.xssf.streaming.SXSSFWorkbook;
- import org.apache.poi.xssf.usermodel.XSSFWorkbook;
- import org.apache.xmlbeans.XmlObject;
- import org.bouncycastle.asn1.x509.KeyUsage;
- import org.bouncycastle.cert.ocsp.OCSPResp;
- import org.etsi.uri.x01903.v13.DigestAlgAndValueType;
- import org.etsi.uri.x01903.v13.QualifyingPropertiesType;
- import org.junit.Assume;
- import org.junit.BeforeClass;
- import org.junit.Test;
- import org.w3.x2000.x09.xmldsig.ReferenceType;
- import org.w3.x2000.x09.xmldsig.SignatureDocument;
- import org.w3c.dom.Document;
-
- public class TestSignatureInfo {
- private static final POILogger LOG = POILogFactory.getLogger(TestSignatureInfo.class);
- private static final POIDataSamples testdata = POIDataSamples.getXmlDSignInstance();
-
- private static Calendar cal;
- private KeyPair keyPair = null;
- private X509Certificate x509 = null;
-
- @BeforeClass
- public static void initBouncy() throws IOException {
- CryptoFunctions.registerBouncyCastle();
-
- /*** TODO : set cal to now ... only set to fixed date for debugging ... */
- cal = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC);
- // cal.set(2014, 7, 6, 21, 42, 12);
- // cal.clear(Calendar.MILLISECOND);
-
- // don't run this test when we are using older Xerces as it triggers an XML Parser backwards compatibility issue
- // in the xmlsec jar file
- String additionalJar = System.getProperty("additionaljar");
- //System.out.println("Having: " + additionalJar);
- Assume.assumeTrue("Not running TestSignatureInfo because we are testing with additionaljar set to " + additionalJar,
- additionalJar == null || additionalJar.trim().length() == 0);
- }
-
- @Test
- public void office2007prettyPrintedRels() throws Exception {
- OPCPackage pkg = OPCPackage.open(testdata.getFile("office2007prettyPrintedRels.docx"), PackageAccess.READ);
- try {
- SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
- SignatureInfo si = new SignatureInfo();
- si.setSignatureConfig(sic);
- boolean isValid = si.verifySignature();
- assertTrue(isValid);
- } finally {
- pkg.close();
- }
- }
-
- @Test
- public void getSignerUnsigned() throws Exception {
- String testFiles[] = {
- "hello-world-unsigned.docx",
- "hello-world-unsigned.pptx",
- "hello-world-unsigned.xlsx",
- "hello-world-office-2010-technical-preview-unsigned.docx"
- };
-
- for (String testFile : testFiles) {
- OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ);
- SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
- SignatureInfo si = new SignatureInfo();
- si.setSignatureConfig(sic);
- List<X509Certificate> result = new ArrayList<X509Certificate>();
- for (SignaturePart sp : si.getSignatureParts()) {
- if (sp.validate()) {
- result.add(sp.getSigner());
- }
- }
- pkg.revert();
- pkg.close();
- assertNotNull(result);
- assertTrue(result.isEmpty());
- }
- }
-
- @Test
- public void getSigner() throws Exception {
- String testFiles[] = {
- "hyperlink-example-signed.docx",
- "hello-world-signed.docx",
- "hello-world-signed.pptx",
- "hello-world-signed.xlsx",
- "hello-world-office-2010-technical-preview.docx",
- "ms-office-2010-signed.docx",
- "ms-office-2010-signed.pptx",
- "ms-office-2010-signed.xlsx",
- "Office2010-SP1-XAdES-X-L.docx",
- "signed.docx",
- };
-
- for (String testFile : testFiles) {
- OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ);
- try {
- SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
- SignatureInfo si = new SignatureInfo();
- si.setSignatureConfig(sic);
- List<X509Certificate> result = new ArrayList<X509Certificate>();
- for (SignaturePart sp : si.getSignatureParts()) {
- if (sp.validate()) {
- result.add(sp.getSigner());
- }
- }
-
- assertNotNull(result);
- assertEquals("test-file: "+testFile, 1, result.size());
- X509Certificate signer = result.get(0);
- LOG.log(POILogger.DEBUG, "signer: " + signer.getSubjectX500Principal());
-
- boolean b = si.verifySignature();
- assertTrue("test-file: "+testFile, b);
- pkg.revert();
- } finally {
- pkg.close();
- }
- }
- }
-
- @Test
- public void getMultiSigners() throws Exception {
- String testFile = "hello-world-signed-twice.docx";
- OPCPackage pkg = OPCPackage.open(testdata.getFile(testFile), PackageAccess.READ);
- try {
- SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
- SignatureInfo si = new SignatureInfo();
- si.setSignatureConfig(sic);
- List<X509Certificate> result = new ArrayList<X509Certificate>();
- for (SignaturePart sp : si.getSignatureParts()) {
- if (sp.validate()) {
- result.add(sp.getSigner());
- }
- }
-
- assertNotNull(result);
- assertEquals("test-file: "+testFile, 2, result.size());
- X509Certificate signer1 = result.get(0);
- X509Certificate signer2 = result.get(1);
- LOG.log(POILogger.DEBUG, "signer 1: " + signer1.getSubjectX500Principal());
- LOG.log(POILogger.DEBUG, "signer 2: " + signer2.getSubjectX500Principal());
-
- boolean b = si.verifySignature();
- assertTrue("test-file: "+testFile, b);
- pkg.revert();
- } finally {
- pkg.close();
- }
- }
-
- @Test
- public void testSignSpreadsheet() throws Exception {
- String testFile = "hello-world-unsigned.xlsx";
- OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
- sign(pkg, "Test", "CN=Test", 1);
- pkg.close();
- }
-
- @Test
- public void testManipulation() throws Exception {
- // sign & validate
- String testFile = "hello-world-unsigned.xlsx";
- @SuppressWarnings("resource")
- OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
- sign(pkg, "Test", "CN=Test", 1);
-
- // manipulate
- XSSFWorkbook wb = new XSSFWorkbook(pkg);
- wb.setSheetName(0, "manipulated");
- // ... I don't know, why commit is protected ...
- POITestCase.callMethod(XSSFWorkbook.class, wb, Void.class, "commit", new Class[0], new Object[0]);
-
- // todo: test a manipulation on a package part, which is not signed
- // ... maybe in combination with #56164
-
- // validate
- SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
- SignatureInfo si = new SignatureInfo();
- si.setSignatureConfig(sic);
- boolean b = si.verifySignature();
- assertFalse("signature should be broken", b);
-
- wb.close();
- }
-
- @Test
- public void testSignSpreadsheetWithSignatureInfo() throws Exception {
- initKeyPair("Test", "CN=Test");
- String testFile = "hello-world-unsigned.xlsx";
- OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
- SignatureConfig sic = new SignatureConfig();
- sic.setOpcPackage(pkg);
- sic.setKey(keyPair.getPrivate());
- sic.setSigningCertificateChain(Collections.singletonList(x509));
- SignatureInfo si = new SignatureInfo();
- si.setSignatureConfig(sic);
- // hash > sha1 doesn't work in excel viewer ...
- si.confirmSignature();
- List<X509Certificate> result = new ArrayList<X509Certificate>();
- for (SignaturePart sp : si.getSignatureParts()) {
- if (sp.validate()) {
- result.add(sp.getSigner());
- }
- }
- assertEquals(1, result.size());
- pkg.close();
- }
-
- @Test
- public void testSignEnvelopingDocument() throws Exception {
- String testFile = "hello-world-unsigned.xlsx";
- OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
-
- initKeyPair("Test", "CN=Test");
- final X509CRL crl = PkiTestUtils.generateCrl(x509, keyPair.getPrivate());
-
- // setup
- SignatureConfig signatureConfig = new SignatureConfig();
- signatureConfig.setOpcPackage(pkg);
- signatureConfig.setKey(keyPair.getPrivate());
-
- /*
- * We need at least 2 certificates for the XAdES-C complete certificate
- * refs construction.
- */
- List<X509Certificate> certificateChain = new ArrayList<X509Certificate>();
- certificateChain.add(x509);
- certificateChain.add(x509);
- signatureConfig.setSigningCertificateChain(certificateChain);
-
- signatureConfig.addSignatureFacet(new EnvelopedSignatureFacet());
- signatureConfig.addSignatureFacet(new KeyInfoSignatureFacet());
- signatureConfig.addSignatureFacet(new XAdESSignatureFacet());
- signatureConfig.addSignatureFacet(new XAdESXLSignatureFacet());
-
- // check for internet, no error means it works
- boolean mockTsp = (getAccessError("http://timestamp.comodoca.com/rfc3161", true, 10000) != null);
-
- // http://timestamping.edelweb.fr/service/tsp
- // http://tsa.belgium.be/connect
- // http://timestamp.comodoca.com/authenticode
- // http://timestamp.comodoca.com/rfc3161
- // http://services.globaltrustfinder.com/adss/tsa
- signatureConfig.setTspUrl("http://timestamp.comodoca.com/rfc3161");
- signatureConfig.setTspRequestPolicy(null); // comodoca request fails, if default policy is set ...
- signatureConfig.setTspOldProtocol(false);
-
- //set proxy info if any
- String proxy = System.getProperty("http_proxy");
- if (proxy != null && proxy.trim().length() > 0) {
- signatureConfig.setProxyUrl(proxy);
- }
-
- if (mockTsp) {
- TimeStampService tspService = new TimeStampService(){
- @Override
- public byte[] timeStamp(byte[] data, RevocationData revocationData) throws Exception {
- revocationData.addCRL(crl);
- return "time-stamp-token".getBytes(LocaleUtil.CHARSET_1252);
- }
- @Override
- public void setSignatureConfig(SignatureConfig config) {
- // empty on purpose
- }
- };
- signatureConfig.setTspService(tspService);
- } else {
- TimeStampServiceValidator tspValidator = new TimeStampServiceValidator() {
- @Override
- public void validate(List<X509Certificate> validateChain,
- RevocationData revocationData) throws Exception {
- for (X509Certificate certificate : validateChain) {
- LOG.log(POILogger.DEBUG, "certificate: " + certificate.getSubjectX500Principal());
- LOG.log(POILogger.DEBUG, "validity: " + certificate.getNotBefore() + " - " + certificate.getNotAfter());
- }
- }
- };
- signatureConfig.setTspValidator(tspValidator);
- signatureConfig.setTspOldProtocol(signatureConfig.getTspUrl().contains("edelweb"));
- }
-
- final RevocationData revocationData = new RevocationData();
- revocationData.addCRL(crl);
- OCSPResp ocspResp = PkiTestUtils.createOcspResp(x509, false,
- x509, x509, keyPair.getPrivate(), "SHA1withRSA", cal.getTimeInMillis());
- revocationData.addOCSP(ocspResp.getEncoded());
-
- RevocationDataService revocationDataService = new RevocationDataService(){
- @Override
- public RevocationData getRevocationData(List<X509Certificate> revocationChain) {
- return revocationData;
- }
- };
- signatureConfig.setRevocationDataService(revocationDataService);
-
- // operate
- SignatureInfo si = new SignatureInfo();
- si.setSignatureConfig(signatureConfig);
- try {
- si.confirmSignature();
- } catch (RuntimeException e) {
- pkg.close();
- // only allow a ConnectException because of timeout, we see this in Jenkins from time to time...
- if(e.getCause() == null) {
- throw e;
- }
- if(!(e.getCause() instanceof ConnectException)) {
- throw e;
- }
- assertTrue("Only allowing ConnectException with 'timed out' as message here, but had: " + e, e.getCause().getMessage().contains("timed out"));
- }
-
- // verify
- Iterator<SignaturePart> spIter = si.getSignatureParts().iterator();
- assertTrue(spIter.hasNext());
- SignaturePart sp = spIter.next();
- boolean valid = sp.validate();
- assertTrue(valid);
-
- SignatureDocument sigDoc = sp.getSignatureDocument();
- String declareNS =
- "declare namespace xades='http://uri.etsi.org/01903/v1.3.2#'; "
- + "declare namespace ds='http://www.w3.org/2000/09/xmldsig#'; ";
-
- String digestValXQuery = declareNS +
- "$this/ds:Signature/ds:SignedInfo/ds:Reference";
- for (ReferenceType rt : (ReferenceType[])sigDoc.selectPath(digestValXQuery)) {
- assertNotNull(rt.getDigestValue());
- assertEquals(signatureConfig.getDigestMethodUri(), rt.getDigestMethod().getAlgorithm());
- }
-
- String certDigestXQuery = declareNS +
- "$this//xades:SigningCertificate/xades:Cert/xades:CertDigest";
- XmlObject xoList[] = sigDoc.selectPath(certDigestXQuery);
- assertEquals(xoList.length, 1);
- DigestAlgAndValueType certDigest = (DigestAlgAndValueType)xoList[0];
- assertNotNull(certDigest.getDigestValue());
-
- String qualPropXQuery = declareNS +
- "$this/ds:Signature/ds:Object/xades:QualifyingProperties";
- xoList = sigDoc.selectPath(qualPropXQuery);
- assertEquals(xoList.length, 1);
- QualifyingPropertiesType qualProp = (QualifyingPropertiesType)xoList[0];
- boolean qualPropXsdOk = qualProp.validate();
- assertTrue(qualPropXsdOk);
-
- pkg.close();
- }
-
- public static String getAccessError(String destinationUrl, boolean fireRequest, int timeout) {
- URL url;
- try {
- url = new URL(destinationUrl);
- } catch (MalformedURLException e) {
- throw new IllegalArgumentException("Invalid destination URL", e);
- }
-
- HttpURLConnection conn = null;
- try {
- conn = (HttpURLConnection) url.openConnection();
-
- // set specified timeout if non-zero
- if(timeout != 0) {
- conn.setConnectTimeout(timeout);
- conn.setReadTimeout(timeout);
- }
-
- conn.setDoOutput(false);
- conn.setDoInput(true);
-
- /* if connecting is not possible this will throw a connection refused exception */
- conn.connect();
-
- if (fireRequest) {
- InputStream is = null;
- try {
- is = conn.getInputStream();
- } finally {
- IOUtils.closeQuietly(is);
- }
-
- }
- /* if connecting is possible we return true here */
- return null;
-
- } catch (IOException e) {
- /* exception is thrown -> server not available */
- return e.getClass().getName() + ": " + e.getMessage();
- } finally {
- if (conn != null) {
- conn.disconnect();
- }
- }
- }
-
- @Test
- public void testCertChain() throws Exception {
- KeyStore keystore = KeyStore.getInstance("PKCS12");
- String password = "test";
- InputStream is = testdata.openResourceAsStream("chaintest.pfx");
- keystore.load(is, password.toCharArray());
- is.close();
-
- Key key = keystore.getKey("poitest", password.toCharArray());
- Certificate chainList[] = keystore.getCertificateChain("poitest");
- List<X509Certificate> certChain = new ArrayList<X509Certificate>();
- for (Certificate c : chainList) {
- certChain.add((X509Certificate)c);
- }
- x509 = certChain.get(0);
- keyPair = new KeyPair(x509.getPublicKey(), (PrivateKey)key);
-
- String testFile = "hello-world-unsigned.xlsx";
- OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
-
- SignatureConfig signatureConfig = new SignatureConfig();
- signatureConfig.setKey(keyPair.getPrivate());
- signatureConfig.setSigningCertificateChain(certChain);
- Calendar oldCal = LocaleUtil.getLocaleCalendar(2007, 7, 1);
- signatureConfig.setExecutionTime(oldCal.getTime());
- signatureConfig.setDigestAlgo(HashAlgorithm.sha1);
- signatureConfig.setOpcPackage(pkg);
-
- SignatureInfo si = new SignatureInfo();
- si.setSignatureConfig(signatureConfig);
-
- si.confirmSignature();
-
- for (SignaturePart sp : si.getSignatureParts()){
- assertTrue("Could not validate", sp.validate());
- X509Certificate signer = sp.getSigner();
- assertNotNull("signer undefined?!", signer);
- List<X509Certificate> certChainRes = sp.getCertChain();
- assertEquals(3, certChainRes.size());
- }
-
- pkg.close();
- }
-
- @Test
- public void testNonSha1() throws Exception {
- String testFile = "hello-world-unsigned.xlsx";
- initKeyPair("Test", "CN=Test");
-
- SignatureConfig signatureConfig = new SignatureConfig();
- signatureConfig.setKey(keyPair.getPrivate());
- signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));
-
- HashAlgorithm testAlgo[] = { HashAlgorithm.sha224, HashAlgorithm.sha256
- , HashAlgorithm.sha384, HashAlgorithm.sha512, HashAlgorithm.ripemd160 };
-
- for (HashAlgorithm ha : testAlgo) {
- OPCPackage pkg = null;
- try {
- signatureConfig.setDigestAlgo(ha);
- pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
- signatureConfig.setOpcPackage(pkg);
-
- SignatureInfo si = new SignatureInfo();
- si.setSignatureConfig(signatureConfig);
-
- si.confirmSignature();
- boolean b = si.verifySignature();
- assertTrue("Signature not correctly calculated for " + ha, b);
- } finally {
- if (pkg != null) pkg.close();
- }
- }
- }
-
- @Test
- public void bug58630() throws Exception {
- // test deletion of sheet 0 and signing
- File tpl = copy(testdata.getFile("bug58630.xlsx"));
- SXSSFWorkbook wb1 = new SXSSFWorkbook((XSSFWorkbook)WorkbookFactory.create(tpl), 10);
- wb1.setCompressTempFiles(true);
- wb1.removeSheetAt(0);
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- wb1.write(os);
- wb1.close();
- OPCPackage pkg = OPCPackage.open(new ByteArrayInputStream(os.toByteArray()));
-
- initKeyPair("Test", "CN=Test");
- SignatureConfig signatureConfig = new SignatureConfig();
- signatureConfig.setKey(keyPair.getPrivate());
- signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));
- signatureConfig.setOpcPackage(pkg);
-
- SignatureInfo si = new SignatureInfo();
- si.setSignatureConfig(signatureConfig);
- si.confirmSignature();
- assertTrue("invalid signature", si.verifySignature());
-
- pkg.close();
- }
-
-
- private void sign(OPCPackage pkgCopy, String alias, String signerDn, int signerCount) throws Exception {
- initKeyPair(alias, signerDn);
-
- SignatureConfig signatureConfig = new SignatureConfig();
- signatureConfig.setKey(keyPair.getPrivate());
- signatureConfig.setSigningCertificateChain(Collections.singletonList(x509));
- signatureConfig.setExecutionTime(cal.getTime());
- signatureConfig.setDigestAlgo(HashAlgorithm.sha1);
- signatureConfig.setOpcPackage(pkgCopy);
-
- SignatureInfo si = new SignatureInfo();
- si.setSignatureConfig(signatureConfig);
-
- Document document = DocumentHelper.createDocument();
-
- // operate
- DigestInfo digestInfo = si.preSign(document, null);
-
- // verify
- assertNotNull(digestInfo);
- LOG.log(POILogger.DEBUG, "digest algo: " + digestInfo.hashAlgo);
- LOG.log(POILogger.DEBUG, "digest description: " + digestInfo.description);
- assertEquals("Office OpenXML Document", digestInfo.description);
- assertNotNull(digestInfo.hashAlgo);
- assertNotNull(digestInfo.digestValue);
-
- // setup: key material, signature value
- byte[] signatureValue = si.signDigest(digestInfo.digestValue);
-
- // operate: postSign
- si.postSign(document, signatureValue);
-
- // verify: signature
- si.getSignatureConfig().setOpcPackage(pkgCopy);
- List<X509Certificate> result = new ArrayList<X509Certificate>();
- for (SignaturePart sp : si.getSignatureParts()) {
- if (sp.validate()) {
- result.add(sp.getSigner());
- }
- }
- assertEquals(signerCount, result.size());
- }
-
- private void initKeyPair(String alias, String subjectDN) throws Exception {
- final char password[] = "test".toCharArray();
- File file = new File("build/test.pfx");
-
- KeyStore keystore = KeyStore.getInstance("PKCS12");
-
- if (file.exists()) {
- FileInputStream fis = new FileInputStream(file);
- keystore.load(fis, password);
- fis.close();
- } else {
- keystore.load(null, password);
- }
-
- if (keystore.isKeyEntry(alias)) {
- Key key = keystore.getKey(alias, password);
- x509 = (X509Certificate)keystore.getCertificate(alias);
- keyPair = new KeyPair(x509.getPublicKey(), (PrivateKey)key);
- } else {
- keyPair = PkiTestUtils.generateKeyPair();
- Date notBefore = cal.getTime();
- Calendar cal2 = (Calendar)cal.clone();
- cal2.add(Calendar.YEAR, 1);
- Date notAfter = cal2.getTime();
- KeyUsage keyUsage = new KeyUsage(KeyUsage.digitalSignature);
-
- x509 = PkiTestUtils.generateCertificate(keyPair.getPublic(), subjectDN
- , notBefore, notAfter, null, keyPair.getPrivate(), true, 0, null, null, keyUsage);
-
- keystore.setKeyEntry(alias, keyPair.getPrivate(), password, new Certificate[]{x509});
- FileOutputStream fos = new FileOutputStream(file);
- keystore.store(fos, password);
- fos.close();
- }
- }
-
- private static File copy(File input) throws IOException {
- String extension = input.getName().replaceAll(".*?(\\.[^.]+)?$", "$1");
- if (extension == null || "".equals(extension)) {
- extension = ".zip";
- }
-
- // ensure that we create the "build" directory as it might not be existing
- // in the Sonar Maven runs where we are at a different source directory
- File buildDir = new File("build");
- if(!buildDir.exists()) {
- assertTrue("Failed to create " + buildDir.getAbsolutePath(),
- buildDir.mkdirs());
- }
- File tmpFile = new File(buildDir, "sigtest"+extension);
-
- OutputStream fos = new FileOutputStream(tmpFile);
- try {
- InputStream fis = new FileInputStream(input);
- try {
- IOUtils.copy(fis, fos);
- } finally {
- fis.close();
- }
- } finally {
- fos.close();
- }
-
- return tmpFile;
- }
-
- }
|