KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > security > signature > SignedInfo


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
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 com.sun.org.apache.xml.internal.security.signature;
18
19
20
21 import java.io.ByteArrayInputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.OutputStream JavaDoc;
24
25 import javax.crypto.SecretKey;
26 import javax.crypto.spec.SecretKeySpec;
27 import javax.xml.parsers.ParserConfigurationException JavaDoc;
28
29 import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm;
30 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
31 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
32 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
33 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
34 import com.sun.org.apache.xml.internal.security.utils.Constants;
35 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
36 import com.sun.org.apache.xml.internal.security.transforms.params.InclusiveNamespaces;
37 import org.w3c.dom.Document JavaDoc;
38 import org.w3c.dom.Element JavaDoc;
39 import org.w3c.dom.Node JavaDoc;
40 import org.xml.sax.SAXException JavaDoc;
41
42
43 /**
44  * Handles <code>&lt;ds:SignedInfo&gt;</code> elements
45  * This <code>SignedInfo<code> element includes the canonicalization algorithm,
46  * a signature algorithm, and one or more references
47  * @author Christian Geuer-Pollmann
48  */

49 public class SignedInfo extends Manifest {
50
51    /** Field _signatureAlgorithm */
52    private SignatureAlgorithm _signatureAlgorithm = null;
53
54    /** Field _c14nizedBytes */
55    private byte[] _c14nizedBytes = null;
56
57    /**
58     * Overwrites {@link Manifest#addDocument} because it creates another Element.
59     *
60     * @param doc the {@link Document} in which <code>XMLsignature</code> will be placed
61     * @throws XMLSecurityException
62     */

63    public SignedInfo(Document JavaDoc doc) throws XMLSecurityException {
64       this(doc, XMLSignature.ALGO_ID_SIGNATURE_DSA, Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
65    }
66
67    /**
68     * Constructs {@link SignedInfo} using given Canoicaliztion algorithm and Signature algorithm
69     *
70     * @param doc <code>SignedInfo</code> is placed in this document
71     * @param CanonicalizationMethodURI URI representation of the Canonicalization method
72     * @param SignatureMethodURI URI representation of the Digest and Signature algorithm
73     * @throws XMLSecurityException
74     */

75    public SignedInfo(
76            Document JavaDoc doc, String JavaDoc SignatureMethodURI, String JavaDoc CanonicalizationMethodURI)
77               throws XMLSecurityException {
78       this(doc, SignatureMethodURI, 0, CanonicalizationMethodURI);
79    }
80
81    /**
82     * Constructor SignedInfo
83     *
84     * @param doc
85     * @param CanonicalizationMethodURI
86     * @param SignatureMethodURI
87     * @param HMACOutputLength
88     * @throws XMLSecurityException
89     */

90    public SignedInfo(
91            Document JavaDoc doc, String JavaDoc SignatureMethodURI, int HMACOutputLength, String JavaDoc CanonicalizationMethodURI)
92               throws XMLSecurityException {
93
94       super(doc);
95
96       // XMLUtils.addReturnToElement(this._constructionElement);
97
{
98          Element JavaDoc canonElem = XMLUtils.createElementInSignatureSpace(this._doc,
99                                 Constants._TAG_CANONICALIZATIONMETHOD);
100
101          canonElem.setAttributeNS(null, Constants._ATT_ALGORITHM,
102                                 CanonicalizationMethodURI);
103          this._constructionElement.appendChild(canonElem);
104          XMLUtils.addReturnToElement(this._constructionElement);
105       }
106       {
107          if (HMACOutputLength > 0) {
108             this._signatureAlgorithm = new SignatureAlgorithm(this._doc,
109                     SignatureMethodURI, HMACOutputLength);
110          } else {
111             this._signatureAlgorithm = new SignatureAlgorithm(this._doc,
112                     SignatureMethodURI);
113          }
114
115          this._constructionElement
116             .appendChild(this._signatureAlgorithm.getElement());
117          XMLUtils.addReturnToElement(this._constructionElement);
118       }
119    }
120    
121    /**
122     * @param doc
123     * @param SignatureMethodElem
124     * @param CanonicalizationMethodElem
125     * @throws XMLSecurityException
126     */

127    public SignedInfo(
128            Document JavaDoc doc, Element JavaDoc SignatureMethodElem, Element JavaDoc CanonicalizationMethodElem)
129               throws XMLSecurityException {
130
131       super(doc);
132
133       this._constructionElement.appendChild(CanonicalizationMethodElem);
134       XMLUtils.addReturnToElement(this._constructionElement);
135
136       this._signatureAlgorithm = new SignatureAlgorithm(SignatureMethodElem, null);
137
138       this._constructionElement
139          .appendChild(this._signatureAlgorithm.getElement());
140       XMLUtils.addReturnToElement(this._constructionElement);
141    }
142
143    /**
144     * Build a {@link SignedInfo} from an {@link Element}
145     *
146     * @param element <code>SignedInfo</code>
147     * @param BaseURI the URI of the resource where the XML instance was stored
148     * @throws XMLSecurityException
149     * @see <A HREF="http://lists.w3.org/Archives/Public/w3c-ietf-xmldsig/2001OctDec/0033.html">Question</A>
150     * @see <A HREF="http://lists.w3.org/Archives/Public/w3c-ietf-xmldsig/2001OctDec/0054.html">Answer</A>
151     */

152    public SignedInfo(Element JavaDoc element, String JavaDoc BaseURI)
153            throws XMLSecurityException {
154
155       // Parse the Reference children and Id attribute in the Manifest
156
super(element, BaseURI);
157
158       /* canonicalize ds:SignedInfo, reparse it into a new document
159        * and replace the original not-canonicalized ds:SignedInfo by
160        * the re-parsed canonicalized one.
161        */

162       String JavaDoc c14nMethodURI=this.getCanonicalizationMethodURI();
163      if (!(c14nMethodURI.equals("http://www.w3.org/TR/2001/REC-xml-c14n-20010315") ||
164             c14nMethodURI.equals("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments") ||
165             c14nMethodURI.equals("http://www.w3.org/2001/10/xml-exc-c14n#") ||
166             c14nMethodURI.equals("http://www.w3.org/2001/10/xml-exc-c14n#WithComments"))) {
167         //The c14n is not a secure one and can rewrite the URIs or like that reparse the SignedInfo to be sure
168
try {
169          Canonicalizer c14nizer =
170             Canonicalizer.getInstance(this.getCanonicalizationMethodURI());
171
172          this._c14nizedBytes =
173             c14nizer.canonicalizeSubtree(this._constructionElement);
174          javax.xml.parsers.DocumentBuilderFactory JavaDoc dbf =
175             javax.xml.parsers.DocumentBuilderFactory.newInstance();
176
177          dbf.setNamespaceAware(true);
178
179          javax.xml.parsers.DocumentBuilder JavaDoc db = dbf.newDocumentBuilder();
180          org.w3c.dom.Document JavaDoc newdoc =
181             db.parse(new ByteArrayInputStream JavaDoc(this._c14nizedBytes));
182          Node JavaDoc imported = this._doc.importNode(newdoc.getDocumentElement(),
183                                               true);
184
185          this._constructionElement.getParentNode().replaceChild(imported,
186                  this._constructionElement);
187
188          this._constructionElement = (Element JavaDoc) imported;
189       } catch (ParserConfigurationException JavaDoc ex) {
190          throw new XMLSecurityException("empty", ex);
191       } catch (IOException JavaDoc ex) {
192          throw new XMLSecurityException("empty", ex);
193       } catch (SAXException JavaDoc ex) {
194          throw new XMLSecurityException("empty", ex);
195       }
196       }
197       this._signatureAlgorithm =
198          new SignatureAlgorithm(this.getSignatureMethodElement(),
199                                 this.getBaseURI());
200    }
201
202    /**
203     * Tests core validation process
204     *
205     * @return true if verification was successful
206     * @throws MissingResourceFailureException
207     * @throws XMLSecurityException
208     */

209    public boolean verify()
210            throws MissingResourceFailureException, XMLSecurityException {
211       return super.verifyReferences(false);
212    }
213
214    /**
215     * Tests core validation process
216     *
217     * @param followManifests defines whether the verification process has to verify referenced <CODE>ds:Manifest</CODE>s, too
218     * @return true if verification was successful
219     * @throws MissingResourceFailureException
220     * @throws XMLSecurityException
221     */

222    public boolean verify(boolean followManifests)
223            throws MissingResourceFailureException, XMLSecurityException {
224       return super.verifyReferences(followManifests);
225    }
226
227    /**
228     * Returns getCanonicalizedOctetStream
229     *
230     * @return the canonicalization result octedt stream of <code>SignedInfo</code> element
231     * @throws CanonicalizationException
232     * @throws InvalidCanonicalizerException
233     * @throws XMLSecurityException
234     */

235    public byte[] getCanonicalizedOctetStream()
236            throws CanonicalizationException, InvalidCanonicalizerException,
237                  XMLSecurityException {
238
239       if ((this._c14nizedBytes == null)
240               /*&& (this._state == ElementProxy.MODE_SIGN)*/) {
241          Canonicalizer c14nizer =
242             Canonicalizer.getInstance(this.getCanonicalizationMethodURI());
243
244          this._c14nizedBytes =
245             c14nizer.canonicalizeSubtree(this._constructionElement);
246       }
247
248       // make defensive copy
249
byte[] output = new byte[this._c14nizedBytes.length];
250
251       System.arraycopy(this._c14nizedBytes, 0, output, 0, output.length);
252
253       return output;
254    }
255    
256    /**
257     * Output the C14n stream to the give outputstream.
258     * @param os
259     * @throws CanonicalizationException
260     * @throws InvalidCanonicalizerException
261     * @throws XMLSecurityException
262     */

263    public void signInOctectStream(OutputStream JavaDoc os)
264        throws CanonicalizationException, InvalidCanonicalizerException,
265        XMLSecurityException {
266
267     if ((this._c14nizedBytes == null)) {
268        Canonicalizer c14nizer =
269           Canonicalizer.getInstance(this.getCanonicalizationMethodURI());
270        c14nizer.setWriter(os);
271        String JavaDoc inclusiveNamespaces = this.getInclusiveNamespaces();
272
273        if(inclusiveNamespaces == null)
274         c14nizer.canonicalizeSubtree(this._constructionElement);
275        else
276         c14nizer.canonicalizeSubtree(this._constructionElement, inclusiveNamespaces);
277     } else {
278         try {
279             os.write(this._c14nizedBytes);
280         } catch (IOException JavaDoc e) {
281             throw new RuntimeException JavaDoc(""+e);
282         }
283     }
284    }
285
286    /**
287     * Returns the Canonicalization method URI
288     *
289     * @return the Canonicalization method URI
290     */

291    public String JavaDoc getCanonicalizationMethodURI() {
292
293     Element JavaDoc el= XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),
294      Constants._TAG_CANONICALIZATIONMETHOD,0);
295      if (el==null) {
296         return null;
297      }
298      return el.getAttributeNS(null, Constants._ATT_ALGORITHM);
299    }
300
301    /**
302     * Returns the Signature method URI
303     *
304     * @return the Signature method URI
305     */

306    public String JavaDoc getSignatureMethodURI() {
307
308       Element JavaDoc signatureElement = this.getSignatureMethodElement();
309
310       if (signatureElement != null) {
311          return signatureElement.getAttributeNS(null, Constants._ATT_ALGORITHM);
312       }
313
314       return null;
315    }
316
317    /**
318     * Method getSignatureMethodElement
319     * @return gets The SignatureMethod Node.
320     *
321     */

322    public Element JavaDoc getSignatureMethodElement() {
323       return XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),
324         Constants._TAG_SIGNATUREMETHOD,0);
325    }
326
327    /**
328     * Creates a SecretKey for the appropriate Mac algorithm based on a
329     * byte[] array password.
330     *
331     * @param secretKeyBytes
332     * @return the secret key for the SignedInfo element.
333     */

334    public SecretKey createSecretKey(byte[] secretKeyBytes)
335    {
336
337       return new SecretKeySpec(secretKeyBytes,
338                                this._signatureAlgorithm
339                                   .getJCEAlgorithmString());
340    }
341
342    /**
343     * Method getBaseLocalName
344     * @inheritDoc
345     *
346     */

347    public String JavaDoc getBaseLocalName() {
348       return Constants._TAG_SIGNEDINFO;
349    }
350
351    public String JavaDoc getInclusiveNamespaces() {
352
353     Element JavaDoc el= XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),
354      Constants._TAG_CANONICALIZATIONMETHOD,0);
355      if (el==null) {
356         return null;
357      }
358
359      String JavaDoc c14nMethodURI = el.getAttributeNS(null, Constants._ATT_ALGORITHM);
360      if(!(c14nMethodURI.equals("http://www.w3.org/2001/10/xml-exc-c14n#") ||
361             c14nMethodURI.equals("http://www.w3.org/2001/10/xml-exc-c14n#WithComments"))) {
362                 return null;
363             }
364
365      Element JavaDoc inclusiveElement = XMLUtils.selectNode(
366              el.getFirstChild(),InclusiveNamespaces.ExclusiveCanonicalizationNamespace,
367         InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES,0);
368
369      if(inclusiveElement != null)
370      {
371          try
372          {
373              String JavaDoc inclusiveNamespaces = new InclusiveNamespaces(inclusiveElement,
374                          InclusiveNamespaces.ExclusiveCanonicalizationNamespace).getInclusiveNamespaces();
375              return inclusiveNamespaces;
376          }
377          catch (XMLSecurityException e)
378          {
379              return null;
380          }
381      }
382      return null;
383     }
384 }
385
Popular Tags