View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.ws.security.action;
21  
22  import java.util.List;
23  
24  import javax.security.auth.callback.CallbackHandler;
25  
26  import org.apache.ws.security.WSConstants;
27  import org.apache.ws.security.WSEncryptionPart;
28  import org.apache.ws.security.WSPasswordCallback;
29  import org.apache.ws.security.WSSecurityException;
30  import org.apache.ws.security.handler.RequestData;
31  import org.apache.ws.security.handler.WSHandler;
32  import org.apache.ws.security.message.WSSecSignature;
33  
34  import org.w3c.dom.Document;
35  import org.w3c.dom.Element;
36  import org.w3c.dom.Node;
37  
38  public class SignatureAction implements Action {
39      public void execute(WSHandler handler, int actionToDo, Document doc, RequestData reqData)
40              throws WSSecurityException {
41          CallbackHandler callbackHandler = 
42              handler.getPasswordCallbackHandler(reqData);
43          WSPasswordCallback passwordCallback = 
44              handler.getPasswordCB(reqData.getSignatureUser(), actionToDo, callbackHandler, reqData);
45          WSSecSignature wsSign = new WSSecSignature(reqData.getWssConfig());
46  
47          if (reqData.getSigKeyId() != 0) {
48              wsSign.setKeyIdentifierType(reqData.getSigKeyId());
49          }
50          if (reqData.getSigAlgorithm() != null) {
51              wsSign.setSignatureAlgorithm(reqData.getSigAlgorithm());
52          }
53          if (reqData.getSigDigestAlgorithm() != null) {
54              wsSign.setDigestAlgo(reqData.getSigDigestAlgorithm());
55          }
56  
57          wsSign.setUserInfo(reqData.getSignatureUser(), passwordCallback.getPassword());
58          wsSign.setUseSingleCertificate(reqData.isUseSingleCert());
59          if (reqData.getSignatureParts().size() > 0) {
60              wsSign.setParts(reqData.getSignatureParts());
61          }
62          
63          if (passwordCallback.getKey() != null) {
64              wsSign.setSecretKey(passwordCallback.getKey());
65          }
66  
67          try {
68              wsSign.prepare(doc, reqData.getSigCrypto(), reqData.getSecHeader());
69  
70              Element siblingElementToPrepend = null;
71              for (WSEncryptionPart part : reqData.getSignatureParts()) {
72                  if ("STRTransform".equals(part.getName()) && part.getId() == null) {
73                      part.setId(wsSign.getSecurityTokenReferenceURI());
74                  } else if (reqData.isAppendSignatureAfterTimestamp()
75                          && WSConstants.WSU_NS.equals(part.getNamespace()) 
76                          && "Timestamp".equals(part.getName())) {
77                      int originalSignatureActionIndex = 
78                          reqData.getOriginalSignatureActionPosition();
79                      // Need to figure out where to put the Signature Element in the header
80                      if (originalSignatureActionIndex > 0) {
81                          Element secHeader = reqData.getSecHeader().getSecurityHeader();
82                          Node lastChild = secHeader.getLastChild();
83                          int count = 0;
84                          while (lastChild != null && count < originalSignatureActionIndex) {
85                              while (lastChild != null && lastChild.getNodeType() != Node.ELEMENT_NODE) {
86                                  lastChild = lastChild.getPreviousSibling();
87                              }
88                              count++;
89                          }
90                          if (lastChild instanceof Element) {
91                              siblingElementToPrepend = (Element)lastChild;
92                          }
93                      }
94                  }
95              }
96  
97              List<javax.xml.crypto.dsig.Reference> referenceList = 
98                  wsSign.addReferencesToSign(reqData.getSignatureParts(), reqData.getSecHeader());
99  
100             if (reqData.isAppendSignatureAfterTimestamp() && siblingElementToPrepend == null) {
101                 wsSign.computeSignature(referenceList, false, null);
102             } else {
103                 wsSign.computeSignature(referenceList, true, siblingElementToPrepend);
104             }
105 
106             wsSign.prependBSTElementToHeader(reqData.getSecHeader());
107             reqData.getSignatureValues().add(wsSign.getSignatureValue());
108         } catch (WSSecurityException e) {
109             throw new WSSecurityException("Error during Signature: ", e);
110         }
111     }
112 
113 }