View Javadoc

1   /*
2    * Copyright [2006] [University Corporation for Advanced Internet Development, Inc.]
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.opensaml.xml.signature;
18  
19  import java.util.List;
20  
21  import org.apache.xml.security.Init;
22  import org.apache.xml.security.exceptions.XMLSecurityException;
23  import org.apache.xml.security.signature.XMLSignature;
24  import org.opensaml.xml.security.SecurityHelper;
25  import org.opensaml.xml.signature.impl.SignatureImpl;
26  import org.slf4j.Logger;
27  import org.slf4j.LoggerFactory;
28  
29  /**
30   * This class is responsible for creating the digital signatures for the given signable XMLObjects.
31   * 
32   * This must be done as a seperate step because in order to support the following cases:
33   * <ul>
34   * <li>Multiple signable objects appear in the DOM tree, in which case the order that the objects should be signed in
35   * is not known (e.g. object 1 could appear first in the tree, but contain a reference to signable object 2)</li>
36   * <li>The DOM tree resulting from marshalling of the XMLObject tree is grafted onto another DOM tree which may cause
37   * element ID conflicts that would invalidate the signature</li>
38   * </ul>
39   */
40  public class Signer {
41  
42      /** Constructor. */
43      protected Signer() {
44  
45      }
46  
47      /**
48       * Signs the given XMLObject in the order provided.
49       * 
50       * @param xmlObjects an orderded list of XMLObject to be signed
51       * @throws SignatureException  thrown if there is an error computing the signature
52       */
53      public static void signObjects(List<Signature> xmlObjects) throws SignatureException {
54          for (Signature xmlObject : xmlObjects) {
55              signObject(xmlObject);
56          }
57      }
58  
59      /**
60       * Signs a single XMLObject.
61       * 
62       * @param signature the signature to computer the signature on
63       * @throws SignatureException thrown if there is an error computing the signature
64       */
65      public static void signObject(Signature signature) throws SignatureException {
66          Logger log = getLogger();
67          try {
68              XMLSignature xmlSignature = ((SignatureImpl) signature).getXMLSignature();
69  
70              if (xmlSignature == null) {
71                  log.error("Unable to compute signature, Signature XMLObject does not have the XMLSignature "
72                          + "created during marshalling.");
73                  throw new SignatureException("XMLObject does not have an XMLSignature instance, unable to compute signature");
74              }
75              log.debug("Computing signature over XMLSignature object");
76              xmlSignature.sign(SecurityHelper.extractSigningKey(signature.getSigningCredential()));
77          } catch (XMLSecurityException e) {
78              log.error("An error occured computing the digital signature", e);
79              throw new SignatureException("Signature computation error", e);
80          }
81      }
82      
83      /**
84       * Get an SLF4J Logger.
85       * 
86       * @return a Logger instance
87       */
88      private static Logger getLogger() {
89          return LoggerFactory.getLogger(Signer.class);
90      }
91  
92      /*
93       * Initialize the Apache XML security library if it hasn't been already
94       */
95      static {
96          Logger log = getLogger();
97          if (!Init.isInitialized()) {
98              log.debug("Initializing XML security library");
99              Init.init();
100         }
101     }
102 }