src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RetrievalMethodResolver.java

Print this page

        

*** 1,29 **** /* * reserved comment block * DO NOT REMOVE OR ALTER! */ ! /* ! * Copyright 1999-2004 The Apache Software Foundation. ! * ! * Licensed under the Apache License, Version 2.0 (the "License"); ! * you may not use this file except in compliance with the License. ! * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * ! * Unless required by applicable law or agreed to in writing, software ! * distributed under the License is distributed on an "AS IS" BASIS, ! * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ! * See the License for the specific language governing permissions and ! * limitations under the License. ! * */ package com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations; - - import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.PublicKey; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; --- 1,29 ---- /* * reserved comment block * DO NOT REMOVE OR ALTER! */ ! /** ! * Licensed to the Apache Software Foundation (ASF) under one ! * or more contributor license agreements. See the NOTICE file ! * distributed with this work for additional information ! * regarding copyright ownership. The ASF licenses this file ! * to you under the Apache License, Version 2.0 (the ! * "License"); you may not use this file except in compliance ! * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * ! * Unless required by applicable law or agreed to in writing, ! * software distributed under the License is distributed on an ! * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ! * KIND, either express or implied. See the License for the ! * specific language governing permissions and limitations ! * under the License. */ package com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.PublicKey; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory;
*** 33,42 **** --- 33,44 ---- import java.util.List; import java.util.ListIterator; import java.util.Set; import javax.xml.XMLConstants; + import javax.xml.parsers.DocumentBuilder; + import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException; import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; import com.sun.org.apache.xml.internal.security.keys.content.RetrievalMethod;
*** 49,314 **** import com.sun.org.apache.xml.internal.security.transforms.Transforms; import com.sun.org.apache.xml.internal.security.utils.Constants; import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.xml.sax.SAXException; - /** * The RetrievalMethodResolver can retrieve public keys and certificates from * other locations. The location is specified using the ds:RetrievalMethod * element which points to the location. This includes the handling of raw * (binary) X.509 certificate which are not encapsulated in an XML structure. * If the retrieval process encounters an element which the * RetrievalMethodResolver cannot handle itself, resolving of the extracted * element is delegated back to the KeyResolver mechanism. * ! * @author $Author: mullan $ modified by Dave Garcia */ public class RetrievalMethodResolver extends KeyResolverSpi { ! /** {@link java.util.logging} logging facility */ ! static java.util.logging.Logger log = ! java.util.logging.Logger.getLogger( ! RetrievalMethodResolver.class.getName()); /** * Method engineResolvePublicKey * @inheritDoc * @param element ! * @param BaseURI * @param storage - * */ public PublicKey engineLookupAndResolvePublicKey( ! Element element, String BaseURI, StorageResolver storage) ! { ! if (!XMLUtils.elementIsInSignatureSpace(element, ! Constants._TAG_RETRIEVALMETHOD)) { return null; } try { ! //Create a retrieval method over the given element ! RetrievalMethod rm = new RetrievalMethod(element, BaseURI); String type = rm.getType(); ! XMLSignatureInput resource=resolveInput(rm,BaseURI); if (RetrievalMethod.TYPE_RAWX509.equals(type)) { ! //a raw certificate, direct parsing is done! ! X509Certificate cert=getRawCertificate(resource); if (cert != null) { return cert.getPublicKey(); } return null; ! }; ! Element e = obtainRefrenceElement(resource); ! return resolveKey(e,BaseURI,storage); } catch (XMLSecurityException ex) { log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); } catch (CertificateException ex) { log.log(java.util.logging.Level.FINE, "CertificateException", ex); } catch (IOException ex) { log.log(java.util.logging.Level.FINE, "IOException", ex); } catch (ParserConfigurationException e) { log.log(java.util.logging.Level.FINE, "ParserConfigurationException", e); } catch (SAXException e) { log.log(java.util.logging.Level.FINE, "SAXException", e); } - return null; - } - - static private Element obtainRefrenceElement(XMLSignatureInput resource) throws CanonicalizationException, ParserConfigurationException, IOException, SAXException, KeyResolverException { - Element e; - if (resource.isElement()){ - e=(Element) resource.getSubNode(); - } else if (resource.isNodeSet()) { - //Retrieved resource is a nodeSet - e=getDocumentElement(resource.getNodeSet()); - } else { - //Retrieved resource is an inputStream - byte inputBytes[] = resource.getBytes(); - e = getDocFromBytes(inputBytes); - //otherwise, we parse the resource, create an Element and delegate - if (log.isLoggable(java.util.logging.Level.FINE)) - log.log(java.util.logging.Level.FINE, "we have to parse " + inputBytes.length + " bytes"); } ! return e; } /** * Method engineResolveX509Certificate * @inheritDoc * @param element ! * @param BaseURI * @param storage - * */ public X509Certificate engineLookupResolveX509Certificate( ! Element element, String BaseURI, StorageResolver storage) ! { ! if (!XMLUtils.elementIsInSignatureSpace(element, ! Constants._TAG_RETRIEVALMETHOD)) { return null; } try { ! RetrievalMethod rm = new RetrievalMethod(element, BaseURI); String type = rm.getType(); ! XMLSignatureInput resource=resolveInput(rm,BaseURI); if (RetrievalMethod.TYPE_RAWX509.equals(type)) { ! X509Certificate cert=getRawCertificate(resource); ! return cert; } ! Element e = obtainRefrenceElement(resource); ! return resolveCertificate(e,BaseURI,storage); } catch (XMLSecurityException ex) { log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); } catch (CertificateException ex) { log.log(java.util.logging.Level.FINE, "CertificateException", ex); } catch (IOException ex) { log.log(java.util.logging.Level.FINE, "IOException", ex); } catch (ParserConfigurationException e) { log.log(java.util.logging.Level.FINE, "ParserConfigurationException", e); } catch (SAXException e) { log.log(java.util.logging.Level.FINE, "SAXException", e); } return null; } /** * Retrieves a x509Certificate from the given information * @param e ! * @param BaseURI * @param storage * @return * @throws KeyResolverException */ ! static private X509Certificate resolveCertificate(Element e,String BaseURI,StorageResolver storage) throws KeyResolverException{ ! if (log.isLoggable(java.util.logging.Level.FINE)) ! log.log(java.util.logging.Level.FINE, "Now we have a {" + e.getNamespaceURI() + "}"+ e.getLocalName() + " Element"); ! //An element has been provided if (e != null) { ! return KeyResolver.getX509Certificate(e,BaseURI, storage); } return null; } /** ! * Retrieves a x509Certificate from the given information * @param e ! * @param BaseURI * @param storage * @return * @throws KeyResolverException */ ! static private PublicKey resolveKey(Element e,String BaseURI,StorageResolver storage) throws KeyResolverException{ ! if (log.isLoggable(java.util.logging.Level.FINE)) ! log.log(java.util.logging.Level.FINE, "Now we have a {" + e.getNamespaceURI() + "}"+ e.getLocalName() + " Element"); ! //An element has been provided if (e != null) { ! return KeyResolver.getPublicKey(e,BaseURI, storage); } return null; } ! static private X509Certificate getRawCertificate(XMLSignatureInput resource) throws CanonicalizationException, IOException, CertificateException{ byte inputBytes[] = resource.getBytes(); // if the resource stores a raw certificate, we have to handle it ! CertificateFactory certFact =CertificateFactory.getInstance(XMLX509Certificate.JCA_CERT_ID); ! X509Certificate cert =(X509Certificate) certFact.generateCertificate(new ByteArrayInputStream(inputBytes)); return cert; } /** * Resolves the input from the given retrieval method * @return * @throws XMLSecurityException */ ! static private XMLSignatureInput resolveInput(RetrievalMethod rm,String BaseURI) throws XMLSecurityException{ Attr uri = rm.getURIAttr(); ! //Apply the trnasforms Transforms transforms = rm.getTransforms(); ! ResourceResolver resRes = ResourceResolver.getInstance(uri, BaseURI); ! if (resRes != null) { ! XMLSignatureInput resource = resRes.resolve(uri, BaseURI); if (transforms != null) { log.log(java.util.logging.Level.FINE, "We have Transforms"); resource = transforms.performTransforms(resource); } return resource; } - return null; - } /** * Parses a byte array and returns the parsed Element. * * @param bytes * @return the Document Element after parsing bytes * @throws KeyResolverException if something goes wrong */ ! static Element getDocFromBytes(byte[] bytes) throws KeyResolverException { try { ! javax.xml.parsers.DocumentBuilderFactory dbf =javax.xml.parsers.DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE); ! javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder(); ! org.w3c.dom.Document doc = ! db.parse(new java.io.ByteArrayInputStream(bytes)); return doc.getDocumentElement(); ! } catch (org.xml.sax.SAXException ex) { throw new KeyResolverException("empty", ex); ! } catch (java.io.IOException ex) { throw new KeyResolverException("empty", ex); ! } catch (javax.xml.parsers.ParserConfigurationException ex) { throw new KeyResolverException("empty", ex); } } /** * Method engineResolveSecretKey * @inheritDoc * @param element ! * @param BaseURI * @param storage - * */ public javax.crypto.SecretKey engineLookupAndResolveSecretKey( ! Element element, String BaseURI, StorageResolver storage) ! { return null; } ! static Element getDocumentElement(Set<Node> set) { ! Iterator<Node> it=set.iterator(); ! Element e=null; while (it.hasNext()) { ! Node currentNode=it.next(); ! if (currentNode != null && currentNode.getNodeType() == Node.ELEMENT_NODE) { ! e=(Element)currentNode; break; } - } ! List<Element> parents=new ArrayList<Element>(10); ! //Obtain all the parents of the elemnt while (e != null) { parents.add(e); ! Node n=e.getParentNode(); ! if (n == null || n.getNodeType() != Node.ELEMENT_NODE) { break; } ! e=(Element)n; } ! //Visit them in reverse order. ! ListIterator<Element> it2=parents.listIterator(parents.size()-1); ! Element ele=null; while (it2.hasPrevious()) { ! ele=it2.previous(); if (set.contains(ele)) { return ele; } } return null; --- 51,389 ---- import com.sun.org.apache.xml.internal.security.transforms.Transforms; import com.sun.org.apache.xml.internal.security.utils.Constants; import com.sun.org.apache.xml.internal.security.utils.XMLUtils; import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver; import org.w3c.dom.Attr; + import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.xml.sax.SAXException; /** * The RetrievalMethodResolver can retrieve public keys and certificates from * other locations. The location is specified using the ds:RetrievalMethod * element which points to the location. This includes the handling of raw * (binary) X.509 certificate which are not encapsulated in an XML structure. * If the retrieval process encounters an element which the * RetrievalMethodResolver cannot handle itself, resolving of the extracted * element is delegated back to the KeyResolver mechanism. * ! * @author $Author: raul $ modified by Dave Garcia */ public class RetrievalMethodResolver extends KeyResolverSpi { ! /** {@link org.apache.commons.logging} logging facility */ ! private static java.util.logging.Logger log = ! java.util.logging.Logger.getLogger(RetrievalMethodResolver.class.getName()); /** * Method engineResolvePublicKey * @inheritDoc * @param element ! * @param baseURI * @param storage */ public PublicKey engineLookupAndResolvePublicKey( ! Element element, String baseURI, StorageResolver storage ! ) { ! if (!XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_RETRIEVALMETHOD)) { return null; } try { ! // Create a retrieval method over the given element ! RetrievalMethod rm = new RetrievalMethod(element, baseURI); String type = rm.getType(); ! XMLSignatureInput resource = resolveInput(rm, baseURI, secureValidation); if (RetrievalMethod.TYPE_RAWX509.equals(type)) { ! // a raw certificate, direct parsing is done! ! X509Certificate cert = getRawCertificate(resource); if (cert != null) { return cert.getPublicKey(); } return null; ! } ! Element e = obtainReferenceElement(resource); ! ! // Check to make sure that the reference is not to another RetrievalMethod ! // which points to this element ! if (XMLUtils.elementIsInSignatureSpace(e, Constants._TAG_RETRIEVALMETHOD)) { ! if (secureValidation) { ! String error = "Error: It is forbidden to have one RetrievalMethod " ! + "point to another with secure validation"; ! if (log.isLoggable(java.util.logging.Level.FINE)) { ! log.log(java.util.logging.Level.FINE, error); ! } ! return null; ! } ! RetrievalMethod rm2 = new RetrievalMethod(e, baseURI); ! XMLSignatureInput resource2 = resolveInput(rm2, baseURI, secureValidation); ! Element e2 = obtainReferenceElement(resource2); ! if (e2 == element) { ! if (log.isLoggable(java.util.logging.Level.FINE)) { ! log.log(java.util.logging.Level.FINE, "Error: Can't have RetrievalMethods pointing to each other"); ! } ! return null; ! } ! } ! ! return resolveKey(e, baseURI, storage); } catch (XMLSecurityException ex) { + if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); + } } catch (CertificateException ex) { + if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "CertificateException", ex); + } } catch (IOException ex) { + if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "IOException", ex); + } } catch (ParserConfigurationException e) { + if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "ParserConfigurationException", e); + } } catch (SAXException e) { + if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "SAXException", e); } } ! return null; } /** * Method engineResolveX509Certificate * @inheritDoc * @param element ! * @param baseURI * @param storage */ public X509Certificate engineLookupResolveX509Certificate( ! Element element, String baseURI, StorageResolver storage) { ! if (!XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_RETRIEVALMETHOD)) { return null; } try { ! RetrievalMethod rm = new RetrievalMethod(element, baseURI); String type = rm.getType(); ! XMLSignatureInput resource = resolveInput(rm, baseURI, secureValidation); if (RetrievalMethod.TYPE_RAWX509.equals(type)) { ! return getRawCertificate(resource); } ! ! Element e = obtainReferenceElement(resource); ! ! // Check to make sure that the reference is not to another RetrievalMethod ! // which points to this element ! if (XMLUtils.elementIsInSignatureSpace(e, Constants._TAG_RETRIEVALMETHOD)) { ! if (secureValidation) { ! String error = "Error: It is forbidden to have one RetrievalMethod " ! + "point to another with secure validation"; ! if (log.isLoggable(java.util.logging.Level.FINE)) { ! log.log(java.util.logging.Level.FINE, error); ! } ! return null; ! } ! RetrievalMethod rm2 = new RetrievalMethod(e, baseURI); ! XMLSignatureInput resource2 = resolveInput(rm2, baseURI, secureValidation); ! Element e2 = obtainReferenceElement(resource2); ! if (e2 == element) { ! if (log.isLoggable(java.util.logging.Level.FINE)) { ! log.log(java.util.logging.Level.FINE, "Error: Can't have RetrievalMethods pointing to each other"); ! } ! return null; ! } ! } ! ! return resolveCertificate(e, baseURI, storage); } catch (XMLSecurityException ex) { + if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "XMLSecurityException", ex); + } } catch (CertificateException ex) { + if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "CertificateException", ex); + } } catch (IOException ex) { + if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "IOException", ex); + } } catch (ParserConfigurationException e) { + if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "ParserConfigurationException", e); + } } catch (SAXException e) { + if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "SAXException", e); } + } return null; } /** * Retrieves a x509Certificate from the given information * @param e ! * @param baseURI * @param storage * @return * @throws KeyResolverException */ ! private static X509Certificate resolveCertificate( ! Element e, String baseURI, StorageResolver storage ! ) throws KeyResolverException { ! if (log.isLoggable(java.util.logging.Level.FINE)) { ! log.log(java.util.logging.Level.FINE, "Now we have a {" + e.getNamespaceURI() + "}" ! + e.getLocalName() + " Element"); ! } ! // An element has been provided if (e != null) { ! return KeyResolver.getX509Certificate(e, baseURI, storage); } return null; } /** ! * Retrieves a PublicKey from the given information * @param e ! * @param baseURI * @param storage * @return * @throws KeyResolverException */ ! private static PublicKey resolveKey( ! Element e, String baseURI, StorageResolver storage ! ) throws KeyResolverException { ! if (log.isLoggable(java.util.logging.Level.FINE)) { ! log.log(java.util.logging.Level.FINE, "Now we have a {" + e.getNamespaceURI() + "}" ! + e.getLocalName() + " Element"); ! } ! // An element has been provided if (e != null) { ! return KeyResolver.getPublicKey(e, baseURI, storage); } return null; } ! private static Element obtainReferenceElement(XMLSignatureInput resource) ! throws CanonicalizationException, ParserConfigurationException, ! IOException, SAXException, KeyResolverException { ! Element e; ! if (resource.isElement()){ ! e = (Element) resource.getSubNode(); ! } else if (resource.isNodeSet()) { ! // Retrieved resource is a nodeSet ! e = getDocumentElement(resource.getNodeSet()); ! } else { ! // Retrieved resource is an inputStream ! byte inputBytes[] = resource.getBytes(); ! e = getDocFromBytes(inputBytes); ! // otherwise, we parse the resource, create an Element and delegate ! if (log.isLoggable(java.util.logging.Level.FINE)) { ! log.log(java.util.logging.Level.FINE, "we have to parse " + inputBytes.length + " bytes"); ! } ! } ! return e; ! } ! ! private static X509Certificate getRawCertificate(XMLSignatureInput resource) ! throws CanonicalizationException, IOException, CertificateException { byte inputBytes[] = resource.getBytes(); // if the resource stores a raw certificate, we have to handle it ! CertificateFactory certFact = ! CertificateFactory.getInstance(XMLX509Certificate.JCA_CERT_ID); ! X509Certificate cert = (X509Certificate) ! certFact.generateCertificate(new ByteArrayInputStream(inputBytes)); return cert; } + /** * Resolves the input from the given retrieval method * @return * @throws XMLSecurityException */ ! private static XMLSignatureInput resolveInput( ! RetrievalMethod rm, String baseURI, boolean secureValidation ! ) throws XMLSecurityException { Attr uri = rm.getURIAttr(); ! // Apply the transforms Transforms transforms = rm.getTransforms(); ! ResourceResolver resRes = ResourceResolver.getInstance(uri, baseURI, secureValidation); ! XMLSignatureInput resource = resRes.resolve(uri, baseURI, secureValidation); if (transforms != null) { + if (log.isLoggable(java.util.logging.Level.FINE)) { log.log(java.util.logging.Level.FINE, "We have Transforms"); + } resource = transforms.performTransforms(resource); } return resource; } /** * Parses a byte array and returns the parsed Element. * * @param bytes * @return the Document Element after parsing bytes * @throws KeyResolverException if something goes wrong */ ! private static Element getDocFromBytes(byte[] bytes) throws KeyResolverException { try { ! DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE); ! DocumentBuilder db = dbf.newDocumentBuilder(); ! Document doc = db.parse(new ByteArrayInputStream(bytes)); return doc.getDocumentElement(); ! } catch (SAXException ex) { throw new KeyResolverException("empty", ex); ! } catch (IOException ex) { throw new KeyResolverException("empty", ex); ! } catch (ParserConfigurationException ex) { throw new KeyResolverException("empty", ex); } } /** * Method engineResolveSecretKey * @inheritDoc * @param element ! * @param baseURI * @param storage */ public javax.crypto.SecretKey engineLookupAndResolveSecretKey( ! Element element, String baseURI, StorageResolver storage ! ) { return null; } ! private static Element getDocumentElement(Set<Node> set) { ! Iterator<Node> it = set.iterator(); ! Element e = null; while (it.hasNext()) { ! Node currentNode = it.next(); ! if (currentNode != null && Node.ELEMENT_NODE == currentNode.getNodeType()) { ! e = (Element) currentNode; break; } } ! List<Node> parents = new ArrayList<Node>(); ! // Obtain all the parents of the elemnt while (e != null) { parents.add(e); ! Node n = e.getParentNode(); ! if (n == null || Node.ELEMENT_NODE != n.getNodeType()) { break; } ! e = (Element) n; } ! // Visit them in reverse order. ! ListIterator<Node> it2 = parents.listIterator(parents.size()-1); ! Element ele = null; while (it2.hasPrevious()) { ! ele = (Element) it2.previous(); if (set.contains(ele)) { return ele; } } return null;