Search in sources :

Example 1 with SignatureDocument

use of org.w3.x2000.x09.xmldsig.SignatureDocument in project poi by apache.

the class TestSignatureInfo method testSignEnvelopingDocument.

@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");
    // comodoca request fails, if default policy is set ...
    signatureConfig.setTspRequestPolicy(null);
    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) || (e.getCause() instanceof SocketTimeoutException)) {
            Assume.assumeFalse("Only allowing ConnectException with 'timed out' as message here, but had: " + e, e.getCause().getMessage().contains("timed out"));
        } else if (e.getCause() instanceof IOException) {
            Assume.assumeFalse("Only allowing IOException with 'Error contacting TSP server' as message here, but had: " + e, e.getCause().getMessage().contains("Error contacting TSP server"));
        } else if (e.getCause() instanceof RuntimeException) {
            Assume.assumeFalse("Only allowing RuntimeException with 'This site is cur' as message here, but had: " + e, e.getCause().getMessage().contains("This site is cur"));
        }
        throw e;
    }
    // verify
    Iterator<SignaturePart> spIter = si.getSignatureParts().iterator();
    assertTrue("Had: " + si.getSignatureConfig().getOpcPackage().getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN), 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();
}
Also used : X509CRL(java.security.cert.X509CRL) EnvelopedSignatureFacet(org.apache.poi.poifs.crypt.dsig.facets.EnvelopedSignatureFacet) SignatureDocument(org.w3.x2000.x09.xmldsig.SignatureDocument) ArrayList(java.util.ArrayList) RevocationDataService(org.apache.poi.poifs.crypt.dsig.services.RevocationDataService) XAdESXLSignatureFacet(org.apache.poi.poifs.crypt.dsig.facets.XAdESXLSignatureFacet) ReferenceType(org.w3.x2000.x09.xmldsig.ReferenceType) DigestAlgAndValueType(org.etsi.uri.x01903.v13.DigestAlgAndValueType) OCSPResp(org.bouncycastle.cert.ocsp.OCSPResp) TimeStampService(org.apache.poi.poifs.crypt.dsig.services.TimeStampService) KeyInfoSignatureFacet(org.apache.poi.poifs.crypt.dsig.facets.KeyInfoSignatureFacet) List(java.util.List) ArrayList(java.util.ArrayList) ConnectException(java.net.ConnectException) RevocationData(org.apache.poi.poifs.crypt.dsig.services.RevocationData) SignatureConfig(org.apache.poi.poifs.crypt.dsig.SignatureConfig) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) SignatureInfo(org.apache.poi.poifs.crypt.dsig.SignatureInfo) TimeStampServiceValidator(org.apache.poi.poifs.crypt.dsig.services.TimeStampServiceValidator) SocketTimeoutException(java.net.SocketTimeoutException) QualifyingPropertiesType(org.etsi.uri.x01903.v13.QualifyingPropertiesType) XmlObject(org.apache.xmlbeans.XmlObject) SignaturePart(org.apache.poi.poifs.crypt.dsig.SignatureInfo.SignaturePart) OPCPackage(org.apache.poi.openxml4j.opc.OPCPackage) XAdESSignatureFacet(org.apache.poi.poifs.crypt.dsig.facets.XAdESSignatureFacet) Test(org.junit.Test)

Example 2 with SignatureDocument

use of org.w3.x2000.x09.xmldsig.SignatureDocument in project poi by apache.

the class SignatureInfo method writeDocument.

/**
     * Write XML signature into the OPC package
     *
     * @param document the xml signature document
     * @throws MarshalException
     */
protected void writeDocument(Document document) throws MarshalException {
    XmlOptions xo = new XmlOptions();
    Map<String, String> namespaceMap = new HashMap<String, String>();
    for (Map.Entry<String, String> entry : signatureConfig.getNamespacePrefixes().entrySet()) {
        namespaceMap.put(entry.getValue(), entry.getKey());
    }
    xo.setSaveSuggestedPrefixes(namespaceMap);
    xo.setUseDefaultNamespace();
    LOG.log(POILogger.DEBUG, "output signed Office OpenXML document");
    /*
         * Copy the original OOXML content to the signed OOXML package. During
         * copying some files need to changed.
         */
    OPCPackage pkg = signatureConfig.getOpcPackage();
    PackagePartName sigPartName, sigsPartName;
    try {
        // <Override PartName="/_xmlsignatures/sig1.xml" ContentType="application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml"/>
        sigPartName = PackagingURIHelper.createPartName("/_xmlsignatures/sig1.xml");
        // <Default Extension="sigs" ContentType="application/vnd.openxmlformats-package.digital-signature-origin"/>
        sigsPartName = PackagingURIHelper.createPartName("/_xmlsignatures/origin.sigs");
    } catch (InvalidFormatException e) {
        throw new MarshalException(e);
    }
    PackagePart sigPart = pkg.getPart(sigPartName);
    if (sigPart == null) {
        sigPart = pkg.createPart(sigPartName, ContentTypes.DIGITAL_SIGNATURE_XML_SIGNATURE_PART);
    }
    try {
        OutputStream os = sigPart.getOutputStream();
        SignatureDocument sigDoc = SignatureDocument.Factory.parse(document, DEFAULT_XML_OPTIONS);
        sigDoc.save(os, xo);
        os.close();
    } catch (Exception e) {
        throw new MarshalException("Unable to write signature document", e);
    }
    PackagePart sigsPart = pkg.getPart(sigsPartName);
    if (sigsPart == null) {
        // touch empty marker file
        sigsPart = pkg.createPart(sigsPartName, ContentTypes.DIGITAL_SIGNATURE_ORIGIN_PART);
    }
    PackageRelationshipCollection relCol = pkg.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN);
    for (PackageRelationship pr : relCol) {
        pkg.removeRelationship(pr.getId());
    }
    pkg.addRelationship(sigsPartName, TargetMode.INTERNAL, PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN);
    sigsPart.addRelationship(sigPartName, TargetMode.INTERNAL, PackageRelationshipTypes.DIGITAL_SIGNATURE);
}
Also used : PackagePartName(org.apache.poi.openxml4j.opc.PackagePartName) MarshalException(javax.xml.crypto.MarshalException) SignatureDocument(org.w3.x2000.x09.xmldsig.SignatureDocument) HashMap(java.util.HashMap) PackageRelationshipCollection(org.apache.poi.openxml4j.opc.PackageRelationshipCollection) XmlOptions(org.apache.xmlbeans.XmlOptions) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) PackagePart(org.apache.poi.openxml4j.opc.PackagePart) InvalidFormatException(org.apache.poi.openxml4j.exceptions.InvalidFormatException) XPathExpressionException(javax.xml.xpath.XPathExpressionException) GeneralSecurityException(java.security.GeneralSecurityException) InvalidFormatException(org.apache.poi.openxml4j.exceptions.InvalidFormatException) SAXException(org.xml.sax.SAXException) MarshalException(javax.xml.crypto.MarshalException) XMLSignatureException(javax.xml.crypto.dsig.XMLSignatureException) NoSuchElementException(java.util.NoSuchElementException) IOException(java.io.IOException) XmlException(org.apache.xmlbeans.XmlException) EncryptedDocumentException(org.apache.poi.EncryptedDocumentException) PackageRelationship(org.apache.poi.openxml4j.opc.PackageRelationship) Map(java.util.Map) HashMap(java.util.HashMap) OPCPackage(org.apache.poi.openxml4j.opc.OPCPackage)

Aggregations

IOException (java.io.IOException)2 OPCPackage (org.apache.poi.openxml4j.opc.OPCPackage)2 SignatureDocument (org.w3.x2000.x09.xmldsig.SignatureDocument)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 OutputStream (java.io.OutputStream)1 ConnectException (java.net.ConnectException)1 SocketTimeoutException (java.net.SocketTimeoutException)1 GeneralSecurityException (java.security.GeneralSecurityException)1 X509CRL (java.security.cert.X509CRL)1 X509Certificate (java.security.cert.X509Certificate)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 NoSuchElementException (java.util.NoSuchElementException)1 MarshalException (javax.xml.crypto.MarshalException)1 XMLSignatureException (javax.xml.crypto.dsig.XMLSignatureException)1 XPathExpressionException (javax.xml.xpath.XPathExpressionException)1 EncryptedDocumentException (org.apache.poi.EncryptedDocumentException)1 InvalidFormatException (org.apache.poi.openxml4j.exceptions.InvalidFormatException)1