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.message;
21
22 import java.io.IOException;
23 import java.util.Collections;
24
25 import javax.crypto.KeyGenerator;
26 import javax.crypto.SecretKey;
27 import javax.security.auth.callback.Callback;
28 import javax.security.auth.callback.CallbackHandler;
29 import javax.security.auth.callback.UnsupportedCallbackException;
30 import javax.xml.crypto.dsig.SignatureMethod;
31
32 import org.apache.wss4j.common.util.SOAPUtil;
33 import org.apache.wss4j.dom.WSConstants;
34 import org.apache.wss4j.dom.common.CustomHandler;
35 import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
36 import org.apache.wss4j.dom.common.SecretKeyCallbackHandler;
37
38 import org.apache.wss4j.dom.engine.WSSConfig;
39 import org.apache.wss4j.dom.engine.WSSecurityEngine;
40 import org.apache.wss4j.common.crypto.Crypto;
41 import org.apache.wss4j.common.crypto.CryptoFactory;
42 import org.apache.wss4j.common.ext.WSPasswordCallback;
43 import org.apache.wss4j.common.util.KeyUtils;
44 import org.apache.wss4j.common.util.XMLUtils;
45 import org.apache.wss4j.dom.handler.HandlerAction;
46 import org.apache.wss4j.dom.handler.RequestData;
47 import org.apache.wss4j.dom.handler.WSHandlerConstants;
48
49 import org.junit.jupiter.api.BeforeEach;
50 import org.junit.jupiter.api.Test;
51 import org.w3c.dom.Document;
52
53
54
55
56
57
58
59 public class SymmetricSignatureTest implements CallbackHandler {
60 private static final org.slf4j.Logger LOG =
61 org.slf4j.LoggerFactory.getLogger(SymmetricSignatureTest.class);
62 private WSSecurityEngine secEngine = new WSSecurityEngine();
63 private CallbackHandler callbackHandler = new KeystoreCallbackHandler();
64 private SecretKeyCallbackHandler secretKeyCallbackHandler = new SecretKeyCallbackHandler();
65 private byte[] keyData;
66 private Crypto crypto;
67
68 public SymmetricSignatureTest() throws Exception {
69 WSSConfig.init();
70 crypto = CryptoFactory.getInstance("wss40.properties");
71 }
72
73
74
75
76
77
78
79 @BeforeEach
80 public void setUp() throws Exception {
81 KeyGenerator keyGen = KeyGenerator.getInstance("AES");
82 keyGen.init(128);
83 SecretKey key = keyGen.generateKey();
84 keyData = key.getEncoded();
85 }
86
87
88
89
90 @Test
91 public void testSymmetricSignatureSHA1() throws Exception {
92 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
93
94 WSSecHeader secHeader = new WSSecHeader(doc);
95 secHeader.insertSecurityHeader();
96
97 WSSecSignature sign = new WSSecSignature(secHeader);
98 sign.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
99 sign.setSecretKey(keyData);
100 sign.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
101
102 Document signedDoc = sign.build(crypto);
103
104 byte[] encodedBytes = KeyUtils.generateDigest(keyData);
105 String identifier = org.apache.xml.security.utils.XMLUtils.encodeToString(encodedBytes);
106 secretKeyCallbackHandler.addSecretKey(identifier, keyData);
107
108 if (LOG.isDebugEnabled()) {
109 LOG.debug("Signed symmetric message SHA1:");
110 String outputString =
111 XMLUtils.prettyDocumentToString(signedDoc);
112 LOG.debug(outputString);
113 }
114
115 secEngine.processSecurityHeader(doc, null, secretKeyCallbackHandler, null, crypto);
116 }
117
118
119
120
121
122
123 @Test
124 public void testSymmetricSignatureDR() throws Exception {
125 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
126
127 WSSecHeader secHeader = new WSSecHeader(doc);
128 secHeader.insertSecurityHeader();
129
130 WSSecEncryptedKey encrKey = new WSSecEncryptedKey(secHeader);
131 encrKey.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
132 encrKey.setUserInfo("wss40", "security");
133
134 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_192);
135 SecretKey symmetricKey = keyGen.generateKey();
136 encrKey.prepare(crypto, symmetricKey);
137
138 WSSecSignature sign = new WSSecSignature(secHeader);
139 sign.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
140 sign.setCustomTokenId(encrKey.getId());
141 sign.setSecretKey(symmetricKey.getEncoded());
142 sign.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
143 sign.setCustomTokenValueType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
144
145 Document signedDoc = sign.build(crypto);
146 encrKey.prependToHeader();
147
148 if (LOG.isDebugEnabled()) {
149 LOG.debug("Signed symmetric message DR:");
150 String outputString =
151 XMLUtils.prettyDocumentToString(signedDoc);
152 LOG.debug(outputString);
153 }
154
155 verify(signedDoc);
156 }
157
158
159
160
161
162
163
164
165 @Test
166 public void testEncryptedKeySignature() throws Exception {
167 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
168 LOG.info("Before Sign/Encryption....");
169
170 WSSecHeader secHeader = new WSSecHeader(doc);
171 secHeader.insertSecurityHeader();
172
173 WSSecEncryptedKey encrKey = new WSSecEncryptedKey(secHeader);
174 encrKey.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
175 encrKey.setUserInfo("wss40", "security");
176
177 KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_192);
178 SecretKey symmetricKey = keyGen.generateKey();
179 encrKey.prepare(crypto, symmetricKey);
180
181 WSSecEncrypt encrypt = new WSSecEncrypt(secHeader);
182 encrypt.setEncKeyId(encrKey.getId());
183 encrypt.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
184 encrypt.setEncryptSymmKey(false);
185 encrypt.setEncryptedKeyElement(encrKey.getEncryptedKeyElement());
186
187 WSSecSignature sign = new WSSecSignature(secHeader);
188 sign.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
189 sign.setCustomTokenId(encrKey.getId());
190 sign.setCustomTokenValueType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
191 sign.setSecretKey(symmetricKey.getEncoded());
192 sign.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
193
194 sign.build(crypto);
195 Document encryptedSignedDoc = encrypt.build(crypto, symmetricKey);
196
197 if (LOG.isDebugEnabled()) {
198 LOG.debug("Signed and encrypted message with IssuerSerial key identifier (both), 3DES:");
199 String outputString =
200 XMLUtils.prettyDocumentToString(encryptedSignedDoc);
201 LOG.debug(outputString);
202 }
203
204 LOG.info("After Sign/Encryption....");
205 verify(encryptedSignedDoc);
206 }
207
208
209
210
211
212 @Test
213 public void testSymmetricSignatureSHA1Handler() throws Exception {
214 final WSSConfig cfg = WSSConfig.getNewInstance();
215 RequestData reqData = new RequestData();
216 reqData.setWssConfig(cfg);
217 java.util.Map<String, Object> messageContext = new java.util.TreeMap<>();
218 messageContext.put(WSHandlerConstants.SIG_KEY_ID, "EncryptedKeySHA1");
219 messageContext.put(WSHandlerConstants.SIG_ALGO, SignatureMethod.HMAC_SHA1);
220 messageContext.put(WSHandlerConstants.PW_CALLBACK_REF, this);
221 reqData.setMsgContext(messageContext);
222 reqData.setUsername("");
223
224 final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
225 CustomHandler handler = new CustomHandler();
226 HandlerAction action = new HandlerAction(WSConstants.SIGN);
227 handler.send(
228 doc,
229 reqData,
230 Collections.singletonList(action),
231 true
232 );
233
234 String outputString =
235 XMLUtils.prettyDocumentToString(doc);
236 if (LOG.isDebugEnabled()) {
237 LOG.debug(outputString);
238 }
239
240 reqData = new RequestData();
241 reqData.setWssConfig(WSSConfig.getNewInstance());
242 messageContext = new java.util.TreeMap<>();
243 messageContext.put(WSHandlerConstants.PW_CALLBACK_REF, this);
244 reqData.setMsgContext(messageContext);
245 reqData.setUsername("");
246
247 handler.receive(Collections.singletonList(WSConstants.SIGN), reqData);
248
249 secEngine.processSecurityHeader(doc, null, this, null, crypto);
250 }
251
252
253
254
255
256
257
258
259
260 private void verify(Document doc) throws Exception {
261 secEngine.processSecurityHeader(doc, null, callbackHandler, null, crypto);
262 if (LOG.isDebugEnabled()) {
263 LOG.debug("Verfied and decrypted message:");
264 String outputString =
265 XMLUtils.prettyDocumentToString(doc);
266 LOG.debug(outputString);
267 }
268 }
269
270 public void handle(Callback[] callbacks)
271 throws IOException, UnsupportedCallbackException {
272 for (Callback callback : callbacks) {
273 if (callback instanceof WSPasswordCallback) {
274 WSPasswordCallback pc = (WSPasswordCallback) callback;
275
276
277
278
279
280
281 pc.setPassword("security");
282 pc.setKey(keyData);
283 } else {
284 throw new UnsupportedCallbackException(callback, "Unrecognized Callback");
285 }
286 }
287 }
288
289
290 }