Repository: camel Updated Branches: refs/heads/master 0866d136d -> 23688d3d8
http://git-wip-us.apache.org/repos/asf/camel/blob/23688d3d/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XAdESSignaturePropertiesTest.java ---------------------------------------------------------------------- diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XAdESSignaturePropertiesTest.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XAdESSignaturePropertiesTest.java new file mode 100644 index 0000000..5af5cfc --- /dev/null +++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XAdESSignaturePropertiesTest.java @@ -0,0 +1,922 @@ +/** + * 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. + */ +package org.apache.camel.component.xmlsecurity; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import javax.xml.XMLConstants; +import javax.xml.crypto.dsig.DigestMethod; +import javax.xml.crypto.dsig.XMLSignature; +import javax.xml.crypto.dsig.spec.XPathFilterParameterSpec; +import javax.xml.namespace.NamespaceContext; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + +import org.apache.camel.Exchange; +import org.apache.camel.Message; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.component.xmlsecurity.api.DefaultXAdESSignatureProperties; +import org.apache.camel.component.xmlsecurity.api.XAdESEncapsulatedPKIData; +import org.apache.camel.component.xmlsecurity.api.XAdESSignatureProperties; +import org.apache.camel.component.xmlsecurity.api.XmlSignatureConstants; +import org.apache.camel.component.xmlsecurity.api.XmlSignatureException; +import org.apache.camel.component.xmlsecurity.api.XmlSignatureHelper; +import org.apache.camel.component.xmlsecurity.api.XmlSignatureProperties; +import org.apache.camel.component.xmlsecurity.util.TestKeystore; +import org.apache.camel.impl.JndiRegistry; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Before; +import org.junit.Test; + +import static org.apache.camel.component.xmlsecurity.XmlSignatureTest.checkThrownException; + +public class XAdESSignaturePropertiesTest extends CamelTestSupport { + + private static final String NOT_EMPTY = "NOT_EMPTY"; + private static String payload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root xmlns=\"http://test/test\"><test>Test Message</test></root>"; + + @Before + public void setUp() throws Exception { + disableJMX(); + super.setUp(); + } + + @Override + protected JndiRegistry createRegistry() throws Exception { + JndiRegistry registry = super.createRegistry(); + registry.bind("keyAccessorDefault", TestKeystore.getKeyAccessor("bob")); + registry.bind("xmlSignatureProperties", getXmlSignatureProperties("bob")); + + Map<String, String> namespaceMap = Collections.singletonMap("ns", "http://test"); + List<XPathFilterParameterSpec> xpaths = Collections + .singletonList(XmlSignatureHelper.getXpathFilter("/ns:root/a/@ID", namespaceMap)); + registry.bind("xpathsToIdAttributes", xpaths); + + return registry; + } + + @Override + protected RouteBuilder[] createRouteBuilders() throws Exception { + return new RouteBuilder[] {new RouteBuilder() { + public void configure() throws Exception { + onException(XmlSignatureException.class).handled(true).to("mock:exception"); + from("direct:enveloped") + .to("xmlsecurity:sign://xades?keyAccessor=#keyAccessorDefault&properties=#xmlSignatureProperties&parentLocalName=root&parentNamespace=http://test/test") + .to("mock:result"); + } + }, new RouteBuilder() { + public void configure() throws Exception { + onException(XmlSignatureException.class).handled(true).to("mock:exception"); + from("direct:enveloping").to("xmlsecurity:sign://xades?keyAccessor=#keyAccessorDefault&properties=#xmlSignatureProperties") + .to("mock:result"); + } + }, new RouteBuilder() { + public void configure() throws Exception { + onException(XmlSignatureException.class).handled(true).to("mock:exception"); + from("direct:emptySignatureId").to( + "xmlsecurity:sign://xades?keyAccessor=#keyAccessorDefault&properties=#xmlSignatureProperties&signatureId=").to( + "mock:result"); + } + }, new RouteBuilder() { + public void configure() throws Exception { + onException(Exception.class).handled(false).to("mock:exception"); + from("direct:detached").to( + "xmlsecurity:sign://detached?keyAccessor=#keyAccessorDefault&xpathsToIdAttributes=#xpathsToIdAttributes&"// + + "schemaResourceUri=org/apache/camel/component/xmlsecurity/Test.xsd&properties=#xmlSignatureProperties") + .to("mock:result"); + } + } }; + } + + @Test + public void envelopingAllParameters() throws Exception { + + Document doc = testEnveloping(); + + Map<String, String> prefix2Namespace = getPrefix2NamespaceMap(); + String pathToSignatureProperties = getPathToSignatureProperties(); + // signing time + checkXpath(doc, pathToSignatureProperties + "etsi:SigningTime/text()", prefix2Namespace, NOT_EMPTY); + // signing certificate + checkXpath(doc, pathToSignatureProperties + "etsi:SigningCertificate/etsi:Cert/etsi:CertDigest/ds:DigestMethod/@Algorithm", + prefix2Namespace, DigestMethod.SHA256); + checkXpath(doc, pathToSignatureProperties + "etsi:SigningCertificate/etsi:Cert/etsi:CertDigest/ds:DigestValue/text()", + prefix2Namespace, NOT_EMPTY); + checkXpath(doc, pathToSignatureProperties + "etsi:SigningCertificate/etsi:Cert/etsi:IssuerSerial/ds:X509IssuerName/text()", + prefix2Namespace, NOT_EMPTY); + checkXpath(doc, pathToSignatureProperties + "etsi:SigningCertificate/etsi:Cert/etsi:IssuerSerial/ds:X509SerialNumber/text()", + prefix2Namespace, NOT_EMPTY); + checkXpath(doc, pathToSignatureProperties + "etsi:SigningCertificate/etsi:Cert/@URI", prefix2Namespace, "http://certuri"); + + // signature policy + checkXpath(doc, pathToSignatureProperties + + "etsi:SignaturePolicyIdentifier/etsi:SignaturePolicyId/etsi:SigPolicyId/etsi:Identifier/text()", prefix2Namespace, + "urn:oid:1.2.840.113549.1.9.16.6.1"); + checkXpath(doc, pathToSignatureProperties + + "etsi:SignaturePolicyIdentifier/etsi:SignaturePolicyId/etsi:SigPolicyId/etsi:Identifier/@Qualifier", prefix2Namespace, + "OIDAsURN"); + checkXpath(doc, pathToSignatureProperties + + "etsi:SignaturePolicyIdentifier/etsi:SignaturePolicyId/etsi:SigPolicyId/etsi:Description/text()", prefix2Namespace, + "invoice version 3.1"); + checkXpath(doc, pathToSignatureProperties + + "etsi:SignaturePolicyIdentifier/etsi:SignaturePolicyId/etsi:SigPolicyHash/ds:DigestMethod/@Algorithm", prefix2Namespace, + DigestMethod.SHA256); + checkXpath(doc, pathToSignatureProperties + + "etsi:SignaturePolicyIdentifier/etsi:SignaturePolicyId/etsi:SigPolicyHash/ds:DigestValue/text()", prefix2Namespace, + "Ohixl6upD6av8N7pEvDABhEL6hM="); + checkXpath( + doc, + pathToSignatureProperties + + "etsi:SignaturePolicyIdentifier/etsi:SignaturePolicyId/etsi:SigPolicyQualifiers/etsi:SigPolicyQualifier[1]/etsi:SPURI/text()", + prefix2Namespace, "http://test.com/sig.policy.pdf"); + checkXpath( + doc, + pathToSignatureProperties + + "etsi:SignaturePolicyIdentifier/etsi:SignaturePolicyId/etsi:SigPolicyQualifiers/etsi:SigPolicyQualifier[1]/etsi:SPUserNotice/etsi:ExplicitText/text()", + prefix2Namespace, "display text"); + checkXpath(doc, pathToSignatureProperties + + "etsi:SignaturePolicyIdentifier/etsi:SignaturePolicyId/etsi:SigPolicyQualifiers/etsi:SigPolicyQualifier[2]/text()", + prefix2Namespace, "category B"); + checkXpath( + doc, + pathToSignatureProperties + + "etsi:SignaturePolicyIdentifier/etsi:SignaturePolicyId/etsi:SigPolicyId/etsi:DocumentationReferences/etsi:DocumentationReference[1]/text()", + prefix2Namespace, "http://test.com/policy.doc.ref1.txt"); + checkXpath( + doc, + pathToSignatureProperties + + "etsi:SignaturePolicyIdentifier/etsi:SignaturePolicyId/etsi:SigPolicyId/etsi:DocumentationReferences/etsi:DocumentationReference[2]/text()", + prefix2Namespace, "http://test.com/policy.doc.ref2.txt"); + + // production place + checkXpath(doc, pathToSignatureProperties + "etsi:SignatureProductionPlace/etsi:City/text()", prefix2Namespace, "Munich"); + checkXpath(doc, pathToSignatureProperties + "etsi:SignatureProductionPlace/etsi:StateOrProvince/text()", prefix2Namespace, + "Bavaria"); + checkXpath(doc, pathToSignatureProperties + "etsi:SignatureProductionPlace/etsi:PostalCode/text()", prefix2Namespace, "80331"); + checkXpath(doc, pathToSignatureProperties + "etsi:SignatureProductionPlace/etsi:CountryName/text()", prefix2Namespace, "Germany"); + + // signer role + checkXpath(doc, pathToSignatureProperties + "etsi:SignerRole/etsi:ClaimedRoles/etsi:ClaimedRole[1]/text()", prefix2Namespace, + "test"); + checkXpath(doc, pathToSignatureProperties + "etsi:SignerRole/etsi:ClaimedRoles/etsi:ClaimedRole[2]/TestRole/text()", + prefix2Namespace, "TestRole"); + checkXpath(doc, pathToSignatureProperties + "etsi:SignerRole/etsi:CertifiedRoles/etsi:CertifiedRole/text()", prefix2Namespace, + "Ahixl6upD6av8N7pEvDABhEL6hM="); + checkXpath(doc, pathToSignatureProperties + "etsi:SignerRole/etsi:CertifiedRoles/etsi:CertifiedRole/@Encoding", prefix2Namespace, + "http://uri.etsi.org/01903/v1.2.2#DER"); + checkXpath(doc, pathToSignatureProperties + "etsi:SignerRole/etsi:CertifiedRoles/etsi:CertifiedRole/@Id", prefix2Namespace, + "IdCertifiedRole"); + + String pathToDataObjectProperties = "/ds:Signature/ds:Object/etsi:QualifyingProperties/etsi:SignedProperties/etsi:SignedDataObjectProperties/"; + //DataObjectFormat + checkXpath(doc, pathToDataObjectProperties + "etsi:DataObjectFormat/etsi:Description/text()", prefix2Namespace, "invoice"); + checkXpath(doc, pathToDataObjectProperties + "etsi:DataObjectFormat/etsi:MimeType/text()", prefix2Namespace, "text/xml"); + checkXpath(doc, pathToDataObjectProperties + "etsi:DataObjectFormat/etsi:ObjectIdentifier/etsi:Identifier/text()", + prefix2Namespace, "urn:oid:1.2.840.113549.1.9.16.6.2"); + checkXpath(doc, pathToDataObjectProperties + "etsi:DataObjectFormat/etsi:ObjectIdentifier/etsi:Identifier/@Qualifier", + prefix2Namespace, "OIDAsURN"); + checkXpath(doc, pathToDataObjectProperties + "etsi:DataObjectFormat/etsi:ObjectIdentifier/etsi:Description/text()", + prefix2Namespace, "identifier desc"); + checkXpath(doc, pathToDataObjectProperties + + "etsi:DataObjectFormat/etsi:ObjectIdentifier/etsi:DocumentationReferences/etsi:DocumentationReference[1]/text()", + prefix2Namespace, "http://test.com/dataobject.format.doc.ref1.txt"); + checkXpath(doc, pathToDataObjectProperties + + "etsi:DataObjectFormat/etsi:ObjectIdentifier/etsi:DocumentationReferences/etsi:DocumentationReference[2]/text()", + prefix2Namespace, "http://test.com/dataobject.format.doc.ref2.txt"); + + //commitment + checkXpath(doc, pathToDataObjectProperties + "etsi:CommitmentTypeIndication/etsi:CommitmentTypeId/etsi:Identifier/text()", + prefix2Namespace, "urn:oid:1.2.840.113549.1.9.16.6.4"); + checkXpath(doc, pathToDataObjectProperties + "etsi:CommitmentTypeIndication/etsi:CommitmentTypeId/etsi:Identifier/@Qualifier", + prefix2Namespace, "OIDAsURN"); + checkXpath(doc, pathToDataObjectProperties + "etsi:CommitmentTypeIndication/etsi:CommitmentTypeId/etsi:Description/text()", + prefix2Namespace, "description for commitment type ID"); + checkXpath(doc, pathToDataObjectProperties + + "etsi:CommitmentTypeIndication/etsi:CommitmentTypeId/etsi:DocumentationReferences/etsi:DocumentationReference[1]/text()", + prefix2Namespace, "http://test.com/commitment.ref1.txt"); + checkXpath(doc, pathToDataObjectProperties + + "etsi:CommitmentTypeIndication/etsi:CommitmentTypeId/etsi:DocumentationReferences/etsi:DocumentationReference[2]/text()", + prefix2Namespace, "http://test.com/commitment.ref2.txt"); + checkXpath(doc, pathToDataObjectProperties + + "etsi:CommitmentTypeIndication/etsi:CommitmentTypeQualifiers/etsi:CommitmentTypeQualifier[1]/text()", prefix2Namespace, + "commitment qualifier"); + checkXpath(doc, pathToDataObjectProperties + + "etsi:CommitmentTypeIndication/etsi:CommitmentTypeQualifiers/etsi:CommitmentTypeQualifier[2]/C/text()", prefix2Namespace, + "c"); + } + + @Test + public void noSigningTime() throws Exception { + + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = (XAdESSignatureProperties) endpoint.getProperties(); + props.setAddSigningTime(false); + + Document doc = testEnveloping(); + + Map<String, String> prefix2Namespace = getPrefix2NamespaceMap(); + String pathToSignatureProperties = getPathToSignatureProperties(); + + checkNode(doc, pathToSignatureProperties + "etsi:SigningTime", prefix2Namespace, false); + + } + + @Test + public void noSigningCertificate() throws Exception { + + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties newProps = new XAdESSignatureProperties(); + newProps.setAddSigningTime(true); + endpoint.setProperties(newProps); + + Document doc = testEnveloping(); + + Map<String, String> prefix2Namespace = getPrefix2NamespaceMap(); + String pathToSignatureProperties = getPathToSignatureProperties(); + + checkNode(doc, pathToSignatureProperties + "etsi:SigningTime", prefix2Namespace, true); + + checkNode(doc, pathToSignatureProperties + "etsi:SigningCertificate", prefix2Namespace, false); + } + + @Test + public void certificateChain() throws Exception { + + XmlSignerEndpoint endpoint = getSignerEndpoint(); + endpoint.setProperties(new CertChainXAdESSignatureProperties()); + + Document doc = testEnveloping(); + + Map<String, String> prefix2Namespace = getPrefix2NamespaceMap(); + String pathToSignatureProperties = getPathToSignatureProperties(); + + // signing certificate + checkXpath(doc, pathToSignatureProperties + "etsi:SigningCertificate/etsi:Cert/etsi:CertDigest/ds:DigestMethod/@Algorithm", + prefix2Namespace, DigestMethod.SHA256); + checkXpath(doc, pathToSignatureProperties + "etsi:SigningCertificate/etsi:Cert/etsi:CertDigest/ds:DigestValue/text()", + prefix2Namespace, NOT_EMPTY); + checkXpath(doc, pathToSignatureProperties + "etsi:SigningCertificate/etsi:Cert/etsi:IssuerSerial/ds:X509IssuerName/text()", + prefix2Namespace, NOT_EMPTY); + checkXpath(doc, pathToSignatureProperties + "etsi:SigningCertificate/etsi:Cert/etsi:IssuerSerial/ds:X509SerialNumber/text()", + prefix2Namespace, NOT_EMPTY); + } + + @Test + public void noPropertiesSpecified() throws Exception { + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = new XAdESSignatureProperties(); + props.setAddSigningTime(false); + endpoint.setProperties(props); + Document doc = testEnveloping(); + // expecting no Qualifying Properties + checkNode(doc, "/ds:Signature/ds:Object/etsi:QualifyingProperties", getPrefix2NamespaceMap(), false); + + } + + @Test + public void policyImplied() throws Exception { + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = (XAdESSignatureProperties) endpoint.getProperties(); + props.setSignaturePolicy(XAdESSignatureProperties.SIG_POLICY_IMPLIED); + Document doc = testEnveloping(); + + String pathToSignatureProperties = getPathToSignatureProperties(); + checkNode(doc, pathToSignatureProperties + "etsi:SignaturePolicyIdentifier/etsi:SignaturePolicyId", getPrefix2NamespaceMap(), false); + checkNode(doc, pathToSignatureProperties + "etsi:SignaturePolicyIdentifier/etsi:SignaturePolicyImplied", getPrefix2NamespaceMap(), + true); + } + + @Test + public void policyNone() throws Exception { + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = (XAdESSignatureProperties) endpoint.getProperties(); + props.setSignaturePolicy(XAdESSignatureProperties.SIG_POLICY_NONE); + Document doc = testEnveloping(); + + String pathToSignatureProperties = getPathToSignatureProperties(); + checkNode(doc, pathToSignatureProperties + "etsi:SignaturePolicyIdentifier", getPrefix2NamespaceMap(), false); + } + + @Test + public void allPropertiesEmpty() throws Exception { + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = new XAdESSignatureProperties(); + props.setAddSigningTime(false); + props.setCommitmentTypeId(""); + props.setCommitmentTypeIdDescription(""); + props.setCommitmentTypeIdQualifier(""); + props.setDataObjectFormatDescription(""); + props.setDataObjectFormatIdentifier(""); + props.setDataObjectFormatIdentifierDescription(""); + props.setDataObjectFormatIdentifierQualifier(""); + props.setDataObjectFormatMimeType(""); + props.setDigestAlgorithmForSigningCertificate(""); + props.setSignaturePolicy("None"); + props.setSigPolicyId(""); + props.setSigPolicyIdDescription(""); + props.setSigPolicyIdQualifier(""); + props.setSignaturePolicyDigestAlgorithm(""); + props.setSignaturePolicyDigestValue(""); + props.setSignatureProductionPlaceCity(""); + props.setSignatureProductionPlaceCountryName(""); + props.setSignatureProductionPlacePostalCode(""); + props.setSignatureProductionPlaceStateOrProvince(""); + + endpoint.setProperties(props); + Document doc = testEnveloping(); + // expecting no Qualifying Properties + checkNode(doc, "/ds:Signature/ds:Object/etsi:QualifyingProperties", getPrefix2NamespaceMap(), false); + + } + + @Test + public void emptySignatureId() throws Exception { + Document doc = testEnveloping("direct:emptySignatureId"); + checkNode(doc, "/ds:Signature/ds:Object/etsi:QualifyingProperties", getPrefix2NamespaceMap(), true); + } + + @Test + public void prefixAndNamespace() throws Exception { + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = (XAdESSignatureProperties) endpoint.getProperties(); + props.setPrefix("p"); + props.setNamespace(XAdESSignatureProperties.HTTP_URI_ETSI_ORG_01903_V1_1_1); + props.setCommitmentTypeIdDescription(null); + props.setCommitmentTypeIdDocumentationReferences(Collections.<String> emptyList()); + props.setCommitmentTypeIdQualifier(null); + props.setDataObjectFormatIdentifierDescription(null); + props.setDataObjectFormatIdentifierDocumentationReferences(Collections.<String> emptyList()); + props.setDataObjectFormatIdentifierQualifier(null); + props.setSigPolicyIdDescription(null); + props.setSigPolicyIdDocumentationReferences(Collections.<String> emptyList()); + props.setSigPolicyIdQualifier(null); + // the following lists must be set to empty because otherwise they would contain XML fragments with a wrong namespace + props.setSigPolicyQualifiers(Collections.<String> emptyList()); + props.setSignerClaimedRoles(Collections.<String> emptyList()); + props.setCommitmentTypeQualifiers(Collections.<String> emptyList()); + + Document doc = testEnveloping(); + + Map<String, String> prefix2Namespace = new TreeMap<String, String>(); + prefix2Namespace.put("ds", XMLSignature.XMLNS); + prefix2Namespace.put("etsi", XAdESSignatureProperties.HTTP_URI_ETSI_ORG_01903_V1_1_1); + + XPathExpression expr = getXpath("/ds:Signature/ds:Object/etsi:QualifyingProperties", prefix2Namespace); + Object result = expr.evaluate(doc, XPathConstants.NODE); + assertNotNull(result); + Node node = (Node) result; + assertEquals("p", node.getPrefix()); + assertEquals(XAdESSignatureProperties.HTTP_URI_ETSI_ORG_01903_V1_1_1, node.getNamespaceURI()); + } + + @Test + public void headers() throws Exception { + Map<String, Object> header = new TreeMap<String, Object>(); + + header.put(XmlSignatureConstants.HEADER_XADES_PREFIX, "ns1"); + header.put(XmlSignatureConstants.HEADER_XADES_NAMESPACE, XAdESSignatureProperties.HTTP_URI_ETSI_ORG_01903_V1_2_2); + + header.put(XmlSignatureConstants.HEADER_XADES_QUALIFYING_PROPERTIES_ID, "QualId"); + header.put(XmlSignatureConstants.HEADER_XADES_SIGNED_DATA_OBJECT_PROPERTIES_ID, "ObjId"); + header.put(XmlSignatureConstants.HEADER_XADES_SIGNED_SIGNATURE_PROPERTIES_ID, "SigId"); + header.put(XmlSignatureConstants.HEADER_XADES_DATA_OBJECT_FORMAT_ENCODING, "base64"); + + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = (XAdESSignatureProperties) endpoint.getProperties(); + // the following lists must be set to empty because otherwise they would contain XML fragments with a wrong namespace + props.setSigPolicyQualifiers(Collections.<String> emptyList()); + props.setSignerClaimedRoles(Collections.<String> emptyList()); + props.setCommitmentTypeQualifiers(Collections.<String> emptyList()); + + Document doc = testEnveloping("direct:enveloping", header); + + Map<String, String> prefix2Namespace = new TreeMap<String, String>(); + prefix2Namespace.put("ds", XMLSignature.XMLNS); + prefix2Namespace.put("etsi", XAdESSignatureProperties.HTTP_URI_ETSI_ORG_01903_V1_2_2); + + XPathExpression expr = getXpath("/ds:Signature/ds:Object/etsi:QualifyingProperties", prefix2Namespace); + Object result = expr.evaluate(doc, XPathConstants.NODE); + assertNotNull(result); + Node node = (Node) result; + assertEquals("ns1", node.getPrefix()); + assertEquals(XAdESSignatureProperties.HTTP_URI_ETSI_ORG_01903_V1_2_2, node.getNamespaceURI()); + + checkXpath(doc, "/ds:Signature/ds:Object/etsi:QualifyingProperties/@Id", prefix2Namespace, "QualId"); + + checkXpath(doc, "/ds:Signature/ds:Object/etsi:QualifyingProperties/etsi:SignedProperties/etsi:SignedDataObjectProperties/@Id", + prefix2Namespace, "ObjId"); + + checkXpath(doc, "/ds:Signature/ds:Object/etsi:QualifyingProperties/etsi:SignedProperties/etsi:SignedSignatureProperties/@Id", + prefix2Namespace, "SigId"); + + checkXpath( + doc, + "/ds:Signature/ds:Object/etsi:QualifyingProperties/etsi:SignedProperties/etsi:SignedDataObjectProperties/etsi:DataObjectFormat/etsi:Encoding/text()", + prefix2Namespace, "base64"); + + } + + @Test + public void enveloped() throws Exception { + setupMock(); + sendBody("direct:enveloped", payload); + assertMockEndpointsSatisfied(); + } + + @Test + public void detached() throws Exception { + String detachedPayload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + // + "<ns:root xmlns:ns=\"http://test\"><a ID=\"myID\"><b>bValue</b></a></ns:root>"; + setupMock(); + sendBody("direct:detached", detachedPayload); + assertMockEndpointsSatisfied(); + } + + @Test + public void sigPolicyIdEmpty() throws Exception { + testExceptionSigPolicyIdMissing(""); + } + + @Test + public void sigPolicyIdNull() throws Exception { + testExceptionSigPolicyIdMissing(null); + } + + private void testExceptionSigPolicyIdMissing(String value) throws InterruptedException, Exception { + MockEndpoint mock = getMockEndpoint("mock:exception"); + mock.expectedMessageCount(1); + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = (XAdESSignatureProperties) endpoint.getProperties(); + props.setSigPolicyId(value); + sendBody("direct:enveloping", payload, Collections.<String, Object> emptyMap()); + assertMockEndpointsSatisfied(); + checkThrownException(mock, XmlSignatureException.class, + "The XAdES-EPES confguration is invalid. The signature policy identifier is missing.", null); + } + + @Test + public void sigPolicyDigestEmpty() throws Exception { + testExceptionSigPolicyDigestMissing(""); + } + + @Test + public void sigPolicyDigestNull() throws Exception { + testExceptionSigPolicyDigestMissing(null); + } + + private void testExceptionSigPolicyDigestMissing(String value) throws InterruptedException, Exception { + MockEndpoint mock = getMockEndpoint("mock:exception"); + mock.expectedMessageCount(1); + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = (XAdESSignatureProperties) endpoint.getProperties(); + props.setSignaturePolicyDigestValue(value); + sendBody("direct:enveloping", payload, Collections.<String, Object> emptyMap()); + assertMockEndpointsSatisfied(); + checkThrownException(mock, XmlSignatureException.class, + "The XAdES-EPES confguration is invalid. The digest value for the signature policy is missing.", null); + } + + @Test + public void sigPolicyDigestAlgoEmpty() throws Exception { + testExceptionSigPolicyDigestAlgoMissing(""); + } + + @Test + public void sigPolicyDigestAlgoNull() throws Exception { + testExceptionSigPolicyDigestAlgoMissing(null); + } + + private void testExceptionSigPolicyDigestAlgoMissing(String value) throws InterruptedException, Exception { + MockEndpoint mock = getMockEndpoint("mock:exception"); + mock.expectedMessageCount(1); + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = (XAdESSignatureProperties) endpoint.getProperties(); + props.setSignaturePolicyDigestAlgorithm(value); + sendBody("direct:enveloping", payload, Collections.<String, Object> emptyMap()); + assertMockEndpointsSatisfied(); + checkThrownException(mock, XmlSignatureException.class, + "The XAdES-EPES confguration is invalid. The digest algorithm for the signature policy is missing.", null); + } + + @Test + public void invalidXmlFragmentForClaimedRole() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:exception"); + mock.expectedMessageCount(1); + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = (XAdESSignatureProperties) endpoint.getProperties(); + props.setSignerClaimedRoles(Collections.singletonList("<ClaimedRole>wrong XML fragment<ClaimedRole>")); // Element 'ClaimedRole' is not closed correctly + sendBody("direct:enveloping", payload, Collections.<String, Object> emptyMap()); + assertMockEndpointsSatisfied(); + checkThrownException( + mock, + XmlSignatureException.class, + "The XAdES confguration is invalid. The list of the claimed roles contains the invalid entry '<ClaimedRole>wrong XML fragment<ClaimedRole>'. An entry must either be a text or" + + " an XML fragment with the root element 'ClaimedRole' with the namespace 'http://uri.etsi.org/01903/v1.3.2#'.", + null); + } + + @Test + public void invalidXmlFragmentForCommitmentTypeQualifier() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:exception"); + mock.expectedMessageCount(1); + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = (XAdESSignatureProperties) endpoint.getProperties(); + props.setCommitmentTypeQualifiers(Collections.singletonList("<CommitmentTypeQualifier>wrong XML fragment<CommitmentTypeQualifier>")); // end tag is not correct + sendBody("direct:enveloping", payload, Collections.<String, Object> emptyMap()); + assertMockEndpointsSatisfied(); + checkThrownException( + mock, + XmlSignatureException.class, + "The XAdES confguration is invalid. The list of the commitment type qualifiers contains the invalid entry '<CommitmentTypeQualifier>wrong XML fragment<CommitmentTypeQualifier>'." + + " An entry must either be a text or an XML fragment with the root element 'CommitmentTypeQualifier' with the namespace 'http://uri.etsi.org/01903/v1.3.2#'.", + null); + } + + @Test + public void invalidXmlFragmentForSigPolicyQualifier() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:exception"); + mock.expectedMessageCount(1); + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = (XAdESSignatureProperties) endpoint.getProperties(); + props.setSigPolicyQualifiers(Collections.singletonList("<SigPolicyQualifier>wrong XML fragment<SigPolicyQualifier>")); // end tag is not correct + sendBody("direct:enveloping", payload, Collections.<String, Object> emptyMap()); + assertMockEndpointsSatisfied(); + checkThrownException( + mock, + XmlSignatureException.class, + "The XAdES confguration is invalid. The list of the signatue policy qualifiers contains the invalid entry '<SigPolicyQualifier>wrong XML fragment<SigPolicyQualifier>'." + + " An entry must either be a text or an XML fragment with the root element 'SigPolicyQualifier' with the namespace 'http://uri.etsi.org/01903/v1.3.2#'.", + null); + } + + @Test + public void invalidNamespaceForTheRootElementInXmlFragmentForSigPolicyQualifier() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:exception"); + mock.expectedMessageCount(1); + XmlSignerEndpoint endpoint = getSignerEndpoint(); + XAdESSignatureProperties props = (XAdESSignatureProperties) endpoint.getProperties(); + props.setSigPolicyQualifiers(Collections + .singletonList("<SigPolicyQualifier xmlns=\"http://invalid.com\">XML fragment with wrong namespace for root element</SigPolicyQualifier>")); + sendBody("direct:enveloping", payload, Collections.<String, Object> emptyMap()); + assertMockEndpointsSatisfied(); + checkThrownException( + mock, + XmlSignatureException.class, + "The XAdES confguration is invalid. The root element 'SigPolicyQualifier' of the provided XML fragment " + + "'<SigPolicyQualifier xmlns=\"http://invalid.com\">XML fragment with wrong namespace for root element</SigPolicyQualifier>' has the invalid namespace 'http://invalid.com'." + + " The correct namespace is 'http://uri.etsi.org/01903/v1.3.2#'.", null); + } + + @Test(expected = IllegalArgumentException.class) + public void namespaceNull() throws Exception { + new XAdESSignatureProperties().setNamespace(null); + } + + @Test(expected = IllegalArgumentException.class) + public void signingCertificateURIsNull() throws Exception { + new XAdESSignatureProperties().setSigningCertificateURIs(null); + } + + @Test(expected = IllegalArgumentException.class) + public void sigPolicyInvalid() throws Exception { + new XAdESSignatureProperties().setSignaturePolicy("invalid"); + } + + @Test(expected = IllegalArgumentException.class) + public void sigPolicyIdDocumentationReferencesNull() throws Exception { + new XAdESSignatureProperties().setSigPolicyIdDocumentationReferences(null); + } + + @Test(expected = IllegalArgumentException.class) + public void sigPolicyIdDocumentationReferencesNullEntry() throws Exception { + new XAdESSignatureProperties().setSigPolicyIdDocumentationReferences(Collections.<String> singletonList(null)); + } + + @Test(expected = IllegalArgumentException.class) + public void sigPolicyIdDocumentationReferencesEmptyEntry() throws Exception { + new XAdESSignatureProperties().setSigPolicyIdDocumentationReferences(Collections.<String> singletonList("")); + } + + @Test(expected = IllegalArgumentException.class) + public void dataObjectFormatIdentifierDocumentationReferencesNull() throws Exception { + new XAdESSignatureProperties().setDataObjectFormatIdentifierDocumentationReferences(null); + } + + @Test(expected = IllegalArgumentException.class) + public void dataObjectFormatIdentifierDocumentationReferencesNullEntry() throws Exception { + new XAdESSignatureProperties().setDataObjectFormatIdentifierDocumentationReferences(Collections.<String> singletonList(null)); + } + + @Test(expected = IllegalArgumentException.class) + public void dataObjectFormatIdentifierDocumentationReferencesEmptyEntry() throws Exception { + new XAdESSignatureProperties().setDataObjectFormatIdentifierDocumentationReferences(Collections.<String> singletonList("")); + } + + @Test(expected = IllegalArgumentException.class) + public void signerClaimedRolesNull() throws Exception { + new XAdESSignatureProperties().setSignerClaimedRoles(null); + } + + @Test(expected = IllegalArgumentException.class) + public void signerClaimedRolesNullEntry() throws Exception { + new XAdESSignatureProperties().setSignerClaimedRoles(Collections.<String> singletonList(null)); + } + + @Test(expected = IllegalArgumentException.class) + public void signerClaimedRolesEmptyEntry() throws Exception { + new XAdESSignatureProperties().setSignerClaimedRoles(Collections.<String> singletonList("")); + } + + @Test(expected = IllegalArgumentException.class) + public void signerCertifiedRolesNull() throws Exception { + new XAdESSignatureProperties().setSignerCertifiedRoles(null); + } + + @Test(expected = IllegalArgumentException.class) + public void signerCertifiedRolesNullEntry() throws Exception { + new XAdESSignatureProperties().setSignerCertifiedRoles(Collections.<XAdESEncapsulatedPKIData> singletonList(null)); + } + + @Test(expected = IllegalArgumentException.class) + public void commitmentTypeIdDocumentationReferencesNull() throws Exception { + new XAdESSignatureProperties().setCommitmentTypeIdDocumentationReferences(null); + } + + @Test(expected = IllegalArgumentException.class) + public void commitmentTypeIdDocumentationReferencesNullEntry() throws Exception { + new XAdESSignatureProperties().setCommitmentTypeIdDocumentationReferences(Collections.<String> singletonList(null)); + } + + @Test(expected = IllegalArgumentException.class) + public void commitmentTypeIdDocumentationReferencesEmptyEntry() throws Exception { + new XAdESSignatureProperties().setCommitmentTypeIdDocumentationReferences(Collections.<String> singletonList("")); + } + + @Test(expected = IllegalArgumentException.class) + public void commitmentTypeQualifiersNull() throws Exception { + new XAdESSignatureProperties().setCommitmentTypeQualifiers(null); + } + + @Test(expected = IllegalArgumentException.class) + public void commitmentTypeQualifiersNullEntry() throws Exception { + new XAdESSignatureProperties().setCommitmentTypeQualifiers(Collections.<String> singletonList(null)); + } + + @Test(expected = IllegalArgumentException.class) + public void commitmentTypeQualifiersEmptyEntry() throws Exception { + new XAdESSignatureProperties().setCommitmentTypeQualifiers(Collections.<String> singletonList("")); + } + + // + + private XmlSignerEndpoint getSignerEndpoint() { + return (XmlSignerEndpoint) context().getEndpoint( + "xmlsecurity:sign://xades?keyAccessor=#keyAccessorDefault&properties=#xmlSignatureProperties"); + } + + private String getPathToSignatureProperties() { + return "/ds:Signature/ds:Object/etsi:QualifyingProperties/etsi:SignedProperties/etsi:SignedSignatureProperties/"; + } + + static Map<String, String> getPrefix2NamespaceMap() { + Map<String, String> prefix2Namespace = new TreeMap<String, String>(); + prefix2Namespace.put("ds", XMLSignature.XMLNS); + prefix2Namespace.put("etsi", XAdESSignatureProperties.HTTP_URI_ETSI_ORG_01903_V1_3_2); + return prefix2Namespace; + } + + private Document testEnveloping() throws InterruptedException, SAXException, IOException, ParserConfigurationException, Exception { + return testEnveloping("direct:enveloping"); + } + + protected Document testEnveloping(String fromUri) throws InterruptedException, SAXException, IOException, ParserConfigurationException, + Exception { + return testEnveloping(fromUri, Collections.<String, Object> emptyMap()); + } + + protected Document testEnveloping(String fromUri, Map<String, Object> headers) throws InterruptedException, SAXException, IOException, + ParserConfigurationException, Exception { + MockEndpoint mock = setupMock(); + sendBody(fromUri, payload, headers); + assertMockEndpointsSatisfied(); + Message message = getMessage(mock); + byte[] body = message.getBody(byte[].class); + Document doc = XmlSignatureHelper.newDocumentBuilder(true).parse(new ByteArrayInputStream(body)); + validateAgainstSchema(doc); + return doc; + } + + private MockEndpoint setupMock() { + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedMessageCount(1); + return mock; + } + + private static XmlSignatureProperties getXmlSignatureProperties(String alias) throws IOException, GeneralSecurityException { + DefaultXAdESSignatureProperties props = new DefaultXAdESSignatureProperties(); + props.setKeystore(TestKeystore.getKeyStore()); + props.setAlias(alias); + props.setAddSigningTime(true); + props.setDigestAlgorithmForSigningCertificate(DigestMethod.SHA256); + props.setSigningCertificateURIs(Collections.singletonList("http://certuri")); + + // policy + props.setSignaturePolicy(XAdESSignatureProperties.SIG_POLICY_EXPLICIT_ID); + props.setSigPolicyId("urn:oid:1.2.840.113549.1.9.16.6.1"); + props.setSigPolicyIdQualifier("OIDAsURN"); + props.setSigPolicyIdDescription("invoice version 3.1"); + props.setSignaturePolicyDigestAlgorithm(DigestMethod.SHA256); + props.setSignaturePolicyDigestValue("Ohixl6upD6av8N7pEvDABhEL6hM="); + props.setSigPolicyQualifiers(Arrays + .asList(new String[] { + "<SigPolicyQualifier xmlns=\"http://uri.etsi.org/01903/v1.3.2#\"><SPURI>http://test.com/sig.policy.pdf</SPURI><SPUserNotice><ExplicitText>display text</ExplicitText>" + + "</SPUserNotice></SigPolicyQualifier>", "category B" })); + props.setSigPolicyIdDocumentationReferences(Arrays.asList(new String[] {"http://test.com/policy.doc.ref1.txt", + "http://test.com/policy.doc.ref2.txt" })); + // production place + props.setSignatureProductionPlaceCity("Munich"); + props.setSignatureProductionPlaceCountryName("Germany"); + props.setSignatureProductionPlacePostalCode("80331"); + props.setSignatureProductionPlaceStateOrProvince("Bavaria"); + + //role + props.setSignerClaimedRoles(Arrays.asList(new String[] {"test", + "<a:ClaimedRole xmlns:a=\"http://uri.etsi.org/01903/v1.3.2#\"><TestRole>TestRole</TestRole></a:ClaimedRole>" })); + props.setSignerCertifiedRoles(Collections.singletonList(new XAdESEncapsulatedPKIData("Ahixl6upD6av8N7pEvDABhEL6hM=", + "http://uri.etsi.org/01903/v1.2.2#DER", "IdCertifiedRole"))); + + // data object format + props.setDataObjectFormatDescription("invoice"); + props.setDataObjectFormatMimeType("text/xml"); + props.setDataObjectFormatIdentifier("urn:oid:1.2.840.113549.1.9.16.6.2"); + props.setDataObjectFormatIdentifierQualifier("OIDAsURN"); + props.setDataObjectFormatIdentifierDescription("identifier desc"); + props.setDataObjectFormatIdentifierDocumentationReferences(Arrays.asList(new String[] { + "http://test.com/dataobject.format.doc.ref1.txt", "http://test.com/dataobject.format.doc.ref2.txt" })); + + //commitment + props.setCommitmentTypeId("urn:oid:1.2.840.113549.1.9.16.6.4"); + props.setCommitmentTypeIdQualifier("OIDAsURN"); + props.setCommitmentTypeIdDescription("description for commitment type ID"); + props.setCommitmentTypeIdDocumentationReferences(Arrays.asList(new String[] {"http://test.com/commitment.ref1.txt", + "http://test.com/commitment.ref2.txt" })); + props.setCommitmentTypeQualifiers(Arrays.asList(new String[] {"commitment qualifier", + "<c:CommitmentTypeQualifier xmlns:c=\"http://uri.etsi.org/01903/v1.3.2#\"><C>c</C></c:CommitmentTypeQualifier>" })); + return props; + } + + private void validateAgainstSchema(Document doc) throws Exception { + + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + + Source schema1 = new StreamSource(new File("target/test-classes/org/apache/camel/component/xmlsecurity/xades/XAdES.xsd")); + Source schema2 = new StreamSource(new File( + "target/test-classes/org/apache/camel/component/xmlsecurity/xades/xmldsig-core-schema.xsd")); + Schema schema = factory.newSchema(new Source[] {schema2, schema1 }); + + Validator validator = schema.newValidator(); + + validator.validate(new DOMSource(doc)); + + } + + static void checkXpath(Document doc, String xpathString, final Map<String, String> prefix2Namespace, String expectedResult) + throws XPathExpressionException { + + XPathExpression expr = getXpath(xpathString, prefix2Namespace); + String result = (String) expr.evaluate(doc, XPathConstants.STRING); + assertNotNull("The xpath " + xpathString + " returned a null value", result); + if (NOT_EMPTY.equals(expectedResult)) { + assertTrue("Not empty result for xpath " + xpathString + " expected", !result.isEmpty()); + } else { + assertEquals(expectedResult, result); + } + } + + private void checkNode(Document doc, String xpathString, final Map<String, String> prefix2Namespace, boolean exists) + throws XPathExpressionException { + + XPathExpression expr = getXpath(xpathString, prefix2Namespace); + Object result = expr.evaluate(doc, XPathConstants.NODE); + if (exists) { + assertNotNull("The xpath " + xpathString + " returned null, expected was a node", result); + } else { + assertNull("The xpath " + xpathString + " returned a node, expected was none: ", result); + } + } + + static XPathExpression getXpath(String xpathString, final Map<String, String> prefix2Namespace) throws XPathExpressionException { + XPathFactory xpathFactory = XPathFactory.newInstance(); + XPath xpath = xpathFactory.newXPath(); + NamespaceContext nc = new NamespaceContext() { + + @SuppressWarnings("rawtypes") + @Override + public Iterator getPrefixes(String namespaceURI) { + return null; + } + + @Override + public String getPrefix(String namespaceURI) { + return null; + } + + @Override + public String getNamespaceURI(String prefix) { + return prefix2Namespace.get(prefix); + } + }; + xpath.setNamespaceContext(nc); + XPathExpression expr = xpath.compile(xpathString); + return expr; + } + + private Message getMessage(MockEndpoint mock) { + List<Exchange> exs = mock.getExchanges(); + assertNotNull(exs); + assertEquals(1, exs.size()); + Exchange ex = exs.get(0); + Message mess = ex.getIn(); + assertNotNull(mess); + return mess; + } + + private static class CertChainXAdESSignatureProperties extends XAdESSignatureProperties { + + private KeyStore keystore = getKeystore(); + + private String alias = "bob"; + + public CertChainXAdESSignatureProperties() { + setAddSigningTime(false); + } + + @Override + protected X509Certificate getSigningCertificate() throws Exception { //NOPMD + return null; + } + + @Override + protected X509Certificate[] getSigningCertificateChain() throws Exception { //NOPMD + Certificate[] certs = keystore.getCertificateChain(alias); + X509Certificate[] result = new X509Certificate[certs.length]; + int counter = 0; + for (Certificate cert : certs) { + result[counter] = (X509Certificate) cert; + counter++; + } + return result; + } + + private static KeyStore getKeystore() { + + try { + return TestKeystore.getKeyStore(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/23688d3d/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java ---------------------------------------------------------------------- diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java index a9cda7c..0cac769 100644 --- a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java +++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/XmlSignatureTest.java @@ -103,7 +103,7 @@ import org.junit.Test; public class XmlSignatureTest extends CamelTestSupport { - private static String payload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + protected static String payload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<root xmlns=\"http://test/test\"><test>Test Message</test></root>"; private KeyPair keyPair; @@ -1254,7 +1254,7 @@ public class XmlSignatureTest extends CamelTestSupport { return result; } - private Message getMessage(MockEndpoint mock) { + Message getMessage(MockEndpoint mock) { List<Exchange> exs = mock.getExchanges(); assertNotNull(exs); assertEquals(1, exs.size()); @@ -1269,7 +1269,7 @@ public class XmlSignatureTest extends CamelTestSupport { checkThrownException(mock, cl, null, expectedCauseClass); } - private void checkThrownException(MockEndpoint mock, Class<? extends Exception> cl, String expectedMessage, + static void checkThrownException(MockEndpoint mock, Class<? extends Exception> cl, String expectedMessage, Class<? extends Exception> expectedCauseClass) throws Exception { Exception e = (Exception) mock.getExchanges().get(0).getProperty(Exchange.EXCEPTION_CAUGHT); assertNotNull("Expected excpetion " + cl.getName() + " missing", e); @@ -1290,7 +1290,7 @@ public class XmlSignatureTest extends CamelTestSupport { } } - private String getStrackTrace(Exception e) throws UnsupportedEncodingException { + private static String getStrackTrace(Exception e) throws UnsupportedEncodingException { ByteArrayOutputStream os = new ByteArrayOutputStream(); PrintWriter w = new PrintWriter(os); e.printStackTrace(w); http://git-wip-us.apache.org/repos/asf/camel/blob/23688d3d/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java ---------------------------------------------------------------------- diff --git a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java index 487ea42..54beee2 100644 --- a/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java +++ b/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/util/TestKeystore.java @@ -54,7 +54,7 @@ public final class TestKeystore { return "abcd1234".toCharArray(); } - private static KeyStore getKeyStore() throws GeneralSecurityException, IOException { + public static KeyStore getKeyStore() throws GeneralSecurityException, IOException { KeyStore ks = KeyStore.getInstance("JKS"); InputStream is = TestKeystore.class.getClassLoader().getResourceAsStream("org/apache/camel/component/xmlsecurity/keystore.jks"); http://git-wip-us.apache.org/repos/asf/camel/blob/23688d3d/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTests.xml ---------------------------------------------------------------------- diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTests.xml b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTests.xml index 53443a0..6ba4920 100644 --- a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTests.xml +++ b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/SpringXmlSignatureTests.xml @@ -283,6 +283,15 @@ </route> <!-- END SNIPPET: enveloped XML signature with parent XPath --> + <!-- START SNIPPET: xades --> + <route> + <from uri="direct:xades" /> + <to + uri="xmlsecurity:sign://xades?keyAccessor=#accessorRsa&properties=#xadesProperties" /> + <to uri="mock:result" /> + </route> + <!-- END SNIPPET: xades --> + </camelContext> <bean id="accessorDsa" @@ -452,4 +461,28 @@ <bean id="parentXpathBean" class="org.apache.camel.component.xmlsecurity.SpringXmlSignatureTest" factory-method="getParentXPathBean" /> + + <bean id="xadesProperties" + class="org.apache.camel.component.xmlsecurity.api.XAdESSignatureProperties"> + <property name="signaturePolicy" value="ExplicitId" /> + <property name="sigPolicyId" value="http://www.test.com/policy.pdf" /> + <property name="sigPolicyIdDescription" value="factura" /> + <property name="signaturePolicyDigestAlgorithm" value="http://www.w3.org/2000/09/xmldsig#sha1" /> + <property name="signaturePolicyDigestValue" value="Ohixl6upD6av8N7pEvDABhEL1hM=" /> + <property name="signerClaimedRoles" ref="signerClaimedRoles_XMLSigner" /> + <property name="dataObjectFormatDescription" value="Factura electrónica" /> + <property name="dataObjectFormatMimeType" value="text/xml" /> + </bean> + + <bean class="java.util.ArrayList" id="signerClaimedRoles_XMLSigner"> + <constructor-arg> + <list> + <value>Emisor</value> + <value><ClaimedRole + xmlns="http://uri.etsi.org/01903/v1.3.2#"><test + xmlns="http://test.com/">test</test></ClaimedRole></value> + </list> + </constructor-arg> + </bean> + </beans> http://git-wip-us.apache.org/repos/asf/camel/blob/23688d3d/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xades/XAdES.xsd ---------------------------------------------------------------------- diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xades/XAdES.xsd b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xades/XAdES.xsd new file mode 100644 index 0000000..b056915 --- /dev/null +++ b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xades/XAdES.xsd @@ -0,0 +1,466 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsd:schema targetNamespace="http://uri.etsi.org/01903/v1.3.2#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://uri.etsi.org/01903/v1.3.2#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" elementFormDefault="qualified"> + <xsd:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/> + <!-- Start auxiliary types definitions: AnyType, ObjectIdentifierType, +EncapsulatedPKIDataType and containers for time-stamp tokens --> + <!-- Start AnyType --> + <xsd:element name="Any" type="AnyType"/> + <xsd:complexType name="AnyType" mixed="true"> + <xsd:sequence minOccurs="0" maxOccurs="unbounded"> + <xsd:any namespace="##any" processContents="lax"/> + </xsd:sequence> + <xsd:anyAttribute namespace="##any"/> + </xsd:complexType> + <!-- End AnyType --> + <!-- Start ObjectIdentifierType--> + <xsd:element name="ObjectIdentifier" type="ObjectIdentifierType"/> + <xsd:complexType name="ObjectIdentifierType"> + <xsd:sequence> + <xsd:element name="Identifier" type="IdentifierType"/> + <xsd:element name="Description" type="xsd:string" minOccurs="0"/> + <xsd:element name="DocumentationReferences" type="DocumentationReferencesType" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="IdentifierType"> + <xsd:simpleContent> + <xsd:extension base="xsd:anyURI"> + <xsd:attribute name="Qualifier" type="QualifierType" use="optional"/> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + <xsd:simpleType name="QualifierType"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="OIDAsURI"/> + <xsd:enumeration value="OIDAsURN"/> + </xsd:restriction> + </xsd:simpleType> + <xsd:complexType name="DocumentationReferencesType"> + <xsd:sequence maxOccurs="unbounded"> + <xsd:element name="DocumentationReference" type="xsd:anyURI"/> + </xsd:sequence> + </xsd:complexType> + <!-- End ObjectIdentifierType--> + <!-- Start EncapsulatedPKIDataType--> + <xsd:element name="EncapsulatedPKIData" type="EncapsulatedPKIDataType"/> + <xsd:complexType name="EncapsulatedPKIDataType"> + <xsd:simpleContent> + <xsd:extension base="xsd:base64Binary"> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + <xsd:attribute name="Encoding" type="xsd:anyURI" use="optional"/> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + <!-- End EncapsulatedPKIDataType --> + <!-- Start time-stamp containers types --> + <!-- Start GenericTimeStampType --> + <xsd:element name="Include" type="IncludeType"/> + <xsd:complexType name="IncludeType"> + <xsd:attribute name="URI" type="xsd:anyURI" use="required"/> + <xsd:attribute name="referencedData" type="xsd:boolean" use="optional"/> + </xsd:complexType> + <xsd:element name="ReferenceInfo" type="ReferenceInfoType"/> + <xsd:complexType name="ReferenceInfoType"> + <xsd:sequence> + <xsd:element ref="ds:DigestMethod"/> + <xsd:element ref="ds:DigestValue"/> + </xsd:sequence> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + <xsd:attribute name="URI" type="xsd:anyURI" use="optional"/> + </xsd:complexType> + <xsd:complexType name="GenericTimeStampType" abstract="true"> + <xsd:sequence> + <xsd:choice minOccurs="0"> + <xsd:element ref="Include" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element ref="ReferenceInfo" maxOccurs="unbounded"/> + </xsd:choice> + <xsd:element ref="ds:CanonicalizationMethod" minOccurs="0"/> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="EncapsulatedTimeStamp" type="EncapsulatedPKIDataType"/> + <xsd:element name="XMLTimeStamp" type="AnyType"/> + </xsd:choice> + </xsd:sequence> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <!-- End GenericTimeStampType --> + <!-- Start XAdESTimeStampType --> + <xsd:element name="XAdESTimeStamp" type="XAdESTimeStampType"/> + <xsd:complexType name="XAdESTimeStampType"> + <xsd:complexContent> + <xsd:restriction base="GenericTimeStampType"> + <xsd:sequence> + <xsd:element ref="Include" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element ref="ds:CanonicalizationMethod" minOccurs="0"/> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="EncapsulatedTimeStamp" type="EncapsulatedPKIDataType"/> + <xsd:element name="XMLTimeStamp" type="AnyType"/> + </xsd:choice> + </xsd:sequence> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:restriction> + </xsd:complexContent> + </xsd:complexType> + <!-- End XAdESTimeStampType --> + <!-- Start OtherTimeStampType --> + <xsd:element name="OtherTimeStamp" type="OtherTimeStampType"/> + <xsd:complexType name="OtherTimeStampType"> + <xsd:complexContent> + <xsd:restriction base="GenericTimeStampType"> + <xsd:sequence> + <xsd:element ref="ReferenceInfo" maxOccurs="unbounded"/> + <xsd:element ref="ds:CanonicalizationMethod" minOccurs="0"/> + <xsd:choice> + <xsd:element name="EncapsulatedTimeStamp" type="EncapsulatedPKIDataType"/> + <xsd:element name="XMLTimeStamp" type="AnyType"/> + </xsd:choice> + </xsd:sequence> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:restriction> + </xsd:complexContent> + </xsd:complexType> + <!-- End OtherTimeStampType --> + <!-- End time-stamp containers types --> + <!-- End auxiliary types definitions--> + <!-- Start container types --> + <!-- Start QualifyingProperties --> + <xsd:element name="QualifyingProperties" type="QualifyingPropertiesType"/> + <xsd:complexType name="QualifyingPropertiesType"> + <xsd:sequence> + <xsd:element name="SignedProperties" type="SignedPropertiesType" minOccurs="0"/> + <xsd:element name="UnsignedProperties" type="UnsignedPropertiesType" minOccurs="0"/> + </xsd:sequence> + <xsd:attribute name="Target" type="xsd:anyURI" use="required"/> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <!-- End QualifyingProperties --> + <!-- Start SignedProperties--> + <xsd:element name="SignedProperties" type="SignedPropertiesType"/> + <xsd:complexType name="SignedPropertiesType"> + <xsd:sequence> + <xsd:element name="SignedSignatureProperties" type="SignedSignaturePropertiesType" minOccurs="0"/> + <xsd:element name="SignedDataObjectProperties" type="SignedDataObjectPropertiesType" minOccurs="0"/> + </xsd:sequence> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <!-- End SignedProperties--> + <!-- Start UnsignedProperties--> + <xsd:element name="UnsignedProperties" type="UnsignedPropertiesType"/> + <xsd:complexType name="UnsignedPropertiesType"> + <xsd:sequence> + <xsd:element name="UnsignedSignatureProperties" type="UnsignedSignaturePropertiesType" minOccurs="0"/> + <xsd:element name="UnsignedDataObjectProperties" type="UnsignedDataObjectPropertiesType" minOccurs="0"/> + </xsd:sequence> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <!-- End UnsignedProperties--> + <!-- Start SignedSignatureProperties--> + <xsd:element name="SignedSignatureProperties" type="SignedSignaturePropertiesType"/> + <xsd:complexType name="SignedSignaturePropertiesType"> + <xsd:sequence> + <xsd:element name="SigningTime" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="SigningCertificate" type="CertIDListType" minOccurs="0"/> + <xsd:element name="SignaturePolicyIdentifier" type="SignaturePolicyIdentifierType" minOccurs="0"/> + <xsd:element name="SignatureProductionPlace" type="SignatureProductionPlaceType" minOccurs="0"/> + <xsd:element name="SignerRole" type="SignerRoleType" minOccurs="0"/> + </xsd:sequence> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <!-- End SignedSignatureProperties--> + <!-- Start SignedDataObjectProperties--> + <xsd:element name="SignedDataObjectProperties" type="SignedDataObjectPropertiesType"/> + <xsd:complexType name="SignedDataObjectPropertiesType"> + <xsd:sequence> + <xsd:element name="DataObjectFormat" type="DataObjectFormatType" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element name="CommitmentTypeIndication" type="CommitmentTypeIndicationType" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element name="AllDataObjectsTimeStamp" type="XAdESTimeStampType" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element name="IndividualDataObjectsTimeStamp" type="XAdESTimeStampType" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <!-- End SignedDataObjectProperties--> + <!-- Start UnsignedSignatureProperties--> + <xsd:element name="UnsignedSignatureProperties" type="UnsignedSignaturePropertiesType"/> + <xsd:complexType name="UnsignedSignaturePropertiesType"> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="CounterSignature" type="CounterSignatureType"/> + <xsd:element name="SignatureTimeStamp" type="XAdESTimeStampType"/> + <xsd:element name="CompleteCertificateRefs" type="CompleteCertificateRefsType"/> + <xsd:element name="CompleteRevocationRefs" type="CompleteRevocationRefsType"/> + <xsd:element name="AttributeCertificateRefs" type="CompleteCertificateRefsType"/> + <xsd:element name="AttributeRevocationRefs" type="CompleteRevocationRefsType"/> + <xsd:element name="SigAndRefsTimeStamp" type="XAdESTimeStampType"/> + <xsd:element name="RefsOnlyTimeStamp" type="XAdESTimeStampType"/> + <xsd:element name="CertificateValues" type="CertificateValuesType"/> + <xsd:element name="RevocationValues" type="RevocationValuesType"/> + <xsd:element name="AttrAuthoritiesCertValues" type="CertificateValuesType"/> + <xsd:element name="AttributeRevocationValues" type="RevocationValuesType"/> + <xsd:element name="ArchiveTimeStamp" type="XAdESTimeStampType"/> + <xsd:any namespace="##other"/> + </xsd:choice> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <!-- End UnsignedSignatureProperties--> + <!-- Start UnsignedDataObjectProperties--> + <xsd:element name="UnsignedDataObjectProperties" type="UnsignedDataObjectPropertiesType"/> + <xsd:complexType name="UnsignedDataObjectPropertiesType"> + <xsd:sequence> + <xsd:element name="UnsignedDataObjectProperty" type="AnyType" maxOccurs="unbounded"/> + </xsd:sequence> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <!-- End UnsignedDataObjectProperties--> + <!-- Start QualifyingPropertiesReference--> + <xsd:element name="QualifyingPropertiesReference" type="QualifyingPropertiesReferenceType"/> + <xsd:complexType name="QualifyingPropertiesReferenceType"> + <xsd:attribute name="URI" type="xsd:anyURI" use="required"/> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <!-- End QualifyingPropertiesReference--> + <!-- End container types --> + <!-- Start SigningTime element --> + <xsd:element name="SigningTime" type="xsd:dateTime"/> + <!-- End SigningTime element --> + <!-- Start SigningCertificate --> + <xsd:element name="SigningCertificate" type="CertIDListType"/> + <xsd:complexType name="CertIDListType"> + <xsd:sequence> + <xsd:element name="Cert" type="CertIDType" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="CertIDType"> + <xsd:sequence> + <xsd:element name="CertDigest" type="DigestAlgAndValueType"/> + <xsd:element name="IssuerSerial" type="ds:X509IssuerSerialType"/> + </xsd:sequence> + <xsd:attribute name="URI" type="xsd:anyURI" use="optional"/> + </xsd:complexType> + <xsd:complexType name="DigestAlgAndValueType"> + <xsd:sequence> + <xsd:element ref="ds:DigestMethod"/> + <xsd:element ref="ds:DigestValue"/> + </xsd:sequence> + </xsd:complexType> + <!-- End SigningCertificate --> + <!-- Start SignaturePolicyIdentifier --> + <xsd:element name="SignaturePolicyIdentifier" type="SignaturePolicyIdentifierType"/> + <xsd:complexType name="SignaturePolicyIdentifierType"> + <xsd:choice> + <xsd:element name="SignaturePolicyId" type="SignaturePolicyIdType"/> + <xsd:element name="SignaturePolicyImplied"/> + </xsd:choice> + </xsd:complexType> + <xsd:complexType name="SignaturePolicyIdType"> + <xsd:sequence> + <xsd:element name="SigPolicyId" type="ObjectIdentifierType"/> + <xsd:element ref="ds:Transforms" minOccurs="0"/> + <xsd:element name="SigPolicyHash" type="DigestAlgAndValueType"/> + <xsd:element name="SigPolicyQualifiers" type="SigPolicyQualifiersListType" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="SigPolicyQualifiersListType"> + <xsd:sequence> + <xsd:element name="SigPolicyQualifier" type="AnyType" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <xsd:element name="SPURI" type="xsd:anyURI"/> + <xsd:element name="SPUserNotice" type="SPUserNoticeType"/> + <xsd:complexType name="SPUserNoticeType"> + <xsd:sequence> + <xsd:element name="NoticeRef" type="NoticeReferenceType" minOccurs="0"/> + <xsd:element name="ExplicitText" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="NoticeReferenceType"> + <xsd:sequence> + <xsd:element name="Organization" type="xsd:string"/> + <xsd:element name="NoticeNumbers" type="IntegerListType"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="IntegerListType"> + <xsd:sequence> + <xsd:element name="int" type="xsd:integer" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <!-- End SignaturePolicyIdentifier --> + <!-- Start CounterSignature --> + <xsd:element name="CounterSignature" type="CounterSignatureType"/> + <xsd:complexType name="CounterSignatureType"> + <xsd:sequence> + <xsd:element ref="ds:Signature"/> + </xsd:sequence> + </xsd:complexType> + <!-- End CounterSignature --> + <!-- Start DataObjectFormat --> + <xsd:element name="DataObjectFormat" type="DataObjectFormatType"/> + <xsd:complexType name="DataObjectFormatType"> + <xsd:sequence> + <xsd:element name="Description" type="xsd:string" minOccurs="0"/> + <xsd:element name="ObjectIdentifier" type="ObjectIdentifierType" minOccurs="0"/> + <xsd:element name="MimeType" type="xsd:string" minOccurs="0"/> + <xsd:element name="Encoding" type="xsd:anyURI" minOccurs="0"/> + </xsd:sequence> + <xsd:attribute name="ObjectReference" type="xsd:anyURI" use="required"/> + </xsd:complexType> + <!-- End DataObjectFormat --> + <!-- Start CommitmentTypeIndication --> + <xsd:element name="CommitmentTypeIndication" type="CommitmentTypeIndicationType"/> + <xsd:complexType name="CommitmentTypeIndicationType"> + <xsd:sequence> + <xsd:element name="CommitmentTypeId" type="ObjectIdentifierType"/> + <xsd:choice> + <xsd:element name="ObjectReference" type="xsd:anyURI" maxOccurs="unbounded"/> + <xsd:element name="AllSignedDataObjects"/> + </xsd:choice> + <xsd:element name="CommitmentTypeQualifiers" type="CommitmentTypeQualifiersListType" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="CommitmentTypeQualifiersListType"> + <xsd:sequence> + <xsd:element name="CommitmentTypeQualifier" type="AnyType" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <!-- End CommitmentTypeIndication --> + <!-- Start SignatureProductionPlace --> + <xsd:element name="SignatureProductionPlace" type="SignatureProductionPlaceType"/> + <xsd:complexType name="SignatureProductionPlaceType"> + <xsd:sequence> + <xsd:element name="City" type="xsd:string" minOccurs="0"/> + <xsd:element name="StateOrProvince" type="xsd:string" minOccurs="0"/> + <xsd:element name="PostalCode" type="xsd:string" minOccurs="0"/> + <xsd:element name="CountryName" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + <!-- End SignatureProductionPlace --> + <!-- Start SignerRole --> + <xsd:element name="SignerRole" type="SignerRoleType"/> + <xsd:complexType name="SignerRoleType"> + <xsd:sequence> + <xsd:element name="ClaimedRoles" type="ClaimedRolesListType" minOccurs="0"/> + <xsd:element name="CertifiedRoles" type="CertifiedRolesListType" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="ClaimedRolesListType"> + <xsd:sequence> + <xsd:element name="ClaimedRole" type="AnyType" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="CertifiedRolesListType"> + <xsd:sequence> + <xsd:element name="CertifiedRole" type="EncapsulatedPKIDataType" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <!-- End SignerRole --> + <xsd:element name="AllDataObjectsTimeStamp" type="XAdESTimeStampType"/> + <xsd:element name="IndividualDataObjectsTimeStamp" type="XAdESTimeStampType"/> + <xsd:element name="SignatureTimeStamp" type="XAdESTimeStampType"/> + <!-- Start CompleteCertificateRefs --> + <xsd:element name="CompleteCertificateRefs" type="CompleteCertificateRefsType"/> + <xsd:complexType name="CompleteCertificateRefsType"> + <xsd:sequence> + <xsd:element name="CertRefs" type="CertIDListType"/> + </xsd:sequence> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <!-- End CompleteCertificateRefs --> + <!-- Start CompleteRevocationRefs--> + <xsd:element name="CompleteRevocationRefs" type="CompleteRevocationRefsType"/> + <xsd:complexType name="CompleteRevocationRefsType"> + <xsd:sequence> + <xsd:element name="CRLRefs" type="CRLRefsType" minOccurs="0"/> + <xsd:element name="OCSPRefs" type="OCSPRefsType" minOccurs="0"/> + <xsd:element name="OtherRefs" type="OtherCertStatusRefsType" minOccurs="0"/> + </xsd:sequence> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <xsd:complexType name="CRLRefsType"> + <xsd:sequence> + <xsd:element name="CRLRef" type="CRLRefType" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="CRLRefType"> + <xsd:sequence> + <xsd:element name="DigestAlgAndValue" type="DigestAlgAndValueType"/> + <xsd:element name="CRLIdentifier" type="CRLIdentifierType" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="CRLIdentifierType"> + <xsd:sequence> + <xsd:element name="Issuer" type="xsd:string"/> + <xsd:element name="IssueTime" type="xsd:dateTime"/> + <xsd:element name="Number" type="xsd:integer" minOccurs="0"/> + </xsd:sequence> + <xsd:attribute name="URI" type="xsd:anyURI" use="optional"/> + </xsd:complexType> + <xsd:complexType name="OCSPRefsType"> + <xsd:sequence> + <xsd:element name="OCSPRef" type="OCSPRefType" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="OCSPRefType"> + <xsd:sequence> + <xsd:element name="OCSPIdentifier" type="OCSPIdentifierType"/> + <xsd:element name="DigestAlgAndValue" type="DigestAlgAndValueType" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="ResponderIDType"> + <xsd:choice> + <xsd:element name="ByName" type="xsd:string"/> + <xsd:element name="ByKey" type="xsd:base64Binary"/> + </xsd:choice> + </xsd:complexType> + <xsd:complexType name="OCSPIdentifierType"> + <xsd:sequence> + <xsd:element name="ResponderID" type="ResponderIDType"/> + <xsd:element name="ProducedAt" type="xsd:dateTime"/> + </xsd:sequence> + <xsd:attribute name="URI" type="xsd:anyURI" use="optional"/> + </xsd:complexType> + <xsd:complexType name="OtherCertStatusRefsType"> + <xsd:sequence> + <xsd:element name="OtherRef" type="AnyType" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <!-- End CompleteRevocationRefs--> + <xsd:element name="AttributeCertificateRefs" type="CompleteCertificateRefsType"/> + <xsd:element name="AttributeRevocationRefs" type="CompleteRevocationRefsType"/> + <xsd:element name="SigAndRefsTimeStamp" type="XAdESTimeStampType"/> + <xsd:element name="RefsOnlyTimeStamp" type="XAdESTimeStampType"/> + <!-- Start CertificateValues --> + <xsd:element name="CertificateValues" type="CertificateValuesType"/> + <xsd:complexType name="CertificateValuesType"> + <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:element name="EncapsulatedX509Certificate" type="EncapsulatedPKIDataType"/> + <xsd:element name="OtherCertificate" type="AnyType"/> + </xsd:choice> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <!-- End CertificateValues --> + <!-- Start RevocationValues--> + <xsd:element name="RevocationValues" type="RevocationValuesType"/> + <xsd:complexType name="RevocationValuesType"> + <xsd:sequence> + <xsd:element name="CRLValues" type="CRLValuesType" minOccurs="0"/> + <xsd:element name="OCSPValues" type="OCSPValuesType" minOccurs="0"/> + <xsd:element name="OtherValues" type="OtherCertStatusValuesType" minOccurs="0"/> + </xsd:sequence> + <xsd:attribute name="Id" type="xsd:ID" use="optional"/> + </xsd:complexType> + <xsd:complexType name="CRLValuesType"> + <xsd:sequence> + <xsd:element name="EncapsulatedCRLValue" type="EncapsulatedPKIDataType" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="OCSPValuesType"> + <xsd:sequence> + <xsd:element name="EncapsulatedOCSPValue" type="EncapsulatedPKIDataType" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <xsd:complexType name="OtherCertStatusValuesType"> + <xsd:sequence> + <xsd:element name="OtherValue" type="AnyType" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <!-- End RevocationValues--> + <xsd:element name="AttrAuthoritiesCertValues" type="CertificateValuesType"/> + <xsd:element name="AttributeRevocationValues" type="RevocationValuesType"/> + <xsd:element name="ArchiveTimeStamp" type="XAdESTimeStampType"/> +</xsd:schema> http://git-wip-us.apache.org/repos/asf/camel/blob/23688d3d/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xades/xmldsig-core-schema.xsd ---------------------------------------------------------------------- diff --git a/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xades/xmldsig-core-schema.xsd b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xades/xmldsig-core-schema.xsd new file mode 100644 index 0000000..9b5ffef --- /dev/null +++ b/components/camel-xmlsecurity/src/test/resources/org/apache/camel/component/xmlsecurity/xades/xmldsig-core-schema.xsd @@ -0,0 +1,291 @@ +<?xml version="1.0" encoding="utf-8"?> +<schema xmlns="http://www.w3.org/2001/XMLSchema" + xmlns:ds="http://www.w3.org/2000/09/xmldsig#" + targetNamespace="http://www.w3.org/2000/09/xmldsig#" + version="0.1" elementFormDefault="qualified"> + +<!-- Basic Types Defined for Signatures --> + +<simpleType name="CryptoBinary"> + <restriction base="base64Binary"> + </restriction> +</simpleType> + +<!-- Start Signature --> + +<element name="Signature" type="ds:SignatureType"/> +<complexType name="SignatureType"> + <sequence> + <element ref="ds:SignedInfo"/> + <element ref="ds:SignatureValue"/> + <element ref="ds:KeyInfo" minOccurs="0"/> + <element ref="ds:Object" minOccurs="0" maxOccurs="unbounded"/> + </sequence> + <attribute name="Id" type="ID" use="optional"/> +</complexType> + + <element name="SignatureValue" type="ds:SignatureValueType"/> + <complexType name="SignatureValueType"> + <simpleContent> + <extension base="base64Binary"> + <attribute name="Id" type="ID" use="optional"/> + </extension> + </simpleContent> + </complexType> + +<!-- Start SignedInfo --> + +<element name="SignedInfo" type="ds:SignedInfoType"/> +<complexType name="SignedInfoType"> + <sequence> + <element ref="ds:CanonicalizationMethod"/> + <element ref="ds:SignatureMethod"/> + <element ref="ds:Reference" maxOccurs="unbounded"/> + </sequence> + <attribute name="Id" type="ID" use="optional"/> +</complexType> + + <element name="CanonicalizationMethod" type="ds:CanonicalizationMethodType"/> + <complexType name="CanonicalizationMethodType" mixed="true"> + <sequence> + <any namespace="##any" minOccurs="0" maxOccurs="unbounded"/> + <!-- (0,unbounded) elements from (1,1) namespace --> + </sequence> + <attribute name="Algorithm" type="anyURI" use="required"/> + </complexType> + + <element name="SignatureMethod" type="ds:SignatureMethodType"/> + <complexType name="SignatureMethodType" mixed="true"> + <sequence> + <element name="HMACOutputLength" minOccurs="0" type="ds:HMACOutputLengthType"/> + <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/> + <!-- (0,unbounded) elements from (1,1) external namespace --> + </sequence> + <attribute name="Algorithm" type="anyURI" use="required"/> + </complexType> + +<!-- Start Reference --> + +<element name="Reference" type="ds:ReferenceType"/> +<complexType name="ReferenceType"> + <sequence> + <element ref="ds:Transforms" minOccurs="0"/> + <element ref="ds:DigestMethod"/> + <element ref="ds:DigestValue"/> + </sequence> + <attribute name="Id" type="ID" use="optional"/> + <attribute name="URI" type="anyURI" use="optional"/> + <attribute name="Type" type="anyURI" use="optional"/> +</complexType> + + <element name="Transforms" type="ds:TransformsType"/> + <complexType name="TransformsType"> + <sequence> + <element ref="ds:Transform" maxOccurs="unbounded"/> + </sequence> + </complexType> + + <element name="Transform" type="ds:TransformType"/> + <complexType name="TransformType" mixed="true"> + <choice minOccurs="0" maxOccurs="unbounded"> + <any namespace="##other" processContents="lax"/> + <!-- (1,1) elements from (0,unbounded) namespaces --> + <element name="XPath" type="string"/> + </choice> + <attribute name="Algorithm" type="anyURI" use="required"/> + </complexType> + +<!-- End Reference --> + +<element name="DigestMethod" type="ds:DigestMethodType"/> +<complexType name="DigestMethodType" mixed="true"> + <sequence> + <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> + </sequence> + <attribute name="Algorithm" type="anyURI" use="required"/> +</complexType> + +<element name="DigestValue" type="ds:DigestValueType"/> +<simpleType name="DigestValueType"> + <restriction base="base64Binary"/> +</simpleType> + +<!-- End SignedInfo --> + +<!-- Start KeyInfo --> + +<element name="KeyInfo" type="ds:KeyInfoType"/> +<complexType name="KeyInfoType" mixed="true"> + <choice maxOccurs="unbounded"> + <element ref="ds:KeyName"/> + <element ref="ds:KeyValue"/> + <element ref="ds:RetrievalMethod"/> + <element ref="ds:X509Data"/> + <element ref="ds:PGPData"/> + <element ref="ds:SPKIData"/> + <element ref="ds:MgmtData"/> + <any processContents="lax" namespace="##other"/> + <!-- (1,1) elements from (0,unbounded) namespaces --> + </choice> + <attribute name="Id" type="ID" use="optional"/> +</complexType> + + <element name="KeyName" type="string"/> + <element name="MgmtData" type="string"/> + + <element name="KeyValue" type="ds:KeyValueType"/> + <complexType name="KeyValueType" mixed="true"> + <choice> + <element ref="ds:DSAKeyValue"/> + <element ref="ds:RSAKeyValue"/> + <any namespace="##other" processContents="lax"/> + </choice> + </complexType> + + <element name="RetrievalMethod" type="ds:RetrievalMethodType"/> + <complexType name="RetrievalMethodType"> + <sequence> + <element ref="ds:Transforms" minOccurs="0"/> + </sequence> + <attribute name="URI" type="anyURI"/> + <attribute name="Type" type="anyURI" use="optional"/> + </complexType> + +<!-- Start X509Data --> + +<element name="X509Data" type="ds:X509DataType"/> +<complexType name="X509DataType"> + <sequence maxOccurs="unbounded"> + <choice> + <element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/> + <element name="X509SKI" type="base64Binary"/> + <element name="X509SubjectName" type="string"/> + <element name="X509Certificate" type="base64Binary"/> + <element name="X509CRL" type="base64Binary"/> + <any namespace="##other" processContents="lax"/> + </choice> + </sequence> +</complexType> + +<complexType name="X509IssuerSerialType"> + <sequence> + <element name="X509IssuerName" type="string"/> + <element name="X509SerialNumber" type="integer"/> + </sequence> +</complexType> + +<!-- End X509Data --> + +<!-- Begin PGPData --> + +<element name="PGPData" type="ds:PGPDataType"/> +<complexType name="PGPDataType"> + <choice> + <sequence> + <element name="PGPKeyID" type="base64Binary"/> + <element name="PGPKeyPacket" type="base64Binary" minOccurs="0"/> + <any namespace="##other" processContents="lax" minOccurs="0" + maxOccurs="unbounded"/> + </sequence> + <sequence> + <element name="PGPKeyPacket" type="base64Binary"/> + <any namespace="##other" processContents="lax" minOccurs="0" + maxOccurs="unbounded"/> + </sequence> + </choice> +</complexType> + +<!-- End PGPData --> + +<!-- Begin SPKIData --> + +<element name="SPKIData" type="ds:SPKIDataType"/> +<complexType name="SPKIDataType"> + <sequence maxOccurs="unbounded"> + <element name="SPKISexp" type="base64Binary"/> + <any namespace="##other" processContents="lax" minOccurs="0"/> + </sequence> +</complexType> + +<!-- End SPKIData --> + +<!-- End KeyInfo --> + +<!-- Start Object (Manifest, SignatureProperty) --> + +<element name="Object" type="ds:ObjectType"/> +<complexType name="ObjectType" mixed="true"> + <sequence minOccurs="0" maxOccurs="unbounded"> + <any namespace="##any" processContents="lax"/> + </sequence> + <attribute name="Id" type="ID" use="optional"/> + <attribute name="MimeType" type="string" use="optional"/> <!-- add a grep facet --> + <attribute name="Encoding" type="anyURI" use="optional"/> +</complexType> + +<element name="Manifest" type="ds:ManifestType"/> +<complexType name="ManifestType"> + <sequence> + <element ref="ds:Reference" maxOccurs="unbounded"/> + </sequence> + <attribute name="Id" type="ID" use="optional"/> +</complexType> + +<element name="SignatureProperties" type="ds:SignaturePropertiesType"/> +<complexType name="SignaturePropertiesType"> + <sequence> + <element ref="ds:SignatureProperty" maxOccurs="unbounded"/> + </sequence> + <attribute name="Id" type="ID" use="optional"/> +</complexType> + + <element name="SignatureProperty" type="ds:SignaturePropertyType"/> + <complexType name="SignaturePropertyType" mixed="true"> + <choice maxOccurs="unbounded"> + <any namespace="##other" processContents="lax"/> + <!-- (1,1) elements from (1,unbounded) namespaces --> + </choice> + <attribute name="Target" type="anyURI" use="required"/> + <attribute name="Id" type="ID" use="optional"/> + </complexType> + +<!-- End Object (Manifest, SignatureProperty) --> + +<!-- Start Algorithm Parameters --> + +<simpleType name="HMACOutputLengthType"> + <restriction base="integer"/> +</simpleType> + +<!-- Start KeyValue Element-types --> + +<element name="DSAKeyValue" type="ds:DSAKeyValueType"/> +<complexType name="DSAKeyValueType"> + <sequence> + <sequence minOccurs="0"> + <element name="P" type="ds:CryptoBinary"/> + <element name="Q" type="ds:CryptoBinary"/> + </sequence> + <element name="G" type="ds:CryptoBinary" minOccurs="0"/> + <element name="Y" type="ds:CryptoBinary"/> + <element name="J" type="ds:CryptoBinary" minOccurs="0"/> + <sequence minOccurs="0"> + <element name="Seed" type="ds:CryptoBinary"/> + <element name="PgenCounter" type="ds:CryptoBinary"/> + </sequence> + </sequence> +</complexType> + +<element name="RSAKeyValue" type="ds:RSAKeyValueType"/> +<complexType name="RSAKeyValueType"> + <sequence> + <element name="Modulus" type="ds:CryptoBinary"/> + <element name="Exponent" type="ds:CryptoBinary"/> + </sequence> +</complexType> + +<!-- End KeyValue Element-types --> + +<!-- End Signature --> + +</schema> http://git-wip-us.apache.org/repos/asf/camel/blob/23688d3d/platforms/karaf/features/src/main/resources/features.xml ---------------------------------------------------------------------- diff --git a/platforms/karaf/features/src/main/resources/features.xml b/platforms/karaf/features/src/main/resources/features.xml index 51505f8..6e04c54 100644 --- a/platforms/karaf/features/src/main/resources/features.xml +++ b/platforms/karaf/features/src/main/resources/features.xml @@ -1450,6 +1450,7 @@ <bundle>mvn:org.apache.camel/camel-xmlrpc/${project.version}</bundle> </feature> <feature name='camel-xmlsecurity' version='${project.version}' resolver='(obr)' start-level='50'> + <bundle dependency='true'>mvn:commons-codec/commons-codec/${commons-codec-version}</bundle> <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xalan/${xalan-bundle-version}</bundle> <bundle dependency='true'>mvn:org.apache.santuario/xmlsec/${xmlsec-version}</bundle> <bundle dependency='true'>mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xerces/${xerces-bundle-version}</bundle>
