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.action;
21
22 import java.util.List;
23
24 import javax.crypto.KeyGenerator;
25 import javax.crypto.SecretKey;
26 import javax.security.auth.callback.CallbackHandler;
27
28 import org.apache.wss4j.common.EncryptionActionToken;
29 import org.apache.wss4j.common.SecurityActionToken;
30 import org.apache.wss4j.common.SignatureActionToken;
31 import org.apache.wss4j.common.WSEncryptionPart;
32 import org.apache.wss4j.common.derivedKey.ConversationConstants;
33 import org.apache.wss4j.common.ext.WSPasswordCallback;
34 import org.apache.wss4j.common.ext.WSSecurityException;
35 import org.apache.wss4j.common.util.KeyUtils;
36 import org.apache.wss4j.dom.WSConstants;
37 import org.apache.wss4j.dom.handler.RequestData;
38 import org.apache.wss4j.dom.handler.WSHandler;
39 import org.apache.wss4j.dom.message.WSSecDKEncrypt;
40 import org.apache.wss4j.dom.util.WSSecurityUtil;
41 import org.w3c.dom.Document;
42 import org.w3c.dom.Element;
43 import org.w3c.dom.Node;
44
45 public class EncryptionDerivedAction extends AbstractDerivedAction implements Action {
46
47 public void execute(WSHandler handler, SecurityActionToken actionToken, RequestData reqData)
48 throws WSSecurityException {
49 CallbackHandler callbackHandler = reqData.getCallbackHandler();
50 if (callbackHandler == null) {
51 callbackHandler = handler.getPasswordCallbackHandler(reqData);
52 }
53
54 EncryptionActionToken encryptionToken = null;
55 if (actionToken instanceof EncryptionActionToken) {
56 encryptionToken = (EncryptionActionToken)actionToken;
57 }
58 if (encryptionToken == null) {
59 encryptionToken = reqData.getEncryptionToken();
60 }
61
62 WSPasswordCallback passwordCallback =
63 handler.getPasswordCB(encryptionToken.getUser(), WSConstants.DKT_ENCR, callbackHandler, reqData);
64 WSSecDKEncrypt wsEncrypt = new WSSecDKEncrypt(reqData.getSecHeader());
65 wsEncrypt.setIdAllocator(reqData.getWssConfig().getIdAllocator());
66 wsEncrypt.setWsDocInfo(reqData.getWsDocInfo());
67 wsEncrypt.setExpandXopInclude(reqData.isExpandXopInclude());
68
69 if (encryptionToken.getKeyIdentifierId() != 0) {
70 wsEncrypt.setKeyIdentifierType(encryptionToken.getKeyIdentifierId());
71 }
72
73 if (encryptionToken.getSymmetricAlgorithm() != null) {
74 wsEncrypt.setSymmetricEncAlgorithm(encryptionToken.getSymmetricAlgorithm());
75 }
76 wsEncrypt.setUserInfo(encryptionToken.getUser(), passwordCallback.getPassword());
77
78 if (reqData.isUse200512Namespace()) {
79 wsEncrypt.setWscVersion(ConversationConstants.VERSION_05_12);
80 } else {
81 wsEncrypt.setWscVersion(ConversationConstants.VERSION_05_02);
82 }
83
84 if (encryptionToken.getDerivedKeyLength() > 0) {
85 wsEncrypt.setDerivedKeyLength(encryptionToken.getDerivedKeyLength());
86 }
87
88 Document doc = reqData.getSecHeader().getSecurityHeaderElement().getOwnerDocument();
89 String derivedKeyTokenReference = encryptionToken.getDerivedKeyTokenReference();
90 Element tokenElement = null;
91 SecretKey symmetricKey = null;
92 if ("EncryptedKey".equals(derivedKeyTokenReference)) {
93 if (reqData.getSignatureToken() == null || reqData.getSignatureToken().getKey() == null
94 || reqData.getSignatureToken().getKeyIdentifier() == null) {
95 String symmetricKeyAlgorithm = encryptionToken.getSymmetricAlgorithm();
96 if (symmetricKeyAlgorithm == null) {
97 symmetricKeyAlgorithm = WSConstants.AES_128;
98 }
99 KeyGenerator keyGen = KeyUtils.getKeyGenerator(symmetricKeyAlgorithm);
100 symmetricKey = keyGen.generateKey();
101 }
102
103 tokenElement = setupEncryptedKeyTokenReference(reqData, encryptionToken, wsEncrypt, symmetricKey);
104 } else if ("SecurityContextToken".equals(derivedKeyTokenReference)) {
105 tokenElement = setupSCTTokenReference(reqData, encryptionToken, wsEncrypt, passwordCallback, doc);
106 }
107
108 wsEncrypt.setAttachmentCallbackHandler(reqData.getAttachmentCallbackHandler());
109 wsEncrypt.setStoreBytesInAttachment(reqData.isStoreBytesInAttachment());
110
111 try {
112 List<WSEncryptionPart> parts = encryptionToken.getParts();
113 if (parts != null && !parts.isEmpty()) {
114 wsEncrypt.getParts().addAll(parts);
115 } else {
116 wsEncrypt.getParts().add(WSSecurityUtil.getDefaultEncryptionPart(doc));
117 }
118
119 byte[] key = getKey(reqData.getSignatureToken(), passwordCallback, symmetricKey);
120 wsEncrypt.prepare(key);
121
122 Element externRefList = wsEncrypt.encrypt();
123
124
125 Node nextSibling = null;
126 if (tokenElement == null
127 && "EncryptedKey".equals(encryptionToken.getDerivedKeyTokenReference())) {
128 nextSibling = findEncryptedKeySibling(reqData);
129 } else if (tokenElement == null
130 && "SecurityContextToken".equals(encryptionToken.getDerivedKeyTokenReference())) {
131 nextSibling = findSCTSibling(reqData);
132 }
133 if (nextSibling == null) {
134 wsEncrypt.prependDKElementToHeader();
135 } else {
136 reqData.getSecHeader().getSecurityHeaderElement().insertBefore(
137 wsEncrypt.getdktElement(), nextSibling);
138 }
139
140
141 wsEncrypt.addExternalRefElement(externRefList);
142
143 if (tokenElement != null) {
144 WSSecurityUtil.prependChildElement(reqData.getSecHeader().getSecurityHeaderElement(), tokenElement);
145 }
146
147 wsEncrypt.clean();
148 } catch (WSSecurityException e) {
149 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e,
150 "empty", new Object[] {"Error during Encryption: "});
151 }
152 }
153
154 private Element setupSCTTokenReference(
155 RequestData reqData, EncryptionActionToken encryptionToken,
156 WSSecDKEncrypt wsEncrypt, WSPasswordCallback passwordCallback,
157 Document doc
158 ) throws WSSecurityException {
159 if (reqData.getSignatureToken() != null && reqData.getSignatureToken().getKey() != null
160 && reqData.getSignatureToken().getKeyIdentifier() != null) {
161 setupSCTReference(wsEncrypt, reqData.getSignatureToken(), reqData.isUse200512Namespace());
162 return null;
163 } else {
164 return setupSCTReference(wsEncrypt, passwordCallback, encryptionToken, reqData.isUse200512Namespace(), doc);
165 }
166 }
167
168 private Element setupEncryptedKeyTokenReference(
169 RequestData reqData, EncryptionActionToken encryptionToken,
170 WSSecDKEncrypt wsEncrypt, SecretKey symmetricKey
171 ) throws WSSecurityException {
172 if (symmetricKey == null) {
173 setupEKReference(wsEncrypt, reqData.getSignatureToken());
174 return null;
175 } else {
176 return setupEKReference(wsEncrypt, reqData.getSecHeader(), encryptionToken, null, null, symmetricKey);
177 }
178 }
179
180 private byte[] getKey(SignatureActionToken encryptionToken,
181 WSPasswordCallback passwordCallback,
182 SecretKey symmetricKey) throws WSSecurityException {
183 if (symmetricKey != null) {
184 return symmetricKey.getEncoded();
185 } else if (encryptionToken != null && encryptionToken.getKey() != null
186 && encryptionToken.getKeyIdentifier() != null) {
187 return encryptionToken.getKey();
188 } else {
189 return passwordCallback.getKey();
190 }
191 }
192 }