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