ArrayList transformList = new ArrayList(2);
boolean disableInclusivePrefix = false;
while(transformIterator.hasNext()) {
SignatureTarget.Transform transformInfo = (SignatureTarget.Transform)transformIterator.next();
String transformAlgo = transformInfo.getTransform();
Transform transform = null;
if(logger.isLoggable(Level.FINEST))
logger.log(Level.FINEST, "Transform Algorithm is "+transformAlgo);
if(transformAlgo == Transform.XPATH || transformAlgo.equals(Transform.XPATH)){
TransformParameterSpec spec =(TransformParameterSpec) transformInfo.getAlgorithmParameters();
//XPathFilterParameterSpec spec = null;
if(spec == null){
logger.log(Level.SEVERE,LogStringsMessages.WSS_1367_ILLEGAL_XPATH());
throw new XWSSecurityException("XPATH parameters cannot be null");
}
//XPATH2,XSLTC , ..
transform = signatureFactory.newTransform(transformAlgo,spec);
}else if(transformAlgo == Transform.XPATH2 || transformAlgo.equals(Transform.XPATH2)){
TransformParameterSpec transformParams = (TransformParameterSpec)transformInfo.getAlgorithmParameters();
transform= signatureFactory.newTransform(transformAlgo,transformParams);
}else if (transformAlgo == MessageConstants.STR_TRANSFORM_URI || transformAlgo.equals(MessageConstants.STR_TRANSFORM_URI)){
Parameter transformParams =(Parameter) transformInfo.getAlgorithmParameters();
String algo = null;
if(transformParams.getParamName().equals("CanonicalizationMethod")){
algo = transformParams.getParamValue();
}
if(algo == null){
logger.log(Level.SEVERE, LogStringsMessages.WSS_1368_ILLEGAL_STR_CANONCALIZATION());
throw new XWSSecurityException("STR Transform must have a"+
"canonicalization method specified");
}
if(logger.isLoggable(Level.FINEST)){
logger.log(Level.FINEST, "CanonicalizationMethod is " + algo);
}
CanonicalizationMethod cm = null;
C14NMethodParameterSpec spec = null;
try{
Document doc = WSITXMLFactory.createDocumentBuilderFactory(WSITXMLFactory.DISABLE_SECURE_PROCESSING).newDocumentBuilder().newDocument();
Element tp = doc.createElementNS(MessageConstants.WSSE_NS, "wsse:TransformationParameters");
Element cem = doc.createElementNS(MessageConstants.DSIG_NS, "ds:CanonicalizationMethod");
tp.appendChild(cem);
cem.setAttribute("Algorithm",algo);
doc.appendChild(tp);
XMLStructure transformSpec = new DOMStructure(tp);
transform = signatureFactory.newTransform(transformAlgo,transformSpec);
}catch(Exception ex){
logger.log(Level.SEVERE,LogStringsMessages.WSS_1300_DSIG_TRANSFORM_PARAM_ERROR(),ex);
throw new XWSSecurityException(ex.getMessage());
}
} else if (MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS.equalsIgnoreCase(transformAlgo)) {
// should be there by default...
// As per R 5412, last child of ds:Transforms must be either excl-c14n, or attachment-content only or attachment-complete transform
exclTransformToBeAdded = true;
disableInclusivePrefix = transformInfo.getDisableInclusivePrefix();
} else {
// XMLStructure transformSpec = null;
// transform = signatureFactory.newTransform(transformAlgo,transformSpec);
// Workaround for JSR105 bug
transform = signatureFactory.newTransform(transformAlgo,(TransformParameterSpec) null);
}
if (!MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS.equalsIgnoreCase(transformAlgo)) {
// will add c14n transform in the end; later
transformList.add(transform);
}
}
String targetURI = "";
String signatureType = signatureTarget.getType();
SOAPMessage msg = secureMessage.getSOAPMessage();
boolean headersOnly = signatureTarget.isSOAPHeadersOnly();
if(signatureType.equals(SignatureTarget.TARGET_TYPE_VALUE_QNAME) || signatureType.equals(SignatureTarget.TARGET_TYPE_VALUE_XPATH)){
String expr = null;
NodeList nodes = null;
if( signatureType == SignatureTarget.TARGET_TYPE_VALUE_QNAME){
String targetValue = signatureTarget.getValue();
boolean optimized = false;
if(fpContext.getConfigType() == MessageConstants.SIGN_BODY || fpContext.getConfigType() == MessageConstants.SIGN_ENCRYPT_BODY){
optimized = true;
}
// if(targetValue.equals(SignatureTarget.BODY) && optimized){
// Reference ref = new JAXWSDigestProcessor(fpContext,signatureTarget , digestMethod, signatureFactory).handleJAXWSSOAPBody();
// references.add(ref);
// continue;
// }
if(targetValue.equals(SignatureTarget.BODY )){
try{
final SOAPElement se = msg.getSOAPBody();
nodes = new NodeList(){
Node node = se;
public int getLength(){
if(node == null){
return 0;
}else{
return 1;
}
}
public Node item(int num){
if(num == 0){
return node;
}else{
return null;
}
}
};
}catch(SOAPException se){
logger.log(Level.SEVERE, LogStringsMessages.WSS_1369_UNABLE_GET_SIGNATURE_TARGET_BY_URI());
throw new XWSSecurityException("SignatureTarget with URI "+targetValue+
" is not in the message");
//logger.log(
// Level.WARNING, "Signed Part with QName " + targetValue + " is not in the message");
//continue;
}
}else{
QName name = QName.valueOf(targetValue);
if(!headersOnly){
if("".equals(name.getNamespaceURI())){
nodes =msg.getSOAPPart().getElementsByTagName(name.getLocalPart());
}else{
if(!"".equals(name.getLocalPart()))
nodes = msg.getSOAPPart().getElementsByTagNameNS(name.getNamespaceURI(), name.getLocalPart());
else
nodes = msg.getSOAPPart().getElementsByTagNameNS(name.getNamespaceURI(), "*");
}
} else{
//process headers of soap message
try{
nodes = new NodeListImpl();
NodeList hdrChilds = msg.getSOAPHeader().getChildNodes();
for(int i = 0; i < hdrChilds.getLength(); i++){
Node child = hdrChilds.item(i);
if(child.getNodeType() == Node.ELEMENT_NODE){
if("".equals(name.getNamespaceURI())){
if(name.getLocalPart().equals(child.getLocalName()))
((NodeListImpl)nodes).add(child);
} else{
// FIXME: Hack to get addressing members from both namespaces, as microsoft uses both of them in a soap message
if(name.getNamespaceURI().equals(MessageConstants.ADDRESSING_MEMBER_SUBMISSION_NAMESPACE) ||
name.getNamespaceURI().equals(MessageConstants.ADDRESSING_W3C_NAMESPACE)){
if((child.getNamespaceURI().equals(MessageConstants.ADDRESSING_MEMBER_SUBMISSION_NAMESPACE) ||
child.getNamespaceURI().equals(MessageConstants.ADDRESSING_W3C_NAMESPACE))) {
if(!"".equals(name.getLocalPart())){
if(name.getLocalPart().equals(child.getLocalName()))
((NodeListImpl)nodes).add(child);
} else{
((NodeListImpl)nodes).add(child);
}
}
} else{
if(!"".equals(name.getLocalPart())){
if(name.getNamespaceURI().equals(child.getNamespaceURI()) &&
name.getLocalPart().equals(child.getLocalName()))
((NodeListImpl)nodes).add(child);
} else{
if(name.getNamespaceURI().equals(child.getNamespaceURI()))
((NodeListImpl)nodes).add(child);
}
}
}
}
}
} catch (SOAPException se){
logger.log(Level.SEVERE, LogStringsMessages.WSS_1370_FAILED_PROCESS_HEADER());
throw new XWSSecurityException(se);
}
}
}
}else{
expr = signatureTarget.getValue();
try{
XPathFactory xpathFactory = WSITXMLFactory.createXPathFactory(WSITXMLFactory.DISABLE_SECURE_PROCESSING);
XPath xpath = xpathFactory.newXPath();
xpath.setNamespaceContext(secureMessage.getNamespaceContext());
// XPathExpression expr = xpath.compile("//*[@wsu:Id]");
//XPathExpression expr = xpath.compile("//*");
XPathExpression xpathExpr = xpath.compile(expr);
if(logger.isLoggable(Level.FINEST)){
logger.log(Level.FINEST, "++++++++++++++++++++++++++++++");
logger.log(Level.FINEST, "Expr is "+expr);
printDocument((Node)secureMessage.getSOAPPart());
}
nodes = (NodeList)xpathExpr.evaluate((Object)secureMessage.getSOAPPart(),XPathConstants.NODESET);
}catch(XPathExpressionException xpe){
logger.log(Level.SEVERE,LogStringsMessages.WSS_1371_FAILED_RESOLVE_X_PATH()+expr,xpe);
throw new XWSSecurityException(xpe);
}
}
int i=0;
if(nodes == null || nodes.getLength() <= 0){
if(signatureTarget.getEnforce()){
logger.log(Level.SEVERE, LogStringsMessages.WSS_1369_UNABLE_GET_SIGNATURE_TARGET_BY_URI());
throw new XWSSecurityException("SignatureTarget with URI "+signatureTarget.getValue()+
" is not in the message");
} else{
continue;
}
// we dont throw error since WSSecurityPolicy allows this
//logger.log(Level.WARNING, "Signed Part with QName/XPath " + signatureTarget.getValue() +
// " is not in the message");
//continue;
}
if(logger.isLoggable(Level.FINEST)){
logger.log(Level.FINEST, "Number of nodes "+nodes.getLength());
logger.log(Level.FINEST, "+++++++++++++++END+++++++++++++++");
}
HashMap elementCache = null;
if(fpContext != null ){
elementCache = fpContext.getElementCache();
}
while(i < nodes.getLength()){
if(logger.isLoggable(Level.FINEST))
logger.log(Level.FINEST, "Nodes is "+nodes.item(i));
Node nodeRef = nodes.item(i++);
if(nodeRef.getNodeType() != Node.ELEMENT_NODE) {
logger.log (Level.SEVERE, LogStringsMessages.WSS_1371_FAILED_RESOLVE_X_PATH());
throw new XWSSecurityException(
"XPath does not correspond to a DOM Element");
}
ArrayList clonedTransformList = (ArrayList) transformList.clone();
if (exclTransformToBeAdded) {
// exc-14-nl must be one of the last transforms under ReferenceList by default.
String transformAlgo = MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS;
ExcC14NParameterSpec spec = null;
if((featureBinding != null && featureBinding.isBSP()) || !disableInclusivePrefix){
spec = new ExcC14NParameterSpec(getReferenceNamespacePrefixes(nodeRef));
}
Transform transform = signatureFactory.newTransform(transformAlgo,spec);
clonedTransformList.add(transform);
}
boolean w3cElem = false;
// Assume only elements with wsu:Id are signed
String id = ((Element)nodeRef).getAttributeNS(MessageConstants.WSU_NS, "Id");
if(id == null || id.equals("")){
if(nodeRef.getNamespaceURI() == MessageConstants.DSIG_NS ||
nodeRef.getNamespaceURI() == MessageConstants.XENC_NS){
w3cElem = true;
id = ((Element)nodeRef).getAttribute("Id");
}
}
if (id == null || id.equals("")) {
id = secureMessage.generateId();
if(!verify){
if(w3cElem){
XMLUtil.setIdAttr((Element)nodeRef, id);
}else{
XMLUtil.setWsuIdAttr((Element)nodeRef, id);
}
}else{
//add to context. dont modify the message.
elementCache.put(id, nodeRef);
}
}
if(logger.isLoggable(Level.FINEST))
logger.log(Level.FINEST, "SignedInfo val id "+id);
targetURI = "#"+id;
byte [] digestValue = fpContext.getDigestValue();
Reference reference = null;
if(!verify && digestValue != null){
reference = signatureFactory.newReference(targetURI,digestMethod,clonedTransformList,null,null,digestValue);
}else{
reference = signatureFactory.newReference(targetURI,digestMethod,clonedTransformList,null,null);
}
references.add(reference);
}
continue;
}else if(signatureType ==SignatureTarget.TARGET_TYPE_VALUE_URI){
targetURI = signatureTarget.getValue();
if(targetURI == null){
targetURI="";
}
if(targetURI == MessageConstants.PROCESS_ALL_ATTACHMENTS){
Iterator itr = secureMessage.getAttachments();
if ( !itr.hasNext()) {
logger.log(Level.SEVERE, LogStringsMessages.WSS_1372_NO_ATTACHMENT_FOUND());
throw new XWSSecurityException("No attachment present in the message");
//logger.log(Level.WARNING, "No Attachment Part present in the message to be secured");
//continue;
}
while(itr.hasNext()){
String cid = null;
AttachmentPart ap = (AttachmentPart)itr.next();
String _cid = ap.getContentId();
if (_cid.charAt(0) == '<' && _cid.charAt(_cid.length()-1) == '>'){
int lindex = _cid.lastIndexOf('>');
int sindex = _cid.indexOf('<');
if(lindex < sindex || lindex == sindex){
//log error
logger.log(Level.SEVERE,LogStringsMessages.WSS_1303_CID_ERROR());
}
cid = "cid:"+_cid.substring(sindex+1,lindex);
}else{
cid = "cid:"+_cid;
}
Reference reference = signatureFactory.newReference(cid,digestMethod,transformList,null,null);
references.add(reference);
}
continue;
}else{
if (exclTransformToBeAdded) {
// exc-14-n must be one of the last transforms under ReferenceList by default.
// String transformAlgo = MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS;
// ExcC14NParameterSpec spec = null;
// Transform transform = signatureFactory.newTransform(transformAlgo,spec);
// transformList.add(transform);
SOAPElement dataElement = null;
if (featureBinding != null && featureBinding.isBSP()) {
// try {
String _uri = targetURI;
if(targetURI.length() > 0 && targetURI.charAt(0)=='#'){
_uri = targetURI.substring(1);
}
dataElement =(SOAPElement) secureMessage.getElementById(_uri);
// } catch (TransformerException te) {
// logger.log(Level.SEVERE, "WSS1373.failedto.resolve.elementbyID", te);
// throw new XWSSecurityException(te.getMessage(), te);
// }
}
String transformAlgo = MessageConstants.TRANSFORM_C14N_EXCL_OMIT_COMMENTS;
ExcC14NParameterSpec spec = null;
if(dataElement != null && !disableInclusivePrefix){
spec = new ExcC14NParameterSpec(getReferenceNamespacePrefixes(dataElement));
}
Transform transform = signatureFactory.newTransform(transformAlgo,spec);
transformList.add(transform);
}
if(targetURI.equals(SignatureTarget.ALL_MESSAGE_HEADERS)){
SOAPHeader soapHeader=null;
try{