in ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandler.java [72:266]
protected void doSenderAction(
Document doc,
RequestData reqData,
List<HandlerAction> actions,
boolean isRequest
) throws WSSecurityException {
WSSConfig wssConfig = reqData.getWssConfig();
if (wssConfig == null) {
wssConfig = WSSConfig.getNewInstance();
reqData.setWssConfig(wssConfig);
}
if (reqData.getWsDocInfo() == null) {
WSDocInfo wsDocInfo = new WSDocInfo(doc);
reqData.setWsDocInfo(wsDocInfo);
}
Object mc = reqData.getMsgContext();
reqData.setEncodePasswords(
decodeBooleanConfigValue(mc, WSHandlerConstants.USE_ENCODED_PASSWORDS, false)
);
reqData.setPrecisionInMilliSeconds(
decodeBooleanConfigValue(mc, WSHandlerConstants.TIMESTAMP_PRECISION, true)
);
reqData.setAddInclusivePrefixes(
decodeBooleanConfigValue(mc, WSHandlerConstants.ADD_INCLUSIVE_PREFIXES, true)
);
reqData.setEnableSignatureConfirmation(
decodeBooleanConfigValue(mc, WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION, false)
);
reqData.setTimeStampTTL(decodeTimeToLive(reqData, true));
String actor = getString(WSHandlerConstants.ACTOR, mc);
reqData.setActor(actor);
boolean mu = decodeBooleanConfigValue(mc, WSHandlerConstants.MUST_UNDERSTAND, true);
WSSecHeader secHeader = new WSSecHeader(actor, mu, doc);
secHeader.insertSecurityHeader();
reqData.setSecHeader(secHeader);
reqData.setSoapConstants(WSSecurityUtil.getSOAPConstants(doc.getDocumentElement()));
// Load CallbackHandler
if (reqData.getCallbackHandler() == null) {
CallbackHandler passwordCallbackHandler = getPasswordCallbackHandler(reqData);
reqData.setCallbackHandler(passwordCallbackHandler);
}
if (!reqData.isStoreBytesInAttachment()) {
boolean storeBytesInAttachment =
decodeBooleanConfigValue(mc, WSHandlerConstants.STORE_BYTES_IN_ATTACHMENT, false);
reqData.setStoreBytesInAttachment(storeBytesInAttachment);
}
// Perform configuration
boolean encryptionFound = false;
for (HandlerAction actionToDo : actions) {
if (actionToDo.getAction() == WSConstants.SC) {
reqData.setEnableSignatureConfirmation(true);
} else if ((actionToDo.getAction() == WSConstants.UT
|| actionToDo.getAction() == WSConstants.UT_NOPASSWORD)
&& actionToDo.getActionToken() == null) {
decodeUTParameter(reqData);
if (actionToDo.getAction() == WSConstants.UT_NOPASSWORD) {
reqData.setPwType(null);
}
} else if (actionToDo.getAction() == WSConstants.UT_SIGN
&& actionToDo.getActionToken() == null) {
decodeUTParameter(reqData);
decodeSignatureParameter(reqData);
} else if ((actionToDo.getAction() == WSConstants.SIGN
|| actionToDo.getAction() == WSConstants.DKT_SIGN)
&& actionToDo.getActionToken() == null) {
SignatureActionToken actionToken = reqData.getSignatureToken();
if (actionToken == null) {
actionToken = new SignatureActionToken();
reqData.setSignatureToken(actionToken);
}
if (actionToken.getCrypto() == null) {
actionToken.setCrypto(loadSignatureCrypto(reqData));
}
decodeSignatureParameter(reqData);
if (encryptionFound && reqData.isStoreBytesInAttachment()) {
LOG.warn("Turning off storeBytesInAttachment as we have encryption before signature."
+ " The danger here is that the actual encryption bytes will not be signed");
reqData.setStoreBytesInAttachment(false);
}
} else if (actionToDo.getAction() == WSConstants.ST_SIGNED
&& actionToDo.getActionToken() == null) {
decodeSignatureParameter(reqData);
} else if ((actionToDo.getAction() == WSConstants.ENCR
|| actionToDo.getAction() == WSConstants.DKT_ENCR)
&& actionToDo.getActionToken() == null) {
encryptionFound = true;
EncryptionActionToken actionToken = reqData.getEncryptionToken();
if (actionToken == null) {
actionToken = new EncryptionActionToken();
reqData.setEncryptionToken(actionToken);
}
if (actionToken.getCrypto() == null) {
actionToken.setCrypto(loadEncryptionCrypto(reqData));
}
decodeEncryptionParameter(reqData);
}
}
/*
* If after all the parsing no Signature parts defined, set here a
* default set. This is necessary because we add SignatureConfirmation
* and therefore the default (Body) must be set here. The default setting
* in WSSignEnvelope doesn't work because the vector is not empty anymore.
*/
SignatureActionToken signatureToken = reqData.getSignatureToken();
if (signatureToken == null) {
signatureToken = new SignatureActionToken();
reqData.setSignatureToken(signatureToken);
}
if (signatureToken.getParts().isEmpty()) {
signatureToken.getParts().add(WSSecurityUtil.getDefaultEncryptionPart(doc));
}
/*
* If SignatureConfirmation is enabled and this is a response then
* insert SignatureConfirmation elements, note their wsu:id in the signature
* parts. They will be signed automatically during a (probably) defined
* SIGN action.
*/
if (reqData.isEnableSignatureConfirmation() && !isRequest) {
String done =
(String)getProperty(reqData.getMsgContext(), WSHandlerConstants.SIG_CONF_DONE);
if (done == null) {
wssConfig.getAction(WSConstants.SC).execute(this, null, reqData);
}
}
// See if the Signature and Timestamp actions (in that order) are defined, and if
// the Timestamp is to be signed. In this case we need to swap the actions, as the
// Timestamp must appear in the security header first for signature creation to work.
List<HandlerAction> actionsToPerform = actions;
HandlerAction signingAction = getSignatureActionThatSignsATimestamp(actions, reqData);
if (signingAction != null) {
actionsToPerform = new ArrayList<>(actions);
// Find TimestampAction
int timestampIndex = -1;
for (int i = 0; i < actionsToPerform.size(); i++) {
if (actionsToPerform.get(i).getAction() == WSConstants.TS) {
timestampIndex = i;
break;
}
}
int signatureIndex = actionsToPerform.indexOf(signingAction);
if (timestampIndex >= 0) {
actionsToPerform.set(signatureIndex, actionsToPerform.get(timestampIndex));
actionsToPerform.set(timestampIndex, signingAction);
}
reqData.setAppendSignatureAfterTimestamp(true);
reqData.setOriginalSignatureActionPosition(signatureIndex);
}
/*
* Here we have all necessary information to perform the requested
* action(s).
*/
for (HandlerAction actionToDo : actionsToPerform) {
LOG.debug("Performing Action: {}", actionToDo.getAction());
if (WSConstants.NO_SECURITY != actionToDo.getAction()) {
wssConfig.getAction(actionToDo.getAction()).execute(
this, actionToDo.getActionToken(), reqData);
}
}
/*
* If this is a request then store all signature values. Add ours to
* already gathered values because of chained handlers, e.g. for
* other actors.
*/
if (reqData.isEnableSignatureConfirmation()
&& isRequest && !reqData.getSignatureValues().isEmpty()) {
@SuppressWarnings("unchecked")
Set<Integer> savedSignatures =
(Set<Integer>)getProperty(reqData.getMsgContext(), WSHandlerConstants.SEND_SIGV);
if (savedSignatures == null) {
savedSignatures = new HashSet<>();
setProperty(
reqData.getMsgContext(), WSHandlerConstants.SEND_SIGV, savedSignatures
);
}
for (byte[] signatureValue : reqData.getSignatureValues()) {
savedSignatures.add(Arrays.hashCode(signatureValue));
}
}
}