/* * eID Applet Project. * Copyright (C) 2009-2011 FedICT. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version * 3.0 as published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, see * http://www.gnu.org/licenses/. */ package test.unit.be.fedict.eid.applet.service.signer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.KeyPair; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.LinkedList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.crypto.Cipher; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bouncycastle.asn1.x509.KeyUsage; import org.joda.time.DateTime; import org.junit.Test; import be.fedict.eid.applet.service.signer.DigestAlgo; import be.fedict.eid.applet.service.signer.TemporaryDataStorage; import be.fedict.eid.applet.service.signer.asic.ASiCSignatureVerifier; import be.fedict.eid.applet.service.signer.asic.AbstractASiCSignatureService; import be.fedict.eid.applet.service.signer.facets.RevocationData; import be.fedict.eid.applet.service.signer.facets.RevocationDataService; import be.fedict.eid.applet.service.signer.time.TimeStampService; import be.fedict.eid.applet.service.spi.AddressDTO; import be.fedict.eid.applet.service.spi.DigestInfo; import be.fedict.eid.applet.service.spi.IdentityDTO; public class ASiCSignatureServiceTest { private static final Log LOG = LogFactory.getLog(ASiCSignatureServiceTest.class); private final static class ASiCSignatureService extends AbstractASiCSignatureService { public ASiCSignatureService(InputStream documentInputStream, DigestAlgo digestAlgo, RevocationDataService revocationDataService, TimeStampService timeStampService, TemporaryDataStorage temporaryDataStorage, IdentityDTO identity, byte[] photo, OutputStream documentOutputStream) throws IOException { super(documentInputStream, digestAlgo, revocationDataService, timeStampService, "ClaimedRole", identity, photo, temporaryDataStorage, documentOutputStream); setSignatureNamespacePrefix("ds"); } } @Test public void testCreateSignature() throws Exception { // setup KeyPair caKeyPair = PkiTestUtils.generateKeyPair(); DateTime caNotBefore = new DateTime(); DateTime caNotAfter = caNotBefore.plusYears(1); X509Certificate caCertificate = PkiTestUtils.generateCertificate(caKeyPair.getPublic(), "CN=TestCA", caNotBefore, caNotAfter, null, caKeyPair.getPrivate(), true, 0, null, null, new KeyUsage(KeyUsage.cRLSign | KeyUsage.keyCertSign)); final X509CRL crl = PkiTestUtils.generateCrl(caCertificate, caKeyPair.getPrivate()); KeyPair keyPair = PkiTestUtils.generateKeyPair(); DateTime notBefore = new DateTime(); DateTime notAfter = notBefore.plusMonths(1); X509Certificate certificate = PkiTestUtils.generateCertificate(keyPair.getPublic(), "CN=Test", notBefore, notAfter, caCertificate, caKeyPair.getPrivate(), false, 0, null, null, new KeyUsage(KeyUsage.nonRepudiation)); ByteArrayOutputStream asicOutputStream = new ByteArrayOutputStream(); ZipOutputStream asicZipOutputStream = new ZipOutputStream(asicOutputStream); ZipEntry fileZipEntry = new ZipEntry("file.txt"); asicZipOutputStream.putNextEntry(fileZipEntry); asicZipOutputStream.write("hello world".getBytes()); asicZipOutputStream.closeEntry(); asicZipOutputStream.close(); ByteArrayInputStream asicInputStream = new ByteArrayInputStream(asicOutputStream.toByteArray()); ByteArrayOutputStream resultOutputStream = new ByteArrayOutputStream(); TemporaryTestDataStorage temporaryDataStorage = new TemporaryTestDataStorage(); IdentityDTO identity = new IdentityDTO(); identity.name = "Cornelis"; identity.firstName = "Frank"; identity.male = true; byte[] photo = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; AddressDTO address = new AddressDTO(); address.city = "Brussels"; RevocationDataService revocationDataService = new RevocationDataService() { public RevocationData getRevocationData(List<X509Certificate> certificateChain) { RevocationData revocationData = new RevocationData(); revocationData.addCRL(crl); return revocationData; } }; TimeStampService timeStampService = new TimeStampService() { public byte[] timeStamp(byte[] data, RevocationData revocationData) throws Exception { return "encoded time-stamp token".getBytes(); } }; ASiCSignatureService testedInstance = new ASiCSignatureService(asicInputStream, DigestAlgo.SHA256, revocationDataService, timeStampService, temporaryDataStorage, identity, photo, resultOutputStream); List<X509Certificate> signingCertificateChain = new LinkedList<X509Certificate>(); signingCertificateChain.add(certificate); signingCertificateChain.add(caCertificate); // operate: preSign DigestInfo digestInfo = testedInstance.preSign(null, signingCertificateChain, identity, address, photo); // verify assertNotNull(digestInfo); LOG.debug("digest info description: " + digestInfo.description); assertEquals("Associated Signature Container", digestInfo.description); LOG.debug("digest info algo: " + digestInfo.digestAlgo); assertEquals("SHA-256", digestInfo.digestAlgo); // sign the digest value Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPrivate()); byte[] digestInfoValue = ArrayUtils.addAll(PkiTestUtils.SHA256_DIGEST_INFO_PREFIX, digestInfo.digestValue); byte[] signatureValue = cipher.doFinal(digestInfoValue); // operate: postSign testedInstance.postSign(signatureValue, signingCertificateChain); // verify File tmpFile = File.createTempFile("signed-container-", ".asice"); byte[] asicResult = resultOutputStream.toByteArray(); FileUtils.writeByteArrayToFile(tmpFile, asicResult); LOG.debug("ASiC file: " + tmpFile.getAbsolutePath()); List<X509Certificate> signers = ASiCSignatureVerifier.verifySignatures(asicResult); assertNotNull(signers); assertEquals(1, signers.size()); assertEquals(certificate, signers.get(0)); } }