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.saml;
21
22 import javax.xml.crypto.dsig.CanonicalizationMethod;
23 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
24 import org.apache.wss4j.common.util.SOAPUtil;
25 import org.w3c.dom.Document;
26 import org.w3c.dom.Element;
27 import org.apache.wss4j.common.crypto.AlgorithmSuite;
28 import org.apache.wss4j.common.crypto.Crypto;
29 import org.apache.wss4j.common.crypto.CryptoFactory;
30 import org.apache.wss4j.common.ext.WSSecurityException;
31 import org.apache.wss4j.dom.WSConstants;
32 import org.apache.wss4j.dom.common.SAML1CallbackHandler;
33
34 import org.apache.wss4j.dom.engine.WSSConfig;
35 import org.apache.wss4j.dom.engine.WSSecurityEngine;
36 import org.apache.wss4j.dom.handler.RequestData;
37 import org.apache.wss4j.dom.handler.WSHandlerResult;
38 import org.apache.wss4j.dom.message.WSSecHeader;
39 import org.apache.wss4j.dom.message.WSSecSAMLToken;
40 import org.apache.wss4j.common.saml.SAMLCallback;
41 import org.apache.wss4j.common.saml.SAMLUtil;
42 import org.apache.wss4j.common.saml.builder.SAML1Constants;
43 import org.apache.wss4j.common.util.XMLUtils;
44 import org.apache.wss4j.dom.util.WSSecurityUtil;
45
46 import org.junit.jupiter.api.Test;
47
48 import static org.junit.jupiter.api.Assertions.assertTrue;
49 import static org.junit.jupiter.api.Assertions.fail;
50
51
52
53
54
55 public class SamlAlgorithmSuiteTest {
56 private static final org.slf4j.Logger LOG =
57 org.slf4j.LoggerFactory.getLogger(SamlAlgorithmSuiteTest.class);
58 private Crypto crypto;
59
60 public SamlAlgorithmSuiteTest() throws Exception {
61 WSSConfig.init();
62 crypto = CryptoFactory.getInstance("crypto.properties");
63 }
64
65 @Test
66 public void testSignedSAML11Assertion() throws Exception {
67 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
68 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
69 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
70 callbackHandler.setIssuer("www.example.com");
71
72 SAMLCallback samlCallback = new SAMLCallback();
73 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
74 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
75
76 samlAssertion.signAssertion("16c73ab6-b892-458f-abf5-2f875f74882e", "security", crypto, false);
77
78
79 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
80 WSSecHeader secHeader = new WSSecHeader(doc);
81 secHeader.insertSecurityHeader();
82
83 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
84 Document signedDoc = wsSign.build(samlAssertion);
85
86 if (LOG.isDebugEnabled()) {
87 String outputString =
88 XMLUtils.prettyDocumentToString(signedDoc);
89 LOG.debug(outputString);
90 }
91
92 Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
93 AlgorithmSuite algorithmSuite = createAlgorithmSuite();
94
95 verify(securityHeader, algorithmSuite, crypto);
96
97 algorithmSuite.setMinimumAsymmetricKeyLength(1024);
98
99 try {
100 verify(securityHeader, algorithmSuite, crypto);
101 fail("Expected failure as 512-bit keys are not allowed");
102 } catch (WSSecurityException ex) {
103 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
104 }
105 }
106
107 @Test
108 public void testDSASignedSAML11Assertion() throws Exception {
109 Crypto dsaCrypto = CryptoFactory.getInstance("wss40.properties");
110
111 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
112 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
113 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
114 callbackHandler.setIssuer("www.example.com");
115
116 SAMLCallback samlCallback = new SAMLCallback();
117 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
118 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
119
120 samlAssertion.signAssertion("wss40DSA", "security", dsaCrypto, false);
121
122 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
123 WSSecHeader secHeader = new WSSecHeader(doc);
124 secHeader.insertSecurityHeader();
125
126 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
127
128 Document signedDoc = wsSign.build(samlAssertion);
129
130 if (LOG.isDebugEnabled()) {
131 String outputString =
132 XMLUtils.prettyDocumentToString(signedDoc);
133 LOG.debug(outputString);
134 }
135
136 Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
137 AlgorithmSuite algorithmSuite = createAlgorithmSuite();
138
139 try {
140 verify(securityHeader, algorithmSuite, dsaCrypto);
141 fail("Expected failure as DSA is not allowed");
142 } catch (WSSecurityException ex) {
143 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
144 }
145
146 algorithmSuite.addSignatureMethod(WSConstants.DSA);
147 verify(securityHeader, algorithmSuite, dsaCrypto);
148 }
149
150 @Test
151 public void testC14nMethod() throws Exception {
152 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
153 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
154 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
155 callbackHandler.setIssuer("www.example.com");
156
157 SAMLCallback samlCallback = new SAMLCallback();
158 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
159 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
160
161 samlAssertion.signAssertion(
162 "16c73ab6-b892-458f-abf5-2f875f74882e", "security", crypto, false,
163 WSConstants.C14N_EXCL_WITH_COMMENTS, WSConstants.RSA_SHA1);
164
165
166 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
167 WSSecHeader secHeader = new WSSecHeader(doc);
168 secHeader.insertSecurityHeader();
169
170 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
171
172 Document signedDoc = wsSign.build(samlAssertion);
173
174 if (LOG.isDebugEnabled()) {
175 String outputString =
176 XMLUtils.prettyDocumentToString(signedDoc);
177 LOG.debug(outputString);
178 }
179
180 Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
181 AlgorithmSuite algorithmSuite = createAlgorithmSuite();
182
183 try {
184 verify(securityHeader, algorithmSuite, crypto);
185 fail("Expected failure as C14n algorithm is not allowed");
186 } catch (WSSecurityException ex) {
187 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
188 }
189
190 algorithmSuite.addC14nAlgorithm(WSConstants.C14N_EXCL_WITH_COMMENTS);
191 verify(securityHeader, algorithmSuite, crypto);
192 }
193
194 @Test
195 public void signWithEcdsaAlgorithmSHA1() throws Exception {
196 crypto = CryptoFactory.getInstance("wss40.properties");
197 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
198 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
199 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
200 callbackHandler.setIssuer("www.example.com");
201
202 SAMLCallback samlCallback = new SAMLCallback();
203 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
204 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
205
206 samlAssertion.signAssertion(
207 "wss40ec", "security", crypto, false,
208 CanonicalizationMethod.EXCLUSIVE, WSConstants.ECDSA_SHA1);
209
210
211 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
212 WSSecHeader secHeader = new WSSecHeader(doc);
213 secHeader.insertSecurityHeader();
214
215 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
216
217 Document signedDoc = wsSign.build(samlAssertion);
218
219 if (LOG.isDebugEnabled()) {
220 String outputString =
221 XMLUtils.prettyDocumentToString(signedDoc);
222 LOG.debug(outputString);
223 }
224
225 Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
226 AlgorithmSuite algorithmSuite = createAlgorithmSuite();
227
228 try {
229 verify(securityHeader, algorithmSuite, crypto);
230 fail("Expected failure as C14n algorithm is not allowed");
231 } catch (WSSecurityException ex) {
232 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
233 }
234
235 algorithmSuite.addSignatureMethod(WSConstants.ECDSA_SHA1);
236
237 verify(securityHeader, algorithmSuite, crypto);
238 }
239
240 @Test
241 public void signWithEcdsaAlgorithmSHA256() throws Exception {
242 crypto = CryptoFactory.getInstance("wss40.properties");
243 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
244 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
245 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
246 callbackHandler.setIssuer("www.example.com");
247
248 SAMLCallback samlCallback = new SAMLCallback();
249 SAMLUtil.doSAMLCallback(callbackHandler, samlCallback);
250 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
251
252 samlAssertion.signAssertion(
253 "wss40ec", "security", crypto, false,
254 CanonicalizationMethod.EXCLUSIVE, WSConstants.ECDSA_SHA256);
255
256
257 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
258 WSSecHeader secHeader = new WSSecHeader(doc);
259 secHeader.insertSecurityHeader();
260
261 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
262
263 Document signedDoc = wsSign.build(samlAssertion);
264
265 if (LOG.isDebugEnabled()) {
266 String outputString =
267 XMLUtils.prettyDocumentToString(signedDoc);
268 LOG.debug(outputString);
269 }
270
271 Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
272 AlgorithmSuite algorithmSuite = createAlgorithmSuite();
273
274 try {
275 verify(securityHeader, algorithmSuite, crypto);
276 fail("Expected failure as C14n algorithm is not allowed");
277 } catch (WSSecurityException ex) {
278 assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.INVALID_SECURITY);
279 }
280
281 algorithmSuite.addSignatureMethod(WSConstants.ECDSA_SHA256);
282
283 verify(securityHeader, algorithmSuite, crypto);
284 }
285
286 private AlgorithmSuite createAlgorithmSuite() {
287 AlgorithmSuite algorithmSuite = new AlgorithmSuite();
288 algorithmSuite.addSignatureMethod(WSConstants.RSA_SHA1);
289 algorithmSuite.setMinimumAsymmetricKeyLength(512);
290 algorithmSuite.addC14nAlgorithm(WSConstants.C14N_EXCL_OMIT_COMMENTS);
291 algorithmSuite.addDigestAlgorithm(WSConstants.SHA1);
292
293 return algorithmSuite;
294 }
295
296 private WSHandlerResult verify(
297 Element securityHeader, AlgorithmSuite algorithmSuite, Crypto sigVerCrypto
298 ) throws Exception {
299 WSSecurityEngine secEngine = new WSSecurityEngine();
300 RequestData data = new RequestData();
301 data.setSigVerCrypto(sigVerCrypto);
302 data.setSamlAlgorithmSuite(algorithmSuite);
303 data.setValidateSamlSubjectConfirmation(false);
304
305 return secEngine.processSecurityHeader(securityHeader, data);
306 }
307
308
309 }