0N/A/*
0N/A * reserved comment block
0N/A * DO NOT REMOVE OR ALTER!
0N/A */
0N/A/*
0N/A * Copyright 1999-2004 The Apache Software Foundation.
0N/A *
0N/A * Licensed under the Apache License, Version 2.0 (the "License");
0N/A * you may not use this file except in compliance with the License.
0N/A * You may obtain a copy of the License at
0N/A *
0N/A * http://www.apache.org/licenses/LICENSE-2.0
0N/A *
0N/A * Unless required by applicable law or agreed to in writing, software
0N/A * distributed under the License is distributed on an "AS IS" BASIS,
0N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0N/A * See the License for the specific language governing permissions and
0N/A * limitations under the License.
0N/A *
0N/A */
0N/Apackage com.sun.org.apache.xml.internal.security.signature;
0N/A
0N/Aimport java.io.ByteArrayInputStream;
0N/Aimport java.io.IOException;
0N/Aimport java.io.OutputStream;
0N/Aimport javax.crypto.SecretKey;
0N/Aimport javax.crypto.spec.SecretKeySpec;
6159N/Aimport javax.xml.XMLConstants;
0N/Aimport javax.xml.parsers.ParserConfigurationException;
0N/A
0N/Aimport com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm;
0N/Aimport com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
0N/Aimport com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
0N/Aimport com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
0N/Aimport com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
0N/Aimport com.sun.org.apache.xml.internal.security.utils.Constants;
0N/Aimport com.sun.org.apache.xml.internal.security.utils.XMLUtils;
0N/Aimport com.sun.org.apache.xml.internal.security.transforms.params.InclusiveNamespaces;
0N/Aimport org.w3c.dom.Document;
0N/Aimport org.w3c.dom.Element;
0N/Aimport org.w3c.dom.Node;
0N/Aimport org.xml.sax.SAXException;
0N/A
0N/A/**
0N/A * Handles <code>&lt;ds:SignedInfo&gt;</code> elements
0N/A * This <code>SignedInfo<code> element includes the canonicalization algorithm,
661N/A * a signature algorithm, and one or more references.
661N/A *
0N/A * @author Christian Geuer-Pollmann
0N/A */
0N/Apublic class SignedInfo extends Manifest {
0N/A
661N/A /** Field _signatureAlgorithm */
661N/A private SignatureAlgorithm _signatureAlgorithm = null;
0N/A
661N/A /** Field _c14nizedBytes */
661N/A private byte[] _c14nizedBytes = null;
661N/A
661N/A private Element c14nMethod;
661N/A private Element signatureMethod;
0N/A
661N/A /**
661N/A * Overwrites {@link Manifest#addDocument} because it creates another
661N/A * Element.
661N/A *
661N/A * @param doc the {@link Document} in which <code>XMLsignature</code> will
661N/A * be placed
661N/A * @throws XMLSecurityException
661N/A */
661N/A public SignedInfo(Document doc) throws XMLSecurityException {
661N/A this(doc, XMLSignature.ALGO_ID_SIGNATURE_DSA,
661N/A Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
661N/A }
0N/A
661N/A /**
661N/A * Constructs {@link SignedInfo} using given Canonicalization algorithm and
661N/A * Signature algorithm.
661N/A *
661N/A * @param doc <code>SignedInfo</code> is placed in this document
661N/A * @param signatureMethodURI URI representation of the Digest and
661N/A * Signature algorithm
661N/A * @param canonicalizationMethodURI URI representation of the
661N/A * Canonicalization method
661N/A * @throws XMLSecurityException
661N/A */
661N/A public SignedInfo(Document doc, String signatureMethodURI,
661N/A String canonicalizationMethodURI)
0N/A throws XMLSecurityException {
661N/A this(doc, signatureMethodURI, 0, canonicalizationMethodURI);
661N/A }
0N/A
661N/A /**
661N/A * Constructor SignedInfo
661N/A *
661N/A * @param doc <code>SignedInfo</code> is placed in this document
661N/A * @param signatureMethodURI URI representation of the Digest and
661N/A * Signature algorithm
661N/A * @param hMACOutputLength
661N/A * @param canonicalizationMethodURI URI representation of the
661N/A * Canonicalization method
661N/A * @throws XMLSecurityException
661N/A */
661N/A public SignedInfo(Document doc, String signatureMethodURI,
661N/A int hMACOutputLength, String canonicalizationMethodURI)
0N/A throws XMLSecurityException {
0N/A
661N/A super(doc);
0N/A
661N/A c14nMethod = XMLUtils.createElementInSignatureSpace(this._doc,
0N/A Constants._TAG_CANONICALIZATIONMETHOD);
0N/A
661N/A c14nMethod.setAttributeNS(null, Constants._ATT_ALGORITHM,
661N/A canonicalizationMethodURI);
661N/A this._constructionElement.appendChild(c14nMethod);
661N/A XMLUtils.addReturnToElement(this._constructionElement);
661N/A
661N/A if (hMACOutputLength > 0) {
0N/A this._signatureAlgorithm = new SignatureAlgorithm(this._doc,
661N/A signatureMethodURI, hMACOutputLength);
661N/A } else {
0N/A this._signatureAlgorithm = new SignatureAlgorithm(this._doc,
661N/A signatureMethodURI);
661N/A }
0N/A
661N/A signatureMethod = this._signatureAlgorithm.getElement();
661N/A this._constructionElement.appendChild(signatureMethod);
661N/A XMLUtils.addReturnToElement(this._constructionElement);
661N/A }
0N/A
661N/A /**
661N/A * @param doc
661N/A * @param signatureMethodElem
661N/A * @param canonicalizationMethodElem
661N/A * @throws XMLSecurityException
661N/A */
661N/A public SignedInfo(Document doc, Element signatureMethodElem,
661N/A Element canonicalizationMethodElem) throws XMLSecurityException {
0N/A
661N/A super(doc);
661N/A // Check this?
661N/A this.c14nMethod = canonicalizationMethodElem;
661N/A this._constructionElement.appendChild(c14nMethod);
661N/A XMLUtils.addReturnToElement(this._constructionElement);
0N/A
661N/A this._signatureAlgorithm =
661N/A new SignatureAlgorithm(signatureMethodElem, null);
0N/A
661N/A signatureMethod = this._signatureAlgorithm.getElement();
661N/A this._constructionElement.appendChild(signatureMethod);
661N/A
661N/A XMLUtils.addReturnToElement(this._constructionElement);
661N/A }
0N/A
661N/A /**
661N/A * Build a {@link SignedInfo} from an {@link Element}
661N/A *
661N/A * @param element <code>SignedInfo</code>
661N/A * @param baseURI the URI of the resource where the XML instance was stored
661N/A * @throws XMLSecurityException
661N/A * @see <A HREF="http://lists.w3.org/Archives/Public/w3c-ietf-xmldsig/2001OctDec/0033.html">Question</A>
661N/A * @see <A HREF="http://lists.w3.org/Archives/Public/w3c-ietf-xmldsig/2001OctDec/0054.html">Answer</A>
661N/A */
661N/A public SignedInfo(Element element, String baseURI)
0N/A throws XMLSecurityException {
0N/A
661N/A // Parse the Reference children and Id attribute in the Manifest
661N/A super(element, baseURI);
0N/A
661N/A /* canonicalize ds:SignedInfo, reparse it into a new document
661N/A * and replace the original not-canonicalized ds:SignedInfo by
661N/A * the re-parsed canonicalized one.
661N/A */
661N/A c14nMethod = XMLUtils.getNextElement(element.getFirstChild());
661N/A String c14nMethodURI = this.getCanonicalizationMethodURI();
661N/A if (!(c14nMethodURI.equals(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS) ||
661N/A c14nMethodURI.equals(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS) ||
661N/A c14nMethodURI.equals(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS) ||
661N/A c14nMethodURI.equals(Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS))) {
661N/A // the c14n is not a secure one and can rewrite the URIs or like
661N/A // that reparse the SignedInfo to be sure
661N/A try {
661N/A Canonicalizer c14nizer =
661N/A Canonicalizer.getInstance(this.getCanonicalizationMethodURI());
0N/A
661N/A this._c14nizedBytes =
661N/A c14nizer.canonicalizeSubtree(this._constructionElement);
661N/A javax.xml.parsers.DocumentBuilderFactory dbf =
661N/A javax.xml.parsers.DocumentBuilderFactory.newInstance();
661N/A dbf.setNamespaceAware(true);
6159N/A dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
6159N/A Boolean.TRUE);
661N/A javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
6159N/A Document newdoc =
661N/A db.parse(new ByteArrayInputStream(this._c14nizedBytes));
661N/A Node imported =
661N/A this._doc.importNode(newdoc.getDocumentElement(), true);
0N/A
661N/A this._constructionElement.getParentNode().replaceChild(imported,
661N/A this._constructionElement);
0N/A
661N/A this._constructionElement = (Element) imported;
661N/A } catch (ParserConfigurationException ex) {
661N/A throw new XMLSecurityException("empty", ex);
661N/A } catch (IOException ex) {
661N/A throw new XMLSecurityException("empty", ex);
661N/A } catch (SAXException ex) {
661N/A throw new XMLSecurityException("empty", ex);
661N/A }
661N/A }
661N/A signatureMethod = XMLUtils.getNextElement(c14nMethod.getNextSibling());
661N/A this._signatureAlgorithm =
661N/A new SignatureAlgorithm(signatureMethod, this.getBaseURI());
661N/A }
0N/A
0N/A /**
0N/A * Tests core validation process
0N/A *
0N/A * @return true if verification was successful
0N/A * @throws MissingResourceFailureException
0N/A * @throws XMLSecurityException
0N/A */
0N/A public boolean verify()
0N/A throws MissingResourceFailureException, XMLSecurityException {
0N/A return super.verifyReferences(false);
0N/A }
0N/A
0N/A /**
0N/A * Tests core validation process
0N/A *
0N/A * @param followManifests defines whether the verification process has to verify referenced <CODE>ds:Manifest</CODE>s, too
0N/A * @return true if verification was successful
0N/A * @throws MissingResourceFailureException
0N/A * @throws XMLSecurityException
0N/A */
0N/A public boolean verify(boolean followManifests)
0N/A throws MissingResourceFailureException, XMLSecurityException {
0N/A return super.verifyReferences(followManifests);
0N/A }
0N/A
0N/A /**
0N/A * Returns getCanonicalizedOctetStream
0N/A *
0N/A * @return the canonicalization result octedt stream of <code>SignedInfo</code> element
0N/A * @throws CanonicalizationException
0N/A * @throws InvalidCanonicalizerException
0N/A * @throws XMLSecurityException
0N/A */
0N/A public byte[] getCanonicalizedOctetStream()
0N/A throws CanonicalizationException, InvalidCanonicalizerException,
0N/A XMLSecurityException {
0N/A
0N/A if ((this._c14nizedBytes == null)
0N/A /*&& (this._state == ElementProxy.MODE_SIGN)*/) {
0N/A Canonicalizer c14nizer =
0N/A Canonicalizer.getInstance(this.getCanonicalizationMethodURI());
0N/A
0N/A this._c14nizedBytes =
0N/A c14nizer.canonicalizeSubtree(this._constructionElement);
0N/A }
0N/A
0N/A // make defensive copy
0N/A byte[] output = new byte[this._c14nizedBytes.length];
0N/A
0N/A System.arraycopy(this._c14nizedBytes, 0, output, 0, output.length);
0N/A
0N/A return output;
0N/A }
0N/A
0N/A /**
0N/A * Output the C14n stream to the give outputstream.
0N/A * @param os
0N/A * @throws CanonicalizationException
0N/A * @throws InvalidCanonicalizerException
0N/A * @throws XMLSecurityException
0N/A */
0N/A public void signInOctectStream(OutputStream os)
0N/A throws CanonicalizationException, InvalidCanonicalizerException,
0N/A XMLSecurityException {
0N/A
0N/A if ((this._c14nizedBytes == null)) {
0N/A Canonicalizer c14nizer =
0N/A Canonicalizer.getInstance(this.getCanonicalizationMethodURI());
0N/A c14nizer.setWriter(os);
0N/A String inclusiveNamespaces = this.getInclusiveNamespaces();
0N/A
0N/A if(inclusiveNamespaces == null)
0N/A c14nizer.canonicalizeSubtree(this._constructionElement);
0N/A else
0N/A c14nizer.canonicalizeSubtree(this._constructionElement, inclusiveNamespaces);
0N/A } else {
0N/A try {
0N/A os.write(this._c14nizedBytes);
0N/A } catch (IOException e) {
0N/A throw new RuntimeException(""+e);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the Canonicalization method URI
0N/A *
0N/A * @return the Canonicalization method URI
0N/A */
0N/A public String getCanonicalizationMethodURI() {
0N/A
661N/A
661N/A return c14nMethod.getAttributeNS(null, Constants._ATT_ALGORITHM);
0N/A }
0N/A
0N/A /**
0N/A * Returns the Signature method URI
0N/A *
0N/A * @return the Signature method URI
0N/A */
0N/A public String getSignatureMethodURI() {
0N/A
0N/A Element signatureElement = this.getSignatureMethodElement();
0N/A
0N/A if (signatureElement != null) {
0N/A return signatureElement.getAttributeNS(null, Constants._ATT_ALGORITHM);
0N/A }
0N/A
0N/A return null;
0N/A }
0N/A
0N/A /**
0N/A * Method getSignatureMethodElement
0N/A * @return gets The SignatureMethod Node.
0N/A *
0N/A */
0N/A public Element getSignatureMethodElement() {
661N/A return signatureMethod;
0N/A }
0N/A
0N/A /**
0N/A * Creates a SecretKey for the appropriate Mac algorithm based on a
0N/A * byte[] array password.
0N/A *
0N/A * @param secretKeyBytes
0N/A * @return the secret key for the SignedInfo element.
0N/A */
0N/A public SecretKey createSecretKey(byte[] secretKeyBytes)
0N/A {
0N/A
0N/A return new SecretKeySpec(secretKeyBytes,
0N/A this._signatureAlgorithm
0N/A .getJCEAlgorithmString());
0N/A }
0N/A
661N/A protected SignatureAlgorithm getSignatureAlgorithm() {
661N/A return _signatureAlgorithm;
661N/A }
0N/A /**
0N/A * Method getBaseLocalName
0N/A * @inheritDoc
0N/A *
0N/A */
0N/A public String getBaseLocalName() {
0N/A return Constants._TAG_SIGNEDINFO;
0N/A }
0N/A
0N/A public String getInclusiveNamespaces() {
0N/A
661N/A
0N/A
661N/A String c14nMethodURI = c14nMethod.getAttributeNS(null, Constants._ATT_ALGORITHM);
0N/A if(!(c14nMethodURI.equals("http://www.w3.org/2001/10/xml-exc-c14n#") ||
0N/A c14nMethodURI.equals("http://www.w3.org/2001/10/xml-exc-c14n#WithComments"))) {
0N/A return null;
0N/A }
0N/A
661N/A Element inclusiveElement = XMLUtils.getNextElement(
661N/A c14nMethod.getFirstChild());
0N/A
0N/A if(inclusiveElement != null)
0N/A {
0N/A try
0N/A {
0N/A String inclusiveNamespaces = new InclusiveNamespaces(inclusiveElement,
0N/A InclusiveNamespaces.ExclusiveCanonicalizationNamespace).getInclusiveNamespaces();
0N/A return inclusiveNamespaces;
0N/A }
0N/A catch (XMLSecurityException e)
0N/A {
0N/A return null;
0N/A }
0N/A }
0N/A return null;
0N/A }
0N/A}