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.ArrayList;
23 import java.util.List;
24
25 import javax.security.auth.callback.CallbackHandler;
26
27 import org.apache.wss4j.common.SecurityActionToken;
28 import org.apache.wss4j.common.SignatureActionToken;
29 import org.apache.wss4j.common.WSEncryptionPart;
30 import org.apache.wss4j.common.ext.WSPasswordCallback;
31 import org.apache.wss4j.common.ext.WSSecurityException;
32 import org.apache.wss4j.dom.WSConstants;
33 import org.apache.wss4j.dom.handler.RequestData;
34 import org.apache.wss4j.dom.handler.WSHandler;
35 import org.apache.wss4j.dom.message.WSSecSignature;
36 import org.apache.wss4j.dom.util.WSSecurityUtil;
37 import org.w3c.dom.Document;
38 import org.w3c.dom.Element;
39 import org.w3c.dom.Node;
40
41 public class SignatureAction implements Action {
42
43 public void execute(WSHandler handler, SecurityActionToken actionToken, RequestData reqData)
44 throws WSSecurityException {
45 CallbackHandler callbackHandler = reqData.getCallbackHandler();
46 if (callbackHandler == null) {
47 callbackHandler = handler.getPasswordCallbackHandler(reqData);
48 }
49
50 SignatureActionToken signatureToken = null;
51 if (actionToken instanceof SignatureActionToken) {
52 signatureToken = (SignatureActionToken)actionToken;
53 }
54 if (signatureToken == null) {
55 signatureToken = reqData.getSignatureToken();
56 }
57
58 WSPasswordCallback passwordCallback =
59 handler.getPasswordCB(signatureToken.getUser(), WSConstants.SIGN, callbackHandler, reqData);
60 WSSecSignature wsSign = new WSSecSignature(reqData.getSecHeader());
61 wsSign.setIdAllocator(reqData.getWssConfig().getIdAllocator());
62 wsSign.setAddInclusivePrefixes(reqData.isAddInclusivePrefixes());
63 wsSign.setWsDocInfo(reqData.getWsDocInfo());
64 wsSign.setExpandXopInclude(reqData.isExpandXopInclude());
65 wsSign.setSignatureProvider(reqData.getSignatureProvider());
66
67 if (signatureToken.getKeyIdentifierId() != 0) {
68 wsSign.setKeyIdentifierType(signatureToken.getKeyIdentifierId());
69 }
70 if (signatureToken.getSignatureAlgorithm() != null) {
71 wsSign.setSignatureAlgorithm(signatureToken.getSignatureAlgorithm());
72 }
73 if (signatureToken.getDigestAlgorithm() != null) {
74 wsSign.setDigestAlgo(signatureToken.getDigestAlgorithm());
75 }
76 if (signatureToken.getC14nAlgorithm() != null) {
77 wsSign.setSigCanonicalization(signatureToken.getC14nAlgorithm());
78 }
79
80 wsSign.setIncludeSignatureToken(signatureToken.isIncludeToken());
81
82 wsSign.setUserInfo(signatureToken.getUser(), passwordCallback.getPassword());
83 wsSign.setUseSingleCertificate(signatureToken.isUseSingleCert());
84
85 if (passwordCallback.getKey() != null) {
86 wsSign.setSecretKey(passwordCallback.getKey());
87 } else if (signatureToken.getKey() != null) {
88 wsSign.setSecretKey(signatureToken.getKey());
89 } else if (signatureToken.getUser() == null) {
90 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noSignatureUser");
91 }
92
93 if (signatureToken.getTokenId() != null) {
94 wsSign.setCustomTokenId(signatureToken.getTokenId());
95 }
96 if (signatureToken.getTokenType() != null) {
97 wsSign.setCustomTokenValueType(signatureToken.getTokenType());
98 }
99 if (signatureToken.getSha1Value() != null) {
100 wsSign.setEncrKeySha1value(signatureToken.getSha1Value());
101 }
102 if (signatureToken.getKeyInfoElement() != null) {
103 wsSign.setCustomKeyInfoElement(signatureToken.getKeyInfoElement());
104 }
105
106 wsSign.setAttachmentCallbackHandler(reqData.getAttachmentCallbackHandler());
107 wsSign.setStoreBytesInAttachment(reqData.isStoreBytesInAttachment());
108
109 try {
110 wsSign.prepare(signatureToken.getCrypto());
111
112 Element siblingElementToPrepend = null;
113 boolean signBST = false;
114 for (WSEncryptionPart part : signatureToken.getParts()) {
115 if ("STRTransform".equals(part.getName()) && part.getId() == null) {
116 part.setId(wsSign.getSecurityTokenReferenceURI());
117 } else if (reqData.isAppendSignatureAfterTimestamp()
118 && WSConstants.WSU_NS.equals(part.getNamespace())
119 && "Timestamp".equals(part.getName())) {
120 int originalSignatureActionIndex =
121 reqData.getOriginalSignatureActionPosition();
122
123 if (originalSignatureActionIndex > 0) {
124 Element secHeader = reqData.getSecHeader().getSecurityHeaderElement();
125 Node lastChild = secHeader.getLastChild();
126 int count = 0;
127 while (lastChild != null && count < originalSignatureActionIndex) {
128 while (lastChild != null && lastChild.getNodeType() != Node.ELEMENT_NODE) {
129 lastChild = lastChild.getPreviousSibling();
130 }
131 count++;
132 }
133 if (lastChild instanceof Element) {
134 siblingElementToPrepend = (Element)lastChild;
135 }
136 }
137 } else if (WSConstants.WSSE_NS.equals(part.getNamespace())
138 && WSConstants.BINARY_TOKEN_LN.equals(part.getName())) {
139 signBST = true;
140 } else if ("KeyInfo".equals(part.getName()) && WSConstants.SIG_NS.equals(part.getNamespace())
141 && part.getElement() == null) {
142
143 part.setId(wsSign.getKeyInfoUri());
144 break;
145 }
146 }
147
148 if (signBST) {
149 wsSign.prependBSTElementToHeader();
150 }
151
152 List<WSEncryptionPart> parts = signatureToken.getParts();
153 if (parts == null || parts.isEmpty()) {
154 parts = new ArrayList<>(1);
155 Document doc = reqData.getSecHeader().getSecurityHeaderElement().getOwnerDocument();
156 parts.add(WSSecurityUtil.getDefaultEncryptionPart(doc));
157 }
158
159 List<javax.xml.crypto.dsig.Reference> referenceList = wsSign.addReferencesToSign(parts);
160
161 if (signBST
162 || reqData.isAppendSignatureAfterTimestamp() && siblingElementToPrepend == null) {
163 wsSign.computeSignature(referenceList, false, null);
164 } else {
165 wsSign.computeSignature(referenceList, true, siblingElementToPrepend);
166 }
167
168 if (!signBST) {
169 wsSign.prependBSTElementToHeader();
170 }
171 reqData.getSignatureValues().add(wsSign.getSignatureValue());
172 } catch (WSSecurityException e) {
173 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e, "empty",
174 new Object[] {"Error during Signature: "});
175 }
176 }
177
178 }