1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.dom.components.crypto;
21
22 import org.apache.wss4j.common.util.SOAPUtil;
23 import org.apache.wss4j.dom.WSConstants;
24 import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
25
26 import org.apache.wss4j.dom.engine.WSSecurityEngine;
27 import org.apache.wss4j.common.crypto.Crypto;
28 import org.apache.wss4j.common.crypto.CryptoFactory;
29 import org.apache.wss4j.common.ext.WSSecurityException;
30 import org.apache.wss4j.common.util.KeyUtils;
31 import org.apache.wss4j.common.util.XMLUtils;
32 import org.apache.wss4j.dom.message.WSSecEncrypt;
33 import org.apache.wss4j.dom.message.WSSecHeader;
34 import org.apache.wss4j.dom.message.WSSecSignature;
35 import org.bouncycastle.jce.provider.BouncyCastleProvider;
36
37 import org.junit.jupiter.api.Test;
38 import org.w3c.dom.Document;
39
40 import javax.crypto.KeyGenerator;
41 import javax.crypto.SecretKey;
42 import javax.security.auth.callback.CallbackHandler;
43 import javax.xml.parsers.DocumentBuilderFactory;
44
45 import java.io.ByteArrayInputStream;
46 import java.io.InputStream;
47 import java.security.Security;
48 import java.security.cert.CertificateFactory;
49 import java.security.cert.X509Certificate;
50
51 import static org.junit.jupiter.api.Assertions.assertTrue;
52 import static org.junit.jupiter.api.Assertions.fail;
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 public class CryptoProviderTest {
68 private static final org.slf4j.Logger LOG =
69 org.slf4j.LoggerFactory.getLogger(CryptoProviderTest.class);
70 private WSSecurityEngine secEngine = new WSSecurityEngine();
71 private CallbackHandler callbackHandler = new KeystoreCallbackHandler();
72 private Crypto crypto;
73
74 public CryptoProviderTest() throws Exception {
75 secEngine.getWssConfig();
76 crypto = CryptoFactory.getInstance("wss86.properties");
77 }
78
79
80
81
82 @Test
83 public void testSignatureOID() throws Exception {
84 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
85 WSSecHeader secHeader = new WSSecHeader(doc);
86 secHeader.insertSecurityHeader();
87
88 WSSecSignature sign = new WSSecSignature(secHeader);
89 sign.setUserInfo("wss86", "security");
90 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
91
92 Document signedDoc = sign.build(crypto);
93
94 if (LOG.isDebugEnabled()) {
95 String outputString =
96 XMLUtils.prettyDocumentToString(signedDoc);
97 LOG.debug(outputString);
98 }
99 verify(signedDoc);
100 }
101
102
103
104
105
106 @Test
107 public void testSignatureEmailAddress() throws Exception {
108 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
109 WSSecHeader secHeader = new WSSecHeader(doc);
110 secHeader.insertSecurityHeader();
111
112 WSSecSignature sign = new WSSecSignature(secHeader);
113 sign.setUserInfo("wss86", "security");
114 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
115
116 Document signedDoc = sign.build(crypto);
117
118 String outputString = XMLUtils.prettyDocumentToString(signedDoc);
119 outputString =
120 outputString.replace("1.2.840.113549.1.9.1=#16125765726e6572406578616d706c652e636f6d",
121 "EMAILADDRESS=Werner@example.com");
122
123 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
124 dbf.setNamespaceAware(true);
125 InputStream is = new ByteArrayInputStream(outputString.getBytes());
126 Document parsedDoc = dbf.newDocumentBuilder().parse(is);
127 verify(parsedDoc);
128 }
129
130
131
132
133
134 @Test
135 public void testSignatureOtherEmailAddress() throws Exception {
136 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
137 WSSecHeader secHeader = new WSSecHeader(doc);
138 secHeader.insertSecurityHeader();
139
140 WSSecSignature sign = new WSSecSignature(secHeader);
141 sign.setUserInfo("wss86", "security");
142 sign.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
143
144 Document signedDoc = sign.build(crypto);
145
146 String outputString = XMLUtils.prettyDocumentToString(signedDoc);
147 outputString =
148 outputString.replace("1.2.840.113549.1.9.1=#16125765726e6572406578616d706c652e636f6d",
149 "E=Werner@example.com");
150
151 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
152 dbf.setNamespaceAware(true);
153 InputStream is = new ByteArrayInputStream(outputString.getBytes());
154 Document parsedDoc = dbf.newDocumentBuilder().parse(is);
155 verify(parsedDoc);
156 }
157
158
159
160
161
162 @Test
163 public void testInterop() throws Exception {
164
165
166
167
168
169 byte[] certBytes =
170 org.apache.xml.security.utils.XMLUtils.decode(
171 "MIIDqTCCApGgAwIBAgIEePiYTTANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCREUxDzANBgNV"
172 + "BAgTBkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZBcGFjaGUxDjAMBgNVBAsTBVdT"
173 + "UzRKMQ8wDQYDVQQDEwZXZXJuZXIxITAfBgkqhkiG9w0BCQEWEldlcm5lckBleGFtcGxlLmNvbTAe"
174 + "Fw0xNTA5MDkxNTA3MzFaFw0yNTA5MDYxNTA3MzFaMIGEMQswCQYDVQQGEwJERTEPMA0GA1UECBMG"
175 + "QmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDzANBgNVBAoTBkFwYWNoZTEOMAwGA1UECxMFV1NTNEox"
176 + "DzANBgNVBAMTBldlcm5lcjEhMB8GCSqGSIb3DQEJARYSV2VybmVyQGV4YW1wbGUuY29tMIIBIjAN"
177 + "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoUlwwKbNU0vNPwEc32E85k36n7cWAmuuhpX+CoTk"
178 + "XOfvpyoVcwBI8LwMmT1CR9KPxa+zmcE7RmX5qzVaW7Ukzra/pfD7YC3WGGAU9Awsq5OFLsMc4tZ/"
179 + "7FM5azGdZA/wSI2384Ytnu88Z8O1qnBblLdNluNWVADq5tvgAdPQMoks9Xg+9SBiwj2p3C0RD0uM"
180 + "x0bwscNEDWeHUJeGqNbWzEeYCvFLDGdl1Or3uha+drq4fNoVGstybM0VeGvFjP3NEX8dfl9WTxAl"
181 + "3dB0TXzb70RuQghLqHJtDEXMC/ckaNHht6F/VcOxjZCtpLlMUptyPjrMDFOIaZ5q/6NSiMIjqwID"
182 + "AQABoyEwHzAdBgNVHQ4EFgQUviIg1rtoiwto4gYIAWFHCsCDISkwDQYJKoZIhvcNAQELBQADggEB"
183 + "AJEaMtEBpI7X1lx2+Wcjn2a3xugfTGZcy3s4fxGpbCxcdbDS7gWR/N+acwp4GXEbDrObwxIO/Kt5"
184 + "eMzfD5EPCuMdLfLjK+G27RXc/89bR3aphm6ZyLnTLBJ5h24Of9+uDKY2bVIcF62uyXCnVAoq6dY/"
185 + "rBj7btSjAOWFshMDJGNN7k/78s33sTdJfD2NQDvAvRZb1hYiUGcUij0ka+bhS/EtazH411w2NOQY"
186 + "UyZ50HRroKJx1PPCE+OTO5JYPNQB2rauK63RHGGC94mY2ySCE2KP/yaWhkDJ60X2JKgnTLKUZxLP"
187 + "9IioeHVeUzGIccIicoiZR5kqaiqoEk82V81R+VA="
188 );
189
190 try {
191 Security.addProvider(new BouncyCastleProvider());
192 CertificateFactory factory =
193 CertificateFactory.getInstance("X.509", "BC");
194 X509Certificate cert =
195 (X509Certificate)factory.generateCertificate(
196 new ByteArrayInputStream(certBytes)
197 );
198
199 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
200 WSSecHeader secHeader = new WSSecHeader(doc);
201 secHeader.insertSecurityHeader();
202
203 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
204 encrypt.setUseThisCert(cert);
205
206 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
207 SecretKey symmetricKey = keyGen.generateKey();
208 Document encryptedDoc = encrypt.build(crypto, symmetricKey);
209
210 if (LOG.isDebugEnabled()) {
211 String outputString =
212 XMLUtils.prettyDocumentToString(encryptedDoc);
213 LOG.debug(outputString);
214 }
215 verify(encryptedDoc);
216 } finally {
217 Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
218 }
219
220 }
221
222
223
224
225
226
227
228 @Test
229 public void testBadInterop() throws Exception {
230 byte[] certBytes =
231 org.apache.xml.security.utils.XMLUtils.decode(
232 "MIIDNDCCAp2gAwIBAgIBEDANBgkqhkiG9w0BAQQFADBmMQswCQYDVQQGEwJERTEPMA0GA1UECBMG"
233 + "QmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUxFTATBgNVBAsTDEFwYWNoZSBX"
234 + "U1M0SjEPMA0GA1UEAxMGV2VybmVyMB4XDTA4MDQwNDE5MzIxOFoXDTEwMDQwNDE5MzIxOFowYTEL"
235 + "MAkGA1UEBhMCREUxDzANBgNVBAgTBkJheWVybjEPMA0GA1UEBxMGTXVuaWNoMQ8wDQYDVQQKEwZB"
236 + "cGFjaGUxDjAMBgNVBAsTBVdTUzRKMQ8wDQYDVQQDEwZXZXJuZXIwgZ8wDQYJKoZIhvcNAQEBBQAD"
237 + "gY0AMIGJAoGBAINlL3/k0H/zvknpBtLo8jzXwx/IJU/CGSv6MsqJZ2fyZ6kpLlXCuSBUZ/tfkdxp"
238 + "uzhYq/Sc7A8csIk9gDf9RUbrhK0qKw0VP6DoCIJjS5IeN+NeJkx8YjmzLPmZqLYbNPXr/hy8CRrR"
239 + "6CqLTTSkBwoEJ+cDkfZrdH2/bND0FEIZAgMBAAGjgfYwgfMwCQYDVR0TBAIwADAsBglghkgBhvhC"
240 + "AQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFFSZXv0I5bG7XPEw"
241 + "jylwG3lmZGdiMIGYBgNVHSMEgZAwgY2AFL/FsHHolGIMacU1TZW/88Bd2EL6oWqkaDBmMQswCQYD"
242 + "VQQGEwJERTEPMA0GA1UECBMGQmF5ZXJuMQ8wDQYDVQQHEwZNdW5pY2gxDTALBgNVBAoTBEhvbWUx"
243 + "FTATBgNVBAsTDEFwYWNoZSBXU1M0SjEPMA0GA1UEAxMGV2VybmVyggkAuBIOAWJ19mwwDQYJKoZI"
244 + "hvcNAQEEBQADgYEAUiUh/wORVcQYXxIh13h3w2Btg6Kj2g6V6YO0Utc/gEYWwT310C2OuroKAwwo"
245 + "HapMIIWiJRclIAiA8Hnb0Sv/puuHYD4G4NWFdiVjRord90eZJe40NMGruRmlqIRIGGKCv+wv3E6U"
246 + "x1cWW862f5H9Eyrcocke2P+3GNAGy83vghA="
247 );
248
249 try {
250 Security.addProvider(new BouncyCastleProvider());
251 CertificateFactory factory =
252 CertificateFactory.getInstance("X.509", "BC");
253 X509Certificate cert =
254 (X509Certificate)factory.generateCertificate(
255 new ByteArrayInputStream(certBytes)
256 );
257
258 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
259 WSSecHeader secHeader = new WSSecHeader(doc);
260 secHeader.insertSecurityHeader();
261
262 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
263 encrypt.setUseThisCert(cert);
264
265 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128);
266 SecretKey symmetricKey = keyGen.generateKey();
267 Document encryptedDoc = encrypt.build(crypto, symmetricKey);
268
269 if (LOG.isDebugEnabled()) {
270 String outputString =
271 XMLUtils.prettyDocumentToString(encryptedDoc);
272 LOG.debug(outputString);
273 }
274 try {
275 verify(encryptedDoc);
276 fail("Failure expected on encryption with a key that does not exist in the keystore");
277 } catch (WSSecurityException ex) {
278 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
279 }
280 } finally {
281 Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
282 }
283 }
284
285
286
287
288
289
290
291
292 private void verify(Document doc) throws Exception {
293 secEngine.processSecurityHeader(doc, null, callbackHandler, crypto);
294 if (LOG.isDebugEnabled()) {
295 LOG.debug("Verfied and decrypted message:");
296 String outputString =
297 XMLUtils.prettyDocumentToString(doc);
298 LOG.debug(outputString);
299 }
300 }
301
302 }