View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.wss4j.dom.components.crypto;
21  
22  import java.io.InputStream;
23  import java.security.KeyStore;
24  import java.util.Properties;
25  
26  import org.apache.wss4j.common.util.SOAPUtil;
27  import org.apache.wss4j.dom.WSConstants;
28  import org.apache.wss4j.dom.common.CustomCrypto;
29  
30  import org.apache.wss4j.dom.engine.WSSConfig;
31  import org.apache.wss4j.dom.engine.WSSecurityEngine;
32  import org.apache.wss4j.common.crypto.Crypto;
33  import org.apache.wss4j.common.crypto.CryptoFactory;
34  import org.apache.wss4j.common.crypto.Merlin;
35  import org.apache.wss4j.common.ext.WSSecurityException;
36  import org.apache.wss4j.common.util.Loader;
37  import org.apache.wss4j.dom.message.WSSecHeader;
38  import org.apache.wss4j.dom.message.WSSecSignature;
39  
40  import org.junit.jupiter.api.Test;
41  import org.w3c.dom.Document;
42  
43  import static org.junit.jupiter.api.Assertions.assertNotNull;
44  import static org.junit.jupiter.api.Assertions.assertSame;
45  import static org.junit.jupiter.api.Assertions.assertTrue;
46  import static org.junit.jupiter.api.Assertions.fail;
47  
48  public class CryptoTest {
49  
50      public CryptoTest() {
51          WSSConfig.init();
52      }
53  
54      @Test
55      public void testCrypto() throws Exception {
56          Crypto crypto = CryptoFactory.getInstance();
57          assertNotNull(crypto);
58      }
59  
60      @Test
61      public void testMerlinWithNullProperties()
62          throws Exception {
63          Crypto crypto = new NullPropertiesCrypto();
64          assertNotNull(crypto);
65      }
66  
67      /**
68       * Ensure that we can load a custom crypto implementation using a Map
69       */
70      @Test
71      public void testCustomCrypto() throws Exception {
72          java.util.Map<Object, Object> tmp = new java.util.TreeMap<>();
73          Crypto crypto = CryptoFactory.getInstance(
74              CustomCrypto.class, tmp
75          );
76          assertNotNull(crypto);
77          assertTrue(crypto instanceof CustomCrypto);
78          CustomCrypto custom = (CustomCrypto)crypto;
79          assertSame(tmp, custom.getConfig());
80      }
81  
82      /**
83       * Test for WSS-149 - "Merlin requires org.apache.wss4j.crypto.merlin.file
84       * to be set and point to an existing file"
85       */
86      @Test
87      public void testNoKeyStoreFile() throws Exception {
88          Crypto crypto = CryptoFactory.getInstance(
89              "nofile.properties"
90          );
91          assertNotNull(crypto);
92      }
93  
94      /**
95       * Test that we can sign and verify a signature using dynamically loaded keystores/truststore
96       */
97      @Test
98      public void testDynamicCrypto() throws Exception {
99          Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
100         WSSecHeader secHeader = new WSSecHeader(doc);
101         secHeader.insertSecurityHeader();
102 
103         WSSecSignature builder = new WSSecSignature(secHeader);
104         builder.setUserInfo("wss40", "security");
105         builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
106 
107         // Load the keystore
108         Crypto crypto = new Merlin();
109         KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
110         ClassLoader loader = Loader.getClassLoader(CryptoTest.class);
111         InputStream input = Merlin.loadInputStream(loader, "keys/wss40.jks");
112         keyStore.load(input, "security".toCharArray());
113         input.close();
114         ((Merlin)crypto).setKeyStore(keyStore);
115         Document signedDoc = builder.build(crypto);
116 
117         // Load the truststore
118         Crypto processCrypto = new Merlin();
119         KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
120         input = Merlin.loadInputStream(loader, "keys/wss40CA.jks");
121         trustStore.load(input, "security".toCharArray());
122         input.close();
123         ((Merlin)processCrypto).setTrustStore(trustStore);
124 
125         WSSecurityEngine secEngine = new WSSecurityEngine();
126         secEngine.processSecurityHeader(signedDoc, null, null, processCrypto);
127 
128         // Load a (bad) truststore
129         processCrypto = new Merlin();
130         trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
131         input = Merlin.loadInputStream(loader, "keys/wss40badca.jks");
132         trustStore.load(input, "security".toCharArray());
133         input.close();
134         ((Merlin)processCrypto).setTrustStore(trustStore);
135 
136         try {
137             secEngine.processSecurityHeader(signedDoc, null, null, processCrypto);
138             fail("Expected failure on a bad trust store");
139         } catch (WSSecurityException ex) {
140             assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
141         }
142     }
143 
144     @Test
145     public void testCryptoFactoryMerlin() throws Exception {
146         ClassLoader classLoader = this.getClass().getClassLoader();
147         Properties properties = CryptoFactory.getProperties("crypto.properties", classLoader);
148         Crypto crypto =
149             CryptoFactory.getInstance(properties, classLoader, null);
150         assertTrue(crypto instanceof Merlin);
151     }
152 
153     @Test
154     public void testCryptoFactoryMerlinDevice() throws Exception {
155         ClassLoader classLoader = this.getClass().getClassLoader();
156         Properties properties = CryptoFactory.getProperties("crypto_device.properties", classLoader);
157         Crypto crypto =
158             CryptoFactory.getInstance(properties, classLoader, null);
159         assertTrue(crypto instanceof Merlin);
160     }
161 
162     /**
163      * WSS-102 -- ensure Merlin with null properties can be instantiated
164      */
165     private static class NullPropertiesCrypto extends Merlin {
166         public NullPropertiesCrypto()
167             throws Exception {
168             super(null, null, null);
169         }
170     }
171 }