PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/components/camel-xmlsecurity/src/test/java/org/apache/camel/component/xmlsecurity/ECDSASignatureTest.java

https://github.com/apache/camel
Java | 308 lines | 239 code | 34 blank | 35 comment | 17 complexity | d2fc083fca00da8d1681510c44c35036 MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package org.apache.camel.component.xmlsecurity;
  18. import java.io.InputStream;
  19. import java.lang.reflect.Constructor;
  20. import java.security.KeyStore;
  21. import java.security.PrivateKey;
  22. import java.security.Provider;
  23. import java.security.Security;
  24. import java.security.cert.Certificate;
  25. import javax.xml.crypto.KeySelector;
  26. import javax.xml.crypto.URIDereferencer;
  27. import javax.xml.crypto.dsig.keyinfo.KeyInfo;
  28. import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
  29. import org.w3c.dom.Node;
  30. import org.apache.camel.Message;
  31. import org.apache.camel.builder.RouteBuilder;
  32. import org.apache.camel.component.mock.MockEndpoint;
  33. import org.apache.camel.component.xmlsecurity.api.KeyAccessor;
  34. import org.apache.camel.component.xmlsecurity.util.SameDocumentUriDereferencer;
  35. import org.apache.camel.spi.Registry;
  36. import org.apache.camel.support.SimpleRegistry;
  37. import org.apache.camel.test.junit5.CamelTestSupport;
  38. import org.apache.camel.test.junit5.TestSupport;
  39. import org.junit.jupiter.api.BeforeEach;
  40. import org.junit.jupiter.api.Test;
  41. import org.slf4j.Logger;
  42. import org.slf4j.LoggerFactory;
  43. import static org.apache.camel.test.junit5.TestSupport.isJavaVendor;
  44. /**
  45. * Test for the ECDSA algorithms
  46. */
  47. public class ECDSASignatureTest extends CamelTestSupport {
  48. private static String payload;
  49. private Logger log = LoggerFactory.getLogger(getClass());
  50. private boolean canTest = true;
  51. static {
  52. boolean includeNewLine = true;
  53. if (TestSupport.getJavaMajorVersion() >= 9
  54. || TestSupport.isJava18_261_later() && !TestSupport.isJavaVendor("Azul")) {
  55. includeNewLine = false;
  56. }
  57. payload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  58. + (includeNewLine ? "\n" : "")
  59. + "<root xmlns=\"http://test/test\"><test>Test Message</test></root>";
  60. }
  61. public ECDSASignatureTest() throws Exception {
  62. try {
  63. // BouncyCastle is required for some algorithms
  64. if (Security.getProvider("BC") == null) {
  65. Constructor<?> cons;
  66. Class<?> c = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider");
  67. cons = c.getConstructor(new Class[] {});
  68. Provider provider = (java.security.Provider) cons.newInstance();
  69. Security.insertProviderAt(provider, 2);
  70. }
  71. // This test fails with the IBM JDK
  72. if (isJavaVendor("IBM")) {
  73. canTest = false;
  74. }
  75. } catch (Exception e) {
  76. System.err.println("Cannot test due " + e.getMessage());
  77. log.warn("Cannot test due " + e.getMessage(), e);
  78. canTest = false;
  79. }
  80. }
  81. @Override
  82. protected Registry createCamelRegistry() throws Exception {
  83. Registry registry = new SimpleRegistry();
  84. // This test fails with the IBM JDK
  85. if (canTest) {
  86. registry.bind("accessor", getKeyAccessor());
  87. registry.bind("selector", KeySelector.singletonKeySelector(getCertificateFromKeyStore().getPublicKey()));
  88. registry.bind("uriDereferencer", getSameDocumentUriDereferencer());
  89. }
  90. return registry;
  91. }
  92. @Override
  93. protected RouteBuilder[] createRouteBuilders() throws Exception {
  94. if (!canTest) {
  95. return new RouteBuilder[] {};
  96. }
  97. return new RouteBuilder[] { new RouteBuilder() {
  98. public void configure() throws Exception {
  99. // START SNIPPET: ecdsa signature algorithm
  100. from("direct:ecdsa_sha1")
  101. .to("xmlsecurity-sign:ecdsa_sha1?keyAccessor=#accessor"
  102. + "&signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1")
  103. // .log("Body: + ${body}")
  104. .to("xmlsecurity-verify:ecdsa?keySelector=#selector")
  105. .to("mock:result");
  106. // END SNIPPET: ecdsa signature algorithm
  107. }
  108. }, new RouteBuilder() {
  109. public void configure() throws Exception {
  110. // START SNIPPET: ecdsa signature algorithm
  111. from("direct:ecdsa_sha224")
  112. .to("xmlsecurity-sign:ecdsa_sha224?keyAccessor=#accessor"
  113. + "&signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224")
  114. .to("xmlsecurity-verify:ecdsa?keySelector=#selector")
  115. .to("mock:result");
  116. // END SNIPPET: ecdsa signature algorithm
  117. }
  118. }, new RouteBuilder() {
  119. public void configure() throws Exception {
  120. // START SNIPPET: ecdsa signature algorithm
  121. from("direct:ecdsa_sha256")
  122. .to("xmlsecurity-sign:ecdsa_sha256?keyAccessor=#accessor"
  123. + "&signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256")
  124. .to("xmlsecurity-verify:ecdsa?keySelector=#selector")
  125. .to("mock:result");
  126. // END SNIPPET: ecdsa signature algorithm
  127. }
  128. }, new RouteBuilder() {
  129. public void configure() throws Exception {
  130. // START SNIPPET: ecdsa signature algorithm
  131. from("direct:ecdsa_sha384")
  132. .to("xmlsecurity-sign:ecdsa_sha384?keyAccessor=#accessor"
  133. + "&signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384")
  134. .to("xmlsecurity-verify:ecdsa?keySelector=#selector")
  135. .to("mock:result");
  136. // END SNIPPET: ecdsa signature algorithm
  137. }
  138. }, new RouteBuilder() {
  139. public void configure() throws Exception {
  140. // START SNIPPET: ecdsa signature algorithm
  141. from("direct:ecdsa_sha512")
  142. .to("xmlsecurity-sign:ecdsa_sha512?keyAccessor=#accessor"
  143. + "&signatureAlgorithm=http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512")
  144. .to("xmlsecurity-verify:ecdsa?keySelector=#selector")
  145. .to("mock:result");
  146. // END SNIPPET: ecdsa signature algorithm
  147. }
  148. }, new RouteBuilder() {
  149. public void configure() throws Exception {
  150. // START SNIPPET: ecdsa signature algorithm
  151. from("direct:ecdsa_ripemd160")
  152. .to("xmlsecurity-sign:ecdsa_ripemd160?keyAccessor=#accessor"
  153. + "&signatureAlgorithm=http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160")
  154. .to("xmlsecurity-verify:ecdsa?keySelector=#selector")
  155. .to("mock:result");
  156. // END SNIPPET: ecdsa signature algorithm
  157. }
  158. }
  159. };
  160. }
  161. @Test
  162. public void testECDSASHA1() throws Exception {
  163. if (!canTest) {
  164. return;
  165. }
  166. setupMock();
  167. sendBody("direct:ecdsa_sha1", payload);
  168. assertMockEndpointsSatisfied();
  169. }
  170. @Test
  171. public void testECDSASHA224() throws Exception {
  172. if (!canTest) {
  173. return;
  174. }
  175. setupMock();
  176. sendBody("direct:ecdsa_sha224", payload);
  177. assertMockEndpointsSatisfied();
  178. }
  179. @Test
  180. public void testECDSASHA256() throws Exception {
  181. if (!canTest) {
  182. return;
  183. }
  184. setupMock();
  185. sendBody("direct:ecdsa_sha256", payload);
  186. assertMockEndpointsSatisfied();
  187. }
  188. @Test
  189. public void testECDSASHA384() throws Exception {
  190. if (!canTest) {
  191. return;
  192. }
  193. setupMock();
  194. sendBody("direct:ecdsa_sha384", payload);
  195. assertMockEndpointsSatisfied();
  196. }
  197. @Test
  198. public void testECDSASHA512() throws Exception {
  199. if (!canTest) {
  200. return;
  201. }
  202. setupMock();
  203. sendBody("direct:ecdsa_sha512", payload);
  204. assertMockEndpointsSatisfied();
  205. }
  206. @Test
  207. public void testECDSARIPEMD160() throws Exception {
  208. if (!canTest) {
  209. return;
  210. }
  211. setupMock();
  212. sendBody("direct:ecdsa_ripemd160", payload);
  213. assertMockEndpointsSatisfied();
  214. }
  215. private MockEndpoint setupMock() {
  216. return setupMock(payload);
  217. }
  218. private MockEndpoint setupMock(String payload) {
  219. String payload2;
  220. int pos = payload.indexOf('\n');
  221. if (pos != -1) {
  222. payload2 = payload.substring(0, pos) + payload.substring(pos + 1);
  223. } else {
  224. payload2 = payload.replaceFirst("\\?>", "\\?>\n");
  225. }
  226. MockEndpoint mock = getMockEndpoint("mock:result");
  227. mock.expectedMessageCount(1);
  228. mock.message(0).body(String.class).in(payload, payload2);
  229. return mock;
  230. }
  231. @Override
  232. @BeforeEach
  233. public void setUp() throws Exception {
  234. disableJMX();
  235. try {
  236. super.setUp();
  237. } catch (Exception e) {
  238. System.err.println("Cannot test due " + e.getMessage());
  239. log.warn("Cannot test due " + e.getMessage(), e);
  240. canTest = false;
  241. }
  242. }
  243. private static KeyStore loadKeystore() throws Exception {
  244. KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
  245. InputStream in = ECDSASignatureTest.class.getResourceAsStream("/org/apache/camel/component/xmlsecurity/ecdsa.jks");
  246. keyStore.load(in, "security".toCharArray());
  247. return keyStore;
  248. }
  249. private static Certificate getCertificateFromKeyStore() throws Exception {
  250. return loadKeystore().getCertificate("ECDSA");
  251. }
  252. private static PrivateKey getKeyFromKeystore() throws Exception {
  253. return (PrivateKey) loadKeystore().getKey("ECDSA", "security".toCharArray());
  254. }
  255. static KeyAccessor getKeyAccessor() {
  256. KeyAccessor accessor = new KeyAccessor() {
  257. @Override
  258. public KeySelector getKeySelector(Message message) throws Exception {
  259. return KeySelector.singletonKeySelector(getKeyFromKeystore());
  260. }
  261. @Override
  262. public KeyInfo getKeyInfo(
  263. Message mess, Node messageBody,
  264. KeyInfoFactory keyInfoFactory)
  265. throws Exception {
  266. return null;
  267. }
  268. };
  269. return accessor;
  270. }
  271. public static URIDereferencer getSameDocumentUriDereferencer() {
  272. return SameDocumentUriDereferencer.getInstance();
  273. }
  274. }