/*
* Check is a timestamp is required. If yes create one and add its Id to
* signed parts. According to WSP a timestamp must be signed
*/
WSSecTimestamp timestamp = null;
if (wpd.isIncludeTimestamp()) {
timestamp = new WSSecTimestamp();
timestamp.prepare(doc);
sigParts.add(new WSEncryptionPart(timestamp.getId()));
}
/*
* Check for a recipient token. If one is avaliable use it as token to
* encrypt data to the recipient. This is according to WSP
* specification. Most of the data is extracted from the
* WSS4JPolicyData, only the user info (name/alias of the certificate in
* the keystore) must be provided by some other means.
*/
WSSecEncrypt recEncrypt = null;
WSS4JPolicyToken recToken = null;
if ((recToken = wpd.getRecipientToken()) != null) {
recEncrypt = new WSSecEncrypt();
recEncrypt.setUserInfo("wss4jcert");
recEncrypt.setKeyIdentifierType(recToken.getKeyIdentifier());
recEncrypt.setSymmetricEncAlgorithm(recToken.getEncAlgorithm());
recEncrypt.setKeyEnc(recToken.getEncTransportAlgorithm());
recEncrypt.prepare(doc, cryptoSKI);
}
/*
* Check for an initiator token. If one is avaliable use it as token to
* sign data. This is according to WSP specification. Most of the data
* is extracted from the WSS4JPolicyData, only the user info (name/alias
* of the certificate in the keystore) must be provided by some other
* means.
*
* If SignatureProtection is enabled add the signature to the encrypted
* parts vector. In any case the signature must be in the internal
* ReferenceList (this list is a child of the EncryptedKey element).
*
* If TokenProtection is enabled add an appropriate signature reference.
*
* TODO Check / enable for STRTransform
*/
WSSecSignature iniSignature = null;
WSS4JPolicyToken iniToken = null;
if ((iniToken = wpd.getInitiatorToken()) != null) {
iniSignature = new WSSecSignature();
iniSignature.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e",
"security");
iniSignature.setKeyIdentifierType(iniToken.getKeyIdentifier());
iniSignature.setSignatureAlgorithm(iniToken.getSigAlgorithm());
iniSignature.prepare(doc, crypto, secHeader);
if (wpd.isSignatureProtection()) {
encPartsInternal.add(new WSEncryptionPart(iniSignature.getId(),
"Element"));
}
if (wpd.isTokenProtection()) {
sigParts.add(new WSEncryptionPart("Token", null, null));
}
}
Element body = WSSecurityUtil.findBodyElement(doc, soapConstants);
if (body == null) {
System.out
.println("No SOAP Body found - illegal message structure. Processing terminated");
return;
}
WSEncryptionPart bodyPart = new WSEncryptionPart("Body", soapConstants
.getEnvelopeURI(), "Content");
/*
* Check the protection order. If Encrypt before signing then first take
* all parts and elements to encrypt and encrypt them. Take their ids
* after encryption and put them to the parts to be signed.
*
*/
Element externRefList = null;
if (Constants.ENCRYPT_BEFORE_SIGNING.equals(wpd.getProtectionOrder())) {
/*
* Process Body: it sign and encrypt: first encrypt the body, insert
* the body to the parts to be signed.
*
* If just to be signed: add the plain Body to the parts to be
* signed
*/
if (wpd.isSignBody()) {
if (wpd.isEncryptBody()) {
Vector parts = new Vector();
parts.add(bodyPart);
externRefList = recEncrypt.encryptForExternalRef(
externRefList, parts);
sigParts.add(bodyPart);
} else {
sigParts.add(bodyPart);
}
}
/*
* Here we need to handle signed/encrypted parts:
*
* Get all parts that need to be encrypted _and_ signed, encrypt
* them, get ids of thier encrypted data elements and add these ids
* to the parts to be signed
*
* Then encrypt the remaining parts that don't need to be signed.
*
* Then add the remaining parts that don't nedd to be encrypted to
* the parts to be signed.
*
* Similar handling for signed/encrypted elements (compare XPath
* strings?)
*
* After all elements are encrypted put the external refernce list
* to the security header. is at the bottom of the security header)
*/
recEncrypt.addExternalRefElement(externRefList, secHeader);
/*
* Now handle the supporting tokens - according to OASIS WSP
* supporting tokens are not part of a Binding assertion but a top
* level assertion similar to Wss11 or SignedParts. If supporting
* tokens are available their BST elements have to be added later
* (probably prepended to the initiator token - see below)
*/
/*
* Now add the various elements to the header. We do a strict layout
* here.
*
*/
/*
* Prepend Signature to the supporting tokens that sign the primary
* signature
*/
iniSignature.prependToHeader(secHeader);
/*
* This prepends a possible initiator token to the security header
*/
iniSignature.prependBSTElementToHeader(secHeader);
/*
* Here prepend BST elements of supporting tokens
* (EndorsingSupportTokens), then prepend supporting token that do
* not sign the primary signature but are signed by the primary
* signature. Take care of the TokenProtection protery!?
*/
/*
* Add the encrypted key element and then the associated BST element
* recipient token)
*/
recEncrypt.prependToHeader(secHeader);
recEncrypt.prependBSTElementToHeader(secHeader);
/*
* Now we are ready to per Signature processing.
*
* First the primary Signature then supporting tokens (Signatures)
* that sign the primary Signature.
*/
timestamp.prependToHeader(secHeader);
iniSignature.addReferencesToSign(sigParts, secHeader);
iniSignature.computeSignature();
Element internRef = recEncrypt.encryptForInternalRef(null,
encPartsInternal);