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.util.ArrayList;
23 import java.util.List;
24
25 import javax.crypto.SecretKey;
26
27 import org.apache.wss4j.common.WSEncryptionPart;
28 import org.apache.wss4j.common.derivedKey.ConversationConstants;
29 import org.apache.wss4j.common.ext.WSSecurityException;
30 import org.apache.wss4j.common.token.Reference;
31 import org.apache.wss4j.common.token.SecurityTokenReference;
32 import org.apache.wss4j.common.util.FIPSUtils;
33 import org.apache.wss4j.common.util.KeyUtils;
34 import org.apache.wss4j.dom.WSConstants;
35 import org.apache.wss4j.dom.util.WSSecurityUtil;
36 import org.apache.xml.security.encryption.Serializer;
37 import org.apache.xml.security.keys.KeyInfo;
38 import org.w3c.dom.Document;
39 import org.w3c.dom.Element;
40 import org.w3c.dom.Node;
41
42
43
44
45
46 public class WSSecDKEncrypt extends WSSecDerivedKeyBase {
47
48 private String symEncAlgo = FIPSUtils.isFIPSEnabled()
49 ? WSConstants.AES_128_GCM : WSConstants.AES_128;
50 private int derivedKeyLength = -1;
51
52 private List<Element> attachmentEncryptedDataElements;
53
54 private Serializer encryptionSerializer;
55
56 public WSSecDKEncrypt(WSSecHeader securityHeader) {
57 super(securityHeader);
58 }
59
60 public WSSecDKEncrypt(Document doc) {
61 super(doc);
62 }
63
64 @Override
65 public void prepare(byte[] ephemeralKey) throws WSSecurityException {
66 super.prepare(ephemeralKey);
67
68 attachmentEncryptedDataElements = new ArrayList<>();
69 }
70
71 public Document build(byte[] ephemeralKey) throws WSSecurityException {
72
73
74
75
76 prepare(ephemeralKey);
77
78
79
80 prependDKElementToHeader();
81
82 Element externRefList = encrypt();
83
84 addAttachmentEncryptedDataElements();
85
86 addExternalRefElement(externRefList);
87
88 return getDocument();
89 }
90
91 public void addAttachmentEncryptedDataElements() {
92 if (attachmentEncryptedDataElements != null) {
93 for (Element encryptedData : attachmentEncryptedDataElements) {
94 Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
95 WSSecurityUtil.prependChildElement(securityHeaderElement, encryptedData);
96 }
97 }
98 }
99
100 public Element encrypt() throws WSSecurityException {
101 if (getParts().isEmpty()) {
102 getParts().add(WSSecurityUtil.getDefaultEncryptionPart(getDocument()));
103 }
104
105 return encryptForExternalRef(null, getParts());
106 }
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 public Element encryptForExternalRef(Element dataRef, List<WSEncryptionPart> references)
130 throws WSSecurityException {
131
132 KeyInfo keyInfo = createKeyInfo();
133
134 SecretKey key = getDerivedKey(symEncAlgo);
135
136 Encryptor encryptor = new Encryptor();
137 encryptor.setDoc(getDocument());
138 encryptor.setSecurityHeader(getSecurityHeader());
139 encryptor.setIdAllocator(getIdAllocator());
140 encryptor.setCallbackLookup(callbackLookup);
141 encryptor.setAttachmentCallbackHandler(attachmentCallbackHandler);
142 encryptor.setStoreBytesInAttachment(storeBytesInAttachment);
143 encryptor.setEncryptionSerializer(encryptionSerializer);
144 encryptor.setWsDocInfo(getWsDocInfo());
145 List<String> encDataRefs =
146 encryptor.doEncryption(keyInfo, key, symEncAlgo, references, attachmentEncryptedDataElements);
147
148 if (dataRef == null) {
149 dataRef =
150 getDocument().createElementNS(
151 WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":ReferenceList"
152 );
153 }
154 return WSSecEncrypt.createDataRefList(getDocument(), dataRef, encDataRefs);
155 }
156
157
158
159
160
161
162 private KeyInfo createKeyInfo() {
163 KeyInfo keyInfo = new KeyInfo(getDocument());
164 SecurityTokenReference secToken = new SecurityTokenReference(getDocument());
165 secToken.addWSSENamespace();
166 if (addWSUNamespace) {
167 secToken.addWSUNamespace();
168 }
169 Reference ref = new Reference(getDocument());
170 ref.setURI("#" + getId());
171 String ns =
172 ConversationConstants.getWSCNs(getWscVersion())
173 + ConversationConstants.TOKEN_TYPE_DERIVED_KEY_TOKEN;
174 ref.setValueType(ns);
175 secToken.setReference(ref);
176
177 keyInfo.addUnknownElement(secToken.getElement());
178 Element keyInfoElement = keyInfo.getElement();
179 keyInfoElement.setAttributeNS(
180 WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS
181 );
182
183 return keyInfo;
184 }
185
186
187
188
189
190
191
192
193
194
195 public void addExternalRefElement(Element referenceList) {
196 if (referenceList != null) {
197 Node node = getdktElement().getNextSibling();
198 Element securityHeaderElement = getSecurityHeader().getSecurityHeaderElement();
199 if (node != null && Node.ELEMENT_NODE == node.getNodeType()) {
200 securityHeaderElement.insertBefore(referenceList, node);
201 } else {
202
203
204 securityHeaderElement.appendChild(referenceList);
205 }
206 }
207 }
208
209
210
211
212
213
214 public void setSymmetricEncAlgorithm(String algo) {
215 symEncAlgo = algo;
216 }
217
218 protected int getDerivedKeyLength() throws WSSecurityException {
219 return derivedKeyLength > 0 ? derivedKeyLength : KeyUtils.getKeyLength(symEncAlgo);
220 }
221
222 public void setDerivedKeyLength(int keyLength) {
223 derivedKeyLength = keyLength;
224 }
225
226 public List<Element> getAttachmentEncryptedDataElements() {
227 return attachmentEncryptedDataElements;
228 }
229
230 public Serializer getEncryptionSerializer() {
231 return encryptionSerializer;
232 }
233
234 public void setEncryptionSerializer(Serializer encryptionSerializer) {
235 this.encryptionSerializer = encryptionSerializer;
236 }
237 }