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.security.Provider;
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import javax.crypto.SecretKey;
27 import javax.crypto.spec.SecretKeySpec;
28 import javax.security.auth.DestroyFailedException;
29
30 import org.apache.wss4j.common.WSEncryptionPart;
31 import org.apache.wss4j.common.crypto.Crypto;
32 import org.apache.wss4j.common.ext.WSSecurityException;
33 import org.apache.wss4j.common.token.Reference;
34 import org.apache.wss4j.common.token.SecurityTokenReference;
35 import org.apache.wss4j.common.util.XMLUtils;
36 import org.apache.wss4j.dom.WSConstants;
37 import org.apache.wss4j.dom.message.token.KerberosSecurity;
38 import org.apache.wss4j.dom.util.WSSecurityUtil;
39 import org.apache.xml.security.algorithms.JCEMapper;
40 import org.apache.xml.security.encryption.Serializer;
41 import org.apache.xml.security.keys.KeyInfo;
42 import org.w3c.dom.Document;
43 import org.w3c.dom.Element;
44
45
46
47
48
49 public class WSSecEncrypt extends WSSecEncryptedKey {
50 private static final org.slf4j.Logger LOG =
51 org.slf4j.LoggerFactory.getLogger(WSSecEncrypt.class);
52
53
54
55
56 private SecurityTokenReference securityTokenReference;
57
58
59
60
61
62 private boolean encryptSymmKey = true;
63
64
65
66
67 private String customReferenceValue;
68
69
70
71
72 private boolean encKeyIdDirectId;
73
74 private boolean embedEncryptedKey;
75
76 private List<Element> attachmentEncryptedDataElements;
77
78 private Serializer encryptionSerializer;
79
80
81
82
83 private String symEncAlgo = WSConstants.AES_128;
84
85 public WSSecEncrypt(WSSecHeader securityHeader) {
86 super(securityHeader);
87 }
88
89 public WSSecEncrypt(Document doc) {
90 super(doc);
91 }
92
93 public WSSecEncrypt(Document doc, Provider provider) {
94 super(doc, provider);
95 }
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111 public void prepare(Crypto crypto, SecretKey symmetricKey) throws WSSecurityException {
112 attachmentEncryptedDataElements = new ArrayList<>();
113
114 if (encryptSymmKey) {
115 super.prepare(crypto, symmetricKey);
116 } else {
117 setEncryptedKeySHA1(symmetricKey.getEncoded());
118 }
119 }
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134 public Document build(Crypto crypto, SecretKey symmetricKey)
135 throws WSSecurityException {
136
137 prepare(crypto, symmetricKey);
138
139 LOG.debug("Beginning Encryption...");
140
141 Element refs = encrypt(symmetricKey);
142
143 addAttachmentEncryptedDataElements();
144 if (getEncryptedKeyElement() != null) {
145 addInternalRefElement(refs);
146 prependToHeader();
147 } else {
148 addExternalRefElement(refs);
149 }
150
151 prependBSTElementToHeader();
152
153 LOG.debug("Encryption complete.");
154 return getDocument();
155 }
156
157
158
159
160
161
162
163 public Element encrypt(SecretKey symmetricKey) throws WSSecurityException {
164 if (getParts().isEmpty()) {
165 getParts().add(WSSecurityUtil.getDefaultEncryptionPart(getDocument()));
166 }
167
168 return encryptForRef(null, getParts(), symmetricKey);
169 }
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 public Element encryptForRef(
194 Element dataRef,
195 List<WSEncryptionPart> references,
196 SecretKey symmetricKey
197 ) throws WSSecurityException {
198 KeyInfo keyInfo = createKeyInfo();
199
200
201
202 String keyAlgorithm = JCEMapper.getJCEKeyAlgorithmFromURI(getSymmetricEncAlgorithm());
203 SecretKeySpec secretKeySpec = new SecretKeySpec(symmetricKey.getEncoded(), keyAlgorithm);
204
205 Encryptor encryptor = new Encryptor();
206 encryptor.setDoc(getDocument());
207 encryptor.setSecurityHeader(getSecurityHeader());
208 encryptor.setIdAllocator(getIdAllocator());
209 encryptor.setCallbackLookup(callbackLookup);
210 encryptor.setAttachmentCallbackHandler(attachmentCallbackHandler);
211 encryptor.setStoreBytesInAttachment(storeBytesInAttachment);
212 encryptor.setEncryptionSerializer(getEncryptionSerializer());
213 encryptor.setExpandXopInclude(isExpandXopInclude());
214 encryptor.setWsDocInfo(getWsDocInfo());
215 List<String> encDataRefs =
216 encryptor.doEncryption(keyInfo, secretKeySpec, getSymmetricEncAlgorithm(), references, attachmentEncryptedDataElements);
217
218
219 try {
220 secretKeySpec.destroy();
221 } catch (DestroyFailedException e) {
222 LOG.debug("Error destroying key: {}", e.getMessage());
223 }
224
225 if (encDataRefs.isEmpty()) {
226 return null;
227 }
228
229 if (dataRef == null) {
230 dataRef =
231 getDocument().createElementNS(
232 WSConstants.ENC_NS,
233 WSConstants.ENC_PREFIX + ":ReferenceList"
234 );
235
236
237
238
239 if (!encryptSymmKey) {
240 XMLUtils.setNamespace(
241 dataRef, WSConstants.ENC_NS, WSConstants.ENC_PREFIX
242 );
243 }
244 }
245 return createDataRefList(getDocument(), dataRef, encDataRefs);
246 }
247
248
249
250
251
252
253
254
255
256
257 public void addInternalRefElement(Element dataRef) {
258 if (dataRef != null) {
259 getEncryptedKeyElement().appendChild(dataRef);
260 }
261 }
262
263
264
265
266
267
268
269
270
271
272 public void addExternalRefElement(Element dataRef) {
273 if (dataRef != null) {
274 Element secHeaderElement = getSecurityHeader().getSecurityHeaderElement();
275 WSSecurityUtil.prependChildElement(secHeaderElement, dataRef);
276 }
277 }
278
279 public void addAttachmentEncryptedDataElements() {
280 if (attachmentEncryptedDataElements != null) {
281 for (Element encryptedData : attachmentEncryptedDataElements) {
282 Element secHeaderElement = getSecurityHeader().getSecurityHeaderElement();
283 WSSecurityUtil.prependChildElement(secHeaderElement, encryptedData);
284 }
285 }
286 }
287
288
289
290
291 private KeyInfo createKeyInfo() throws WSSecurityException {
292
293 KeyInfo keyInfo = new KeyInfo(getDocument());
294 if (embedEncryptedKey) {
295 keyInfo.addUnknownElement(getEncryptedKeyElement());
296 } else if (keyIdentifierType == WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER) {
297 SecurityTokenReference secToken = new SecurityTokenReference(getDocument());
298 if (addWSUNamespace) {
299 secToken.addWSUNamespace();
300 }
301 secToken.addWSSENamespace();
302 if (customReferenceValue != null) {
303 secToken.setKeyIdentifierEncKeySHA1(customReferenceValue);
304 } else {
305 secToken.setKeyIdentifierEncKeySHA1(getEncryptedKeySHA1());
306 }
307 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
308 keyInfo.addUnknownElement(secToken.getElement());
309 } else if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customReferenceValue)) {
310 SecurityTokenReference secToken = new SecurityTokenReference(getDocument());
311 if (addWSUNamespace) {
312 secToken.addWSUNamespace();
313 }
314 secToken.addWSSENamespace();
315 secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
316 secToken.setKeyIdentifier(WSConstants.WSS_SAML_KI_VALUE_TYPE, getId());
317 keyInfo.addUnknownElement(secToken.getElement());
318 } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customReferenceValue)) {
319 SecurityTokenReference secToken = new SecurityTokenReference(getDocument());
320 if (addWSUNamespace) {
321 secToken.addWSUNamespace();
322 }
323 secToken.addWSSENamespace();
324 secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
325 secToken.setKeyIdentifier(WSConstants.WSS_SAML2_KI_VALUE_TYPE, getId());
326 keyInfo.addUnknownElement(secToken.getElement());
327 } else if (WSConstants.WSS_KRB_KI_VALUE_TYPE.equals(customReferenceValue)) {
328 SecurityTokenReference secToken = new SecurityTokenReference(getDocument());
329 if (addWSUNamespace) {
330 secToken.addWSUNamespace();
331 }
332 secToken.addWSSENamespace();
333 secToken.addTokenType(WSConstants.WSS_GSS_KRB_V5_AP_REQ);
334 secToken.setKeyIdentifier(customReferenceValue, getId(), true);
335 keyInfo.addUnknownElement(secToken.getElement());
336 } else if (securityTokenReference != null) {
337 Element tmpE = securityTokenReference.getElement();
338 tmpE.setAttributeNS(
339 WSConstants.XMLNS_NS, "xmlns:" + tmpE.getPrefix(), tmpE.getNamespaceURI()
340 );
341 keyInfo.addUnknownElement(securityTokenReference.getElement());
342 } else if (getId() != null) {
343 SecurityTokenReference secToken = new SecurityTokenReference(getDocument());
344 if (addWSUNamespace) {
345 secToken.addWSUNamespace();
346 }
347 secToken.addWSSENamespace();
348 Reference ref = new Reference(getDocument());
349 if (encKeyIdDirectId) {
350 ref.setURI(getId());
351 } else {
352 ref.setURI("#" + getId());
353 }
354 if (customReferenceValue != null) {
355 ref.setValueType(customReferenceValue);
356 }
357 secToken.setReference(ref);
358 if (KerberosSecurity.isKerberosToken(customReferenceValue)) {
359 secToken.addTokenType(customReferenceValue);
360 } else if (!WSConstants.WSS_USERNAME_TOKEN_VALUE_TYPE.equals(customReferenceValue)) {
361 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
362 }
363 keyInfo.addUnknownElement(secToken.getElement());
364 } else if (!encryptSymmKey && (keyIdentifierType == WSConstants.ISSUER_SERIAL
365 || keyIdentifierType == WSConstants.ISSUER_SERIAL_QUOTE_FORMAT)) {
366 SecurityTokenReference secToken = new SecurityTokenReference(getDocument());
367 if (addWSUNamespace) {
368 secToken.addWSUNamespace();
369 }
370 secToken.addWSSENamespace();
371 if (customReferenceValue != null) {
372 secToken.setKeyIdentifierEncKeySHA1(customReferenceValue);
373 } else {
374 secToken.setKeyIdentifierEncKeySHA1(getEncryptedKeySHA1());
375 }
376 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
377 keyInfo.addUnknownElement(secToken.getElement());
378 }
379
380 Element keyInfoElement = keyInfo.getElement();
381 keyInfoElement.setAttributeNS(
382 WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS
383 );
384
385 return keyInfo;
386 }
387
388
389
390
391
392
393
394
395
396 public static Element createDataRefList(
397 Document doc,
398 Element referenceList,
399 List<String> encDataRefs
400 ) {
401 for (String dataReferenceUri : encDataRefs) {
402 Element dataReference =
403 doc.createElementNS(
404 WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":DataReference"
405 );
406 dataReference.setAttributeNS(null, "URI", dataReferenceUri);
407 referenceList.appendChild(dataReference);
408 }
409 return referenceList;
410 }
411
412
413
414
415 public SecurityTokenReference getSecurityTokenReference() {
416 return securityTokenReference;
417 }
418
419
420
421
422 public void setSecurityTokenReference(SecurityTokenReference reference) {
423 securityTokenReference = reference;
424 }
425
426 public boolean isEncryptSymmKey() {
427 return encryptSymmKey;
428 }
429
430 public void setEncryptSymmKey(boolean encryptSymmKey) {
431 this.encryptSymmKey = encryptSymmKey;
432 }
433
434 public void setCustomReferenceValue(String customReferenceValue) {
435 this.customReferenceValue = customReferenceValue;
436 }
437
438 public void setEncKeyIdDirectId(boolean b) {
439 encKeyIdDirectId = b;
440 }
441
442 public void setEmbedEncryptedKey(boolean embedEncryptedKey) {
443 this.embedEncryptedKey = embedEncryptedKey;
444 }
445
446 public boolean isEmbedEncryptedKey() {
447 return embedEncryptedKey;
448 }
449
450 public List<Element> getAttachmentEncryptedDataElements() {
451 return attachmentEncryptedDataElements;
452 }
453
454 public Serializer getEncryptionSerializer() {
455 return encryptionSerializer;
456 }
457
458 public void setEncryptionSerializer(Serializer encryptionSerializer) {
459 this.encryptionSerializer = encryptionSerializer;
460 }
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475 public void setSymmetricEncAlgorithm(String algo) {
476 symEncAlgo = algo;
477 }
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492 public String getSymmetricEncAlgorithm() {
493 return symEncAlgo;
494 }
495
496 }