1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.stax.utils;
20
21 import java.io.IOException;
22 import java.security.Key;
23 import java.security.MessageDigest;
24 import java.security.NoSuchAlgorithmException;
25 import java.security.cert.CertificateEncodingException;
26 import java.security.cert.CertificateException;
27 import java.security.cert.CertificateFactory;
28 import java.security.cert.X509Certificate;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Iterator;
32 import java.util.List;
33
34 import javax.security.auth.callback.Callback;
35 import javax.security.auth.callback.CallbackHandler;
36 import javax.security.auth.callback.UnsupportedCallbackException;
37 import javax.xml.namespace.QName;
38 import javax.xml.stream.XMLStreamException;
39 import javax.xml.stream.events.Attribute;
40
41 import org.apache.wss4j.common.crypto.Merlin;
42 import org.apache.wss4j.common.ext.WSSecurityException;
43 import org.apache.wss4j.stax.ext.WSSConstants;
44 import org.apache.wss4j.stax.ext.WSSSecurityProperties;
45 import org.apache.wss4j.stax.securityEvent.DerivedKeyTokenSecurityEvent;
46 import org.apache.wss4j.stax.securityEvent.EncryptedKeyTokenSecurityEvent;
47 import org.apache.wss4j.stax.securityEvent.HttpsTokenSecurityEvent;
48 import org.apache.wss4j.stax.securityEvent.KerberosTokenSecurityEvent;
49 import org.apache.wss4j.stax.securityEvent.KeyValueTokenSecurityEvent;
50 import org.apache.wss4j.stax.securityEvent.RelTokenSecurityEvent;
51 import org.apache.wss4j.stax.securityEvent.SamlTokenSecurityEvent;
52 import org.apache.wss4j.stax.securityEvent.SecurityContextTokenSecurityEvent;
53 import org.apache.wss4j.stax.securityEvent.UsernameTokenSecurityEvent;
54 import org.apache.wss4j.stax.securityEvent.X509TokenSecurityEvent;
55 import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
56 import org.apache.xml.security.exceptions.XMLSecurityException;
57 import org.apache.xml.security.stax.ext.AbstractOutputProcessor;
58 import org.apache.xml.security.stax.ext.OutputProcessorChain;
59 import org.apache.xml.security.stax.ext.SecurePart;
60 import org.apache.xml.security.stax.ext.XMLSecurityConstants;
61 import org.apache.xml.security.stax.ext.XMLSecurityUtils;
62 import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
63 import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
64 import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
65 import org.apache.xml.security.stax.impl.EncryptionPartDef;
66 import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
67 import org.apache.xml.security.stax.securityToken.InboundSecurityToken;
68 import org.apache.xml.security.stax.securityToken.SecurityToken;
69 import org.apache.xml.security.utils.XMLUtils;
70
71 public class WSSUtils extends XMLSecurityUtils {
72
73 protected WSSUtils() {
74 super();
75 }
76
77
78
79
80
81
82
83
84 public static void doPasswordCallback(CallbackHandler callbackHandler, Callback callback)
85 throws WSSecurityException {
86
87 if (callbackHandler == null) {
88 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noCallback");
89 }
90 try {
91 callbackHandler.handle(new Callback[]{callback});
92 } catch (IOException | UnsupportedCallbackException e) {
93 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
94 }
95 }
96
97
98
99
100
101
102
103 public static void doSecretKeyCallback(CallbackHandler callbackHandler, Callback callback)
104 throws WSSecurityException {
105
106 if (callbackHandler != null) {
107 try {
108 callbackHandler.handle(new Callback[]{callback});
109 } catch (IOException | UnsupportedCallbackException e) {
110 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e, "noPassword");
111 }
112 }
113 }
114
115 public static String getSOAPMessageVersionNamespace(XMLSecEvent xmlSecEvent) {
116 XMLSecStartElement xmlSecStartElement = xmlSecEvent.getStartElementAtLevel(1);
117 if (xmlSecStartElement != null) {
118 if (WSSConstants.TAG_SOAP11_ENVELOPE.equals(xmlSecStartElement.getName())) {
119 return WSSConstants.NS_SOAP11;
120 } else if (WSSConstants.TAG_SOAP12_ENVELOPE.equals(xmlSecStartElement.getName())) {
121 return WSSConstants.NS_SOAP12;
122 }
123 }
124 return null;
125 }
126
127 public static boolean isInSOAPHeader(XMLSecEvent xmlSecEvent) {
128 final List<QName> elementPath = xmlSecEvent.getElementPath();
129 return isInSOAPHeader(elementPath);
130 }
131
132 public static boolean isInSOAPHeader(List<QName> elementPath) {
133 if (elementPath.size() > 1) {
134 final QName secondLevelElementName = elementPath.get(1);
135 return WSSConstants.TAG_SOAP_HEADER_LN.equals(secondLevelElementName.getLocalPart())
136 && elementPath.get(0).getNamespaceURI().equals(secondLevelElementName.getNamespaceURI());
137 }
138 return false;
139 }
140
141 public static boolean isInSOAPBody(XMLSecEvent xmlSecEvent) {
142 final List<QName> elementPath = xmlSecEvent.getElementPath();
143 return isInSOAPBody(elementPath);
144 }
145
146 public static boolean isInSOAPBody(List<QName> elementPath) {
147 if (elementPath.size() > 1) {
148 final QName secondLevelElementName = elementPath.get(1);
149 return WSSConstants.TAG_SOAP_BODY_LN.equals(secondLevelElementName.getLocalPart())
150 && elementPath.get(0).getNamespaceURI().equals(secondLevelElementName.getNamespaceURI());
151 }
152 return false;
153 }
154
155 public static boolean isInSecurityHeader(XMLSecEvent xmlSecEvent, String actorOrRole) {
156 final List<QName> elementPath = xmlSecEvent.getElementPath();
157 return isInSecurityHeader(xmlSecEvent, elementPath, actorOrRole);
158 }
159
160 public static boolean isInSecurityHeader(XMLSecEvent xmlSecEvent, List<QName> elementPath, String actorOrRole) {
161 if (elementPath.size() > 2) {
162 final QName secondLevelElementName = elementPath.get(1);
163 return WSSConstants.TAG_WSSE_SECURITY.equals(elementPath.get(2))
164 && isResponsibleActorOrRole(xmlSecEvent.getStartElementAtLevel(3), actorOrRole)
165 && WSSConstants.TAG_SOAP_HEADER_LN.equals(secondLevelElementName.getLocalPart())
166 && elementPath.get(0).getNamespaceURI().equals(secondLevelElementName.getNamespaceURI());
167 }
168 return false;
169 }
170
171 public static boolean isSecurityHeaderElement(XMLSecEvent xmlSecEvent, String actorOrRole) {
172 if (!xmlSecEvent.isStartElement()) {
173 return false;
174 }
175
176 final List<QName> elementPath = xmlSecEvent.getElementPath();
177 if (elementPath.size() == 3) {
178 final QName secondLevelElementName = elementPath.get(1);
179 return WSSConstants.TAG_WSSE_SECURITY.equals(elementPath.get(2))
180 && isResponsibleActorOrRole(xmlSecEvent.getStartElementAtLevel(3), actorOrRole)
181 && WSSConstants.TAG_SOAP_HEADER_LN.equals(secondLevelElementName.getLocalPart())
182 && elementPath.get(0).getNamespaceURI().equals(secondLevelElementName.getNamespaceURI());
183 }
184 return false;
185 }
186
187 public static boolean isResponsibleActorOrRole(XMLSecStartElement xmlSecStartElement, String responsibleActor) {
188 final QName actorRole;
189 final String soapVersionNamespace = getSOAPMessageVersionNamespace(xmlSecStartElement);
190 if (WSSConstants.NS_SOAP11.equals(soapVersionNamespace)) {
191 actorRole = WSSConstants.ATT_SOAP11_ACTOR;
192 } else {
193 actorRole = WSSConstants.ATT_SOAP12_ROLE;
194 }
195
196 String actor = null;
197 Attribute attribute = xmlSecStartElement.getAttributeByName(actorRole);
198 if (attribute != null) {
199 actor = attribute.getValue();
200 }
201
202 if (responsibleActor == null) {
203 return actor == null;
204 } else {
205 return responsibleActor.equals(actor);
206 }
207 }
208
209 public static void createBinarySecurityTokenStructure(AbstractOutputProcessor abstractOutputProcessor,
210 OutputProcessorChain outputProcessorChain,
211 String referenceId, X509Certificate[] x509Certificates,
212 boolean useSingleCertificate)
213 throws XMLStreamException, XMLSecurityException {
214 String valueType;
215 if (useSingleCertificate) {
216 valueType = WSSConstants.NS_X509_V3_TYPE;
217 } else {
218 valueType = WSSConstants.NS_X509_PKIPATH_V1;
219 }
220 List<XMLSecAttribute> attributes = new ArrayList<>(3);
221 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE,
222 WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
223 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, valueType));
224 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_WSU_ID, referenceId));
225 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
226 WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN,
227 false, attributes);
228 try {
229 if (useSingleCertificate) {
230 String encodedCert =
231 XMLUtils.encodeToString(x509Certificates[0].getEncoded());
232 abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, encodedCert);
233 } else {
234 try {
235 CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
236 List<X509Certificate> certificates = Arrays.asList(x509Certificates);
237 String encodedCert =
238 XMLUtils.encodeToString(certificateFactory.generateCertPath(certificates).getEncoded());
239 abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, encodedCert);
240 } catch (CertificateException e) {
241 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
242 }
243 }
244 } catch (CertificateEncodingException e) {
245 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
246 }
247 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
248 WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN);
249 }
250
251 public static void createX509SubjectKeyIdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
252 OutputProcessorChain outputProcessorChain,
253 X509Certificate[] x509Certificates)
254 throws XMLSecurityException, XMLStreamException {
255
256 if (x509Certificates[0].getVersion() != 3) {
257 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidCertForSKI");
258 }
259
260 List<XMLSecAttribute> attributes = new ArrayList<>(2);
261 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE,
262 WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
263 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE,
264 WSSConstants.NS_X509_SKI));
265 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
266 WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
267 false, attributes);
268 byte[] data = new Merlin().getSKIBytesFromCert(x509Certificates[0]);
269 abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain,
270 XMLUtils.encodeToString(data));
271 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
272 WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
273 }
274
275 public static void createX509KeyIdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
276 OutputProcessorChain outputProcessorChain,
277 X509Certificate[] x509Certificates)
278 throws XMLStreamException, XMLSecurityException {
279 List<XMLSecAttribute> attributes = new ArrayList<>(2);
280 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE,
281 WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
282 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE,
283 WSSConstants.NS_X509_V3_TYPE));
284 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
285 WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
286 false, attributes);
287 try {
288 String encodedCert = XMLUtils.encodeToString(x509Certificates[0].getEncoded());
289 abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, encodedCert);
290 } catch (CertificateEncodingException e) {
291 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
292 }
293 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
294 WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
295 }
296
297 public static void createThumbprintKeyIdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
298 OutputProcessorChain outputProcessorChain,
299 X509Certificate[] x509Certificates)
300 throws XMLStreamException, XMLSecurityException {
301 List<XMLSecAttribute> attributes = new ArrayList<>(2);
302 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE,
303 WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
304 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE,
305 WSSConstants.NS_THUMBPRINT));
306 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
307 WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
308 false, attributes);
309 try {
310 MessageDigest sha = MessageDigest.getInstance("SHA-1");
311 byte[] data = sha.digest(x509Certificates[0].getEncoded());
312 abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain,
313 XMLUtils.encodeToString(data));
314 } catch (CertificateEncodingException | NoSuchAlgorithmException e) {
315 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
316 }
317 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
318 }
319
320 public static void createEncryptedKeySha1IdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
321 OutputProcessorChain outputProcessorChain, Key key)
322 throws XMLStreamException, XMLSecurityException {
323
324 try {
325 MessageDigest sha = MessageDigest.getInstance("SHA-1");
326 byte[] data = sha.digest(key.getEncoded());
327 createEncryptedKeySha1IdentifierStructure(abstractOutputProcessor, outputProcessorChain,
328 XMLUtils.encodeToString(data));
329 } catch (NoSuchAlgorithmException e) {
330 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
331 }
332 }
333
334 public static void createEncryptedKeySha1IdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
335 OutputProcessorChain outputProcessorChain, String identifier)
336 throws XMLStreamException, XMLSecurityException {
337
338 List<XMLSecAttribute> attributes = new ArrayList<>(2);
339 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE,
340 WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
341 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE,
342 WSSConstants.NS_ENCRYPTED_KEY_SHA1));
343 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
344 false, attributes);
345 abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, identifier);
346 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
347 }
348
349 public static void createKerberosSha1IdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
350 OutputProcessorChain outputProcessorChain, String identifier)
351 throws XMLStreamException, XMLSecurityException {
352
353 List<XMLSecAttribute> attributes = new ArrayList<>(2);
354 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE,
355 WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
356 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE,
357 WSSConstants.NS_KERBEROS5_AP_REQ_SHA1));
358 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
359 false, attributes);
360 abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, identifier);
361 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
362 }
363
364 public static void createBSTReferenceStructure(AbstractOutputProcessor abstractOutputProcessor,
365 OutputProcessorChain outputProcessorChain, String referenceId,
366 String valueType, boolean includedInMessage)
367 throws XMLStreamException, XMLSecurityException {
368 List<XMLSecAttribute> attributes = new ArrayList<>(2);
369 String uri = includedInMessage ? "#" + referenceId : referenceId;
370 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_URI, uri));
371 if (valueType != null) {
372 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, valueType));
373 }
374 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_REFERENCE,
375 false, attributes);
376 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_REFERENCE);
377 }
378
379 public static void createEmbeddedKeyIdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
380 OutputProcessorChain outputProcessorChain,
381 WSSecurityTokenConstants.TokenType tokenType, String referenceId)
382 throws XMLStreamException, XMLSecurityException {
383 List<XMLSecAttribute> attributes = new ArrayList<>(1);
384 if (WSSecurityTokenConstants.SAML_10_TOKEN.equals(tokenType) || WSSecurityTokenConstants.SAML_11_TOKEN.equals(tokenType)) {
385 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, WSSConstants.NS_SAML10_TYPE));
386 } else if (WSSecurityTokenConstants.SAML_20_TOKEN.equals(tokenType)) {
387 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, WSSConstants.NS_SAML20_TYPE));
388 }
389 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
390 false, attributes);
391 abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, referenceId);
392 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
393 }
394
395 public static void createSAMLKeyIdentifierStructure(AbstractOutputProcessor abstractOutputProcessor,
396 OutputProcessorChain outputProcessorChain,
397 WSSecurityTokenConstants.TokenType tokenType, String referenceId)
398 throws XMLStreamException, XMLSecurityException {
399 List<XMLSecAttribute> attributes = new ArrayList<>(1);
400 if (WSSecurityTokenConstants.SAML_10_TOKEN.equals(tokenType) || WSSecurityTokenConstants.SAML_11_TOKEN.equals(tokenType)) {
401 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, WSSConstants.NS_SAML10_TYPE));
402 } else if (WSSecurityTokenConstants.SAML_20_TOKEN.equals(tokenType)) {
403 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, WSSConstants.NS_SAML20_TYPE));
404 }
405 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER,
406 false, attributes);
407 abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, referenceId);
408 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_KEY_IDENTIFIER);
409 }
410
411 public static void createUsernameTokenReferenceStructure(AbstractOutputProcessor abstractOutputProcessor,
412 OutputProcessorChain outputProcessorChain, String tokenId)
413 throws XMLStreamException, XMLSecurityException {
414 List<XMLSecAttribute> attributes = new ArrayList<>(2);
415 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_URI, "#" + tokenId));
416 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE,
417 WSSConstants.NS_USERNAMETOKEN_PROFILE_USERNAME_TOKEN));
418 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_REFERENCE,
419 false, attributes);
420 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain, WSSConstants.TAG_WSSE_REFERENCE);
421 }
422
423 public static void createReferenceListStructureForEncryption(AbstractOutputProcessor abstractOutputProcessor,
424 OutputProcessorChain outputProcessorChain)
425 throws XMLStreamException, XMLSecurityException {
426 List<EncryptionPartDef> encryptionPartDefs =
427 outputProcessorChain.getSecurityContext().getAsList(EncryptionPartDef.class);
428 if (encryptionPartDefs == null) {
429 return;
430 }
431 List<XMLSecAttribute> attributes;
432 abstractOutputProcessor.createStartElementAndOutputAsEvent(
433 outputProcessorChain, XMLSecurityConstants.TAG_xenc_ReferenceList, true, null);
434
435 Iterator<EncryptionPartDef> encryptionPartDefIterator = encryptionPartDefs.iterator();
436 while (encryptionPartDefIterator.hasNext()) {
437 EncryptionPartDef encryptionPartDef = encryptionPartDefIterator.next();
438
439 attributes = new ArrayList<>(1);
440 attributes.add(abstractOutputProcessor.createAttribute(
441 XMLSecurityConstants.ATT_NULL_URI, "#" + encryptionPartDef.getEncRefId()));
442 abstractOutputProcessor.createStartElementAndOutputAsEvent(
443 outputProcessorChain, XMLSecurityConstants.TAG_xenc_DataReference, false, attributes);
444 final String compressionAlgorithm =
445 ((WSSSecurityProperties)abstractOutputProcessor.getSecurityProperties()).getEncryptionCompressionAlgorithm();
446 if (compressionAlgorithm != null) {
447 abstractOutputProcessor.createStartElementAndOutputAsEvent(
448 outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transforms, true, null);
449 attributes = new ArrayList<>(1);
450 attributes.add(abstractOutputProcessor.createAttribute(
451 XMLSecurityConstants.ATT_NULL_Algorithm, compressionAlgorithm));
452 abstractOutputProcessor.createStartElementAndOutputAsEvent(
453 outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transform, false, attributes);
454 abstractOutputProcessor.createEndElementAndOutputAsEvent(
455 outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transform);
456 abstractOutputProcessor.createEndElementAndOutputAsEvent(
457 outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transforms);
458 }
459 abstractOutputProcessor.createEndElementAndOutputAsEvent(
460 outputProcessorChain, XMLSecurityConstants.TAG_xenc_DataReference);
461 }
462 abstractOutputProcessor.createEndElementAndOutputAsEvent(
463 outputProcessorChain, XMLSecurityConstants.TAG_xenc_ReferenceList);
464 }
465
466 public static void createEncryptedDataStructureForAttachments(
467 AbstractOutputProcessor abstractOutputProcessor, OutputProcessorChain outputProcessorChain)
468 throws XMLStreamException, XMLSecurityException {
469
470 List<EncryptionPartDef> encryptionPartDefs =
471 outputProcessorChain.getSecurityContext().getAsList(EncryptionPartDef.class);
472 if (encryptionPartDefs == null) {
473 return;
474 }
475
476 Iterator<EncryptionPartDef> encryptionPartDefIterator = encryptionPartDefs.iterator();
477 while (encryptionPartDefIterator.hasNext()) {
478 EncryptionPartDef encryptionPartDef = encryptionPartDefIterator.next();
479
480 if (encryptionPartDef.getCipherReferenceId() == null) {
481 continue;
482 }
483
484 List<XMLSecAttribute> attributes = new ArrayList<>(3);
485 attributes.add(abstractOutputProcessor.createAttribute(XMLSecurityConstants.ATT_NULL_Id,
486 encryptionPartDef.getEncRefId()));
487 if (encryptionPartDef.getModifier() == SecurePart.Modifier.Element) {
488 attributes.add(
489 abstractOutputProcessor.createAttribute(XMLSecurityConstants.ATT_NULL_Type,
490 WSSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE));
491 } else {
492 attributes.add(
493 abstractOutputProcessor.createAttribute(XMLSecurityConstants.ATT_NULL_Type,
494 WSSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_CONTENT_ONLY));
495 }
496 attributes.add(
497 abstractOutputProcessor.createAttribute(XMLSecurityConstants.ATT_NULL_MimeType,
498 encryptionPartDef.getMimeType()));
499 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
500 XMLSecurityConstants.TAG_xenc_EncryptedData, true, attributes);
501
502 attributes = new ArrayList<>(1);
503 attributes.add(abstractOutputProcessor.createAttribute(XMLSecurityConstants.ATT_NULL_Algorithm,
504 abstractOutputProcessor.getSecurityProperties().getEncryptionSymAlgorithm()));
505 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
506 XMLSecurityConstants.TAG_xenc_EncryptionMethod, false, attributes);
507
508 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
509 XMLSecurityConstants.TAG_xenc_EncryptionMethod);
510
511 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
512 XMLSecurityConstants.TAG_dsig_KeyInfo, true, null);
513
514 attributes = new ArrayList<>(1);
515 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_WSSE11_TOKEN_TYPE,
516 WSSConstants.NS_WSS_ENC_KEY_VALUE_TYPE));
517 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
518 WSSConstants.TAG_WSSE_SECURITY_TOKEN_REFERENCE, true, attributes);
519
520 attributes = new ArrayList<>(1);
521 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_URI,
522 "#" + encryptionPartDef.getKeyId()));
523 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
524 WSSConstants.TAG_WSSE_REFERENCE, false, attributes);
525 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
526 WSSConstants.TAG_WSSE_REFERENCE);
527 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
528 WSSConstants.TAG_WSSE_SECURITY_TOKEN_REFERENCE);
529 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
530 XMLSecurityConstants.TAG_dsig_KeyInfo);
531
532 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
533 XMLSecurityConstants.TAG_xenc_CipherData, false, null);
534
535 attributes = new ArrayList<>(1);
536 attributes.add(abstractOutputProcessor.createAttribute(WSSConstants.ATT_NULL_URI,
537 "cid:" + encryptionPartDef.getCipherReferenceId()));
538 abstractOutputProcessor.createStartElementAndOutputAsEvent(outputProcessorChain,
539 XMLSecurityConstants.TAG_xenc_CipherReference, false, attributes);
540
541 abstractOutputProcessor.createStartElementAndOutputAsEvent(
542 outputProcessorChain, XMLSecurityConstants.TAG_xenc_Transforms, false, null);
543
544 attributes = new ArrayList<>(1);
545 attributes.add(abstractOutputProcessor.createAttribute(
546 XMLSecurityConstants.ATT_NULL_Algorithm, WSSConstants.SWA_ATTACHMENT_CIPHERTEXT_TRANS));
547 abstractOutputProcessor.createStartElementAndOutputAsEvent(
548 outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transform, true, attributes);
549 abstractOutputProcessor.createEndElementAndOutputAsEvent(
550 outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transform);
551 abstractOutputProcessor.createEndElementAndOutputAsEvent(
552 outputProcessorChain, XMLSecurityConstants.TAG_dsig_Transforms);
553
554 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
555 XMLSecurityConstants.TAG_xenc_CipherReference);
556 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
557 XMLSecurityConstants.TAG_xenc_CipherData);
558 abstractOutputProcessor.createEndElementAndOutputAsEvent(outputProcessorChain,
559 XMLSecurityConstants.TAG_xenc_EncryptedData);
560 }
561 }
562
563 @SuppressWarnings("unchecked")
564 public static TokenSecurityEvent<? extends InboundSecurityToken>
565 createTokenSecurityEvent(final InboundSecurityToken inboundSecurityToken, String correlationID)
566 throws WSSecurityException {
567 WSSecurityTokenConstants.TokenType tokenType = inboundSecurityToken.getTokenType();
568
569 TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent;
570 if (WSSecurityTokenConstants.X509V1Token.equals(tokenType)
571 || WSSecurityTokenConstants.X509V3Token.equals(tokenType)
572 || WSSecurityTokenConstants.X509Pkcs7Token.equals(tokenType)
573 || WSSecurityTokenConstants.X509PkiPathV1Token.equals(tokenType)) {
574 tokenSecurityEvent = new X509TokenSecurityEvent();
575 } else if (WSSecurityTokenConstants.USERNAME_TOKEN.equals(tokenType)) {
576 tokenSecurityEvent = new UsernameTokenSecurityEvent();
577 } else if (WSSecurityTokenConstants.KERBEROS_TOKEN.equals(tokenType)) {
578 tokenSecurityEvent = new KerberosTokenSecurityEvent();
579 } else if (WSSecurityTokenConstants.SECURITY_CONTEXT_TOKEN.equals(tokenType)) {
580 tokenSecurityEvent = new SecurityContextTokenSecurityEvent();
581 } else if (WSSecurityTokenConstants.SAML_10_TOKEN.equals(tokenType)
582 || WSSecurityTokenConstants.SAML_11_TOKEN.equals(tokenType)
583 || WSSecurityTokenConstants.SAML_20_TOKEN.equals(tokenType)) {
584 tokenSecurityEvent = new SamlTokenSecurityEvent();
585 } else if (WSSecurityTokenConstants.REL_TOKEN.equals(tokenType)) {
586 tokenSecurityEvent = new RelTokenSecurityEvent();
587 } else if (WSSecurityTokenConstants.HTTPS_TOKEN.equals(tokenType)) {
588 tokenSecurityEvent = new HttpsTokenSecurityEvent();
589 } else if (WSSecurityTokenConstants.KeyValueToken.equals(tokenType)) {
590 tokenSecurityEvent = new KeyValueTokenSecurityEvent();
591 } else if (WSSecurityTokenConstants.DerivedKeyToken.equals(tokenType)) {
592 tokenSecurityEvent = new DerivedKeyTokenSecurityEvent();
593 } else if (WSSecurityTokenConstants.EncryptedKeyToken.equals(tokenType)) {
594 tokenSecurityEvent = new EncryptedKeyTokenSecurityEvent();
595 } else {
596 throw new WSSecurityException(WSSecurityException.ErrorCode.UNSUPPORTED_SECURITY_TOKEN);
597 }
598 ((TokenSecurityEvent<SecurityToken>)tokenSecurityEvent).setSecurityToken(inboundSecurityToken);
599 tokenSecurityEvent.setCorrelationID(correlationID);
600 return (TokenSecurityEvent<? extends InboundSecurityToken>)tokenSecurityEvent;
601 }
602
603 public static boolean pathMatches(List<QName> path1, List<QName> path2) {
604 return pathMatches(path1, path2, false);
605 }
606
607 public static boolean pathMatches(List<QName> path1, List<QName> path2, boolean lastElementWildCard) {
608 if (path1 == null) {
609 throw new IllegalArgumentException("Internal error");
610 }
611 if (path2 == null || path1.size() != path2.size()) {
612 return false;
613 }
614 Iterator<QName> path1Iterator = path1.iterator();
615 Iterator<QName> path2Iterator = path2.iterator();
616 while (path1Iterator.hasNext()) {
617 QName qName1 = path1Iterator.next();
618 QName qName2 = path2Iterator.next();
619 if (!qName1.equals(qName2)) {
620 if (!path1Iterator.hasNext() && lastElementWildCard) {
621 if (!qName1.getNamespaceURI().equals(qName2.getNamespaceURI())) {
622 return false;
623 }
624 } else {
625 return false;
626 }
627 }
628 }
629 return true;
630 }
631
632 public static String pathAsString(List<QName> path) {
633 StringBuilder stringBuilder = new StringBuilder();
634 Iterator<QName> pathIterator = path.iterator();
635 while (pathIterator.hasNext()) {
636 QName qName = pathIterator.next();
637 stringBuilder.append('/');
638 stringBuilder.append(qName.toString());
639 }
640 return stringBuilder.toString();
641 }
642
643 @SuppressWarnings("unchecked")
644 public static <T extends SecurityToken> T getRootToken(T securityToken) throws XMLSecurityException {
645 T tmp = securityToken;
646 while (tmp.getKeyWrappingToken() != null) {
647 tmp = (T)tmp.getKeyWrappingToken();
648 }
649 return tmp;
650 }
651
652 }