com.sun.xml.wss.impl.dsig.DSigResolver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of webservices-rt Show documentation
Show all versions of webservices-rt Show documentation
This module contains the Metro runtime code.
/*
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package com.sun.xml.wss.impl.dsig;
import com.sun.xml.wss.core.reference.X509ThumbPrintIdentifier;
import com.sun.xml.wss.impl.FilterProcessingContext;
import com.sun.xml.wss.core.reference.X509SubjectKeyIdentifier;
import com.sun.xml.wss.logging.LogDomainConstants;
import com.sun.xml.wss.impl.MessageConstants;
import com.sun.xml.wss.impl.SecurableSoapMessage;
import com.sun.xml.wss.impl.XMLUtil;
import com.sun.xml.wss.XWSSecurityException;
import com.sun.xml.wss.impl.XWSSecurityRuntimeException;
import com.sun.xml.wss.core.ReferenceElement;
import com.sun.xml.wss.core.SecurityToken;
import com.sun.xml.wss.core.SecurityTokenReference;
import com.sun.xml.wss.core.X509SecurityToken;
import com.sun.xml.wss.core.reference.DirectReference;
import com.sun.xml.wss.core.reference.KeyIdentifier;
import com.sun.xml.wss.core.reference.X509IssuerSerial;
import com.sun.xml.wss.logging.impl.dsig.LogStringsMessages;
import com.sun.xml.wss.saml.AssertionUtil;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.math.BigInteger;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Logger;
import javax.xml.crypto.Data;
import javax.xml.crypto.NodeSetData;
import javax.xml.crypto.OctetStreamData;
import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.URIReference;
import javax.xml.crypto.URIReferenceException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.dom.DOMURIReference;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPMessage;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.sun.xml.wss.saml.Assertion;
import com.sun.xml.wss.saml.util.SAMLUtil;
import java.util.logging.Level;
/**
* Implementation of JSR 105 URIDereference interface.
* @author [email protected]
*/
public class DSigResolver implements URIDereferencer{
private static volatile DSigResolver resolver = null;
private static Logger logger = Logger.getLogger (LogDomainConstants.IMPL_SIGNATURE_DOMAIN,
LogDomainConstants.IMPL_SIGNATURE_DOMAIN_BUNDLE);
private String optNSClassName = "org.apache.jcp.xml.dsig.internal.dom.DOMSubTreeData";
private Class _nodeSetClass = null;
private Constructor _constructor = null;
private Boolean _false = Boolean.valueOf(false);
/** Creates a new instance of DSigResolver */
@SuppressWarnings("unchecked")
private DSigResolver () {
try{
_nodeSetClass = Class.forName (optNSClassName);
_constructor = _nodeSetClass.getConstructor (new Class [] {org.w3c.dom.Node.class,boolean.class});
}catch(LinkageError le){
logger.log (Level.FINE,"Not able load JSR 105 RI specific NodeSetData class ",le);
}catch(ClassNotFoundException cne){
logger.log (Level.FINE,"Not able load JSR 105 RI specific NodeSetData class ",cne);
}catch(NoSuchMethodException ne){
}
}
/**
*
* @return URI Dereferencer instance.
*/
public static URIDereferencer getInstance (){
if(resolver == null){
init ();
}
return resolver;
}
private static void init (){
if(resolver == null){
synchronized(DSigResolver.class){
if(resolver == null){
resolver = new DSigResolver ();
}
}
}
}
/**
* resolve the URI of type "cid:" , "attachmentRef:", "http:", "#xyz".
* @param uriRef {@inheritDoc}
* @param context{@inheritDoc}
* @throws URIReferenceException {@inheritDoc}
* @return {@inheritDoc}
*/
public Data dereference (URIReference uriRef, XMLCryptoContext context) throws URIReferenceException {
String uri = null;
try{
if(uriRef instanceof DOMURIReference ){
DOMURIReference domRef = (DOMURIReference) uriRef;
Node node = domRef.getHere ();
if(node.getNodeType () == Node.ATTRIBUTE_NODE){
uri = uriRef.getURI ();
return dereferenceURI (uri,context);
}else if(node.getNodeType () == Node.ELEMENT_NODE ){
if("SecurityTokenReference".equals (node.getLocalName ())){
return derefSecurityTokenReference (node,context);
}
}
}else {
uri = uriRef.getURI ();
if(MessageConstants.debug){
logger.log (Level.FINEST, "URI "+ uri);
}
return dereferenceURI (uri,context);
}
}catch(XWSSecurityException ex){
if(logger.getLevel () == Level.FINEST){
logger.log (Level.FINEST,"Error occurred while resolving"+uri,ex);
}
throw new URIReferenceException (ex.getMessage ());
}
return null;
}
Data dereferenceURI (String uri, XMLCryptoContext context) throws URIReferenceException, XWSSecurityException{
FilterProcessingContext filterContext =(FilterProcessingContext) context.get (MessageConstants.WSS_PROCESSING_CONTEXT);
SecurableSoapMessage secureMsg = filterContext.getSecurableSoapMessage ();
if(uri == null || uri.equals ("")){
SOAPMessage msg = filterContext.getSOAPMessage ();
Document doc = msg.getSOAPPart ();
if(_constructor == null){
return convertToData ((Node)doc,true);
}else{
try{
return (Data)_constructor.newInstance (new Object[] {doc,_false});
}catch(Exception ex){
//throw new XWSSecurityException(ex);
}
return convertToData ((Node)doc,true);
}
}else if(uri.charAt (0) == '#'){
return dereferenceFragment (secureMsg.getIdFromFragmentRef (uri),context);
}else if(uri.startsWith ("cid:") || uri.startsWith ("attachmentRef:")){
return dereferenceAttachments (uri,context);
}else if(uri.startsWith ("http")){
//throw new UnsupportedOperationException("Not yet supported ");
return dereferenceExternalResource (uri,context);
}else {
return dereferenceFragment (uri,context);
}
//throw new URIReferenceException("Resource "+uri+" was not found");
}
Data dereferenceExternalResource (final String uri,XMLCryptoContext context) throws URIReferenceException, XWSSecurityException {
URIDereferencer resolver = WSSPolicyConsumerImpl.getInstance ().getDefaultResolver ();
URIReference uriRef = null;
FilterProcessingContext filterContext =(FilterProcessingContext) context.get (MessageConstants.WSS_PROCESSING_CONTEXT);
SecurableSoapMessage secureMsg = filterContext.getSecurableSoapMessage ();
final Attr uriAttr = secureMsg.getSOAPMessage ().getSOAPPart ().createAttribute ("uri");
uriAttr.setNodeValue (uri);
uriRef = new DOMURIReference (){
public String getURI (){
return uri;
}
public String getType (){
return null;
}
public Node getHere (){
return uriAttr;
}
};
try{
Data data = resolver.dereference (uriRef, context);
if(MessageConstants.debug){
if(data instanceof NodeSetData){
logger.log (Level.FINE,"Node set Data");
}else if(data instanceof OctetStreamData){
logger.log (Level.FINE,"Octet Data");
try{
InputStream is = ((OctetStreamData)data).getOctetStream ();
int len = is.available ();
byte [] bb = new byte[len];
is.read (bb);
logger.log (Level.FINE,"Data: "+new String (bb));
}catch(Exception ex){
logger.log (Level.FINE,"ERROR",ex);
}
}
}
return data;
}catch(URIReferenceException ue){
logger.log (Level.SEVERE,LogStringsMessages.WSS_1325_DSIG_EXTERNALTARGET(ue));
throw ue;
}
}
Data dereferenceAttachments (String uri, XMLCryptoContext context) throws URIReferenceException, XWSSecurityException {
boolean sunAttachmentTransformProvider = true;
FilterProcessingContext filterContext =(FilterProcessingContext)
context.get (MessageConstants.WSS_PROCESSING_CONTEXT);
SecurableSoapMessage secureMsg = filterContext.getSecurableSoapMessage ();
AttachmentPart attachment = secureMsg.getAttachmentPart (uri);
if(attachment == null){
throw new URIReferenceException ("Attachment Resource with Identifier "+uri+" was not found");
}
if(sunAttachmentTransformProvider){
AttachmentData attachData = new AttachmentData ();
attachData.setAttachmentPart (attachment);
return attachData;
}else{
//Attachments need to be serialized and returned as OctectStreamData
//attachment.getDataHandler();
// new OctectStreamData();
throw new UnsupportedOperationException ("Not yet supported ");
}
// throw new URIReferenceException("Attachment Resource with Identifier "+uri+" was not found");
}
Data dereferenceFragment (String uri, XMLCryptoContext context) throws URIReferenceException, XWSSecurityException {
FilterProcessingContext filterContext =(FilterProcessingContext) context.get(MessageConstants.WSS_PROCESSING_CONTEXT);
HashMap elementCache = filterContext.getElementCache ();
if(elementCache.size () > 0){
Object obj = elementCache.get (uri);
if(obj != null ){
if(_constructor == null){
return convertToData ((Element)obj,true);
}else{
try{
return (Data)_constructor.newInstance (new Object[] {obj,_false});
}catch(Exception ex){
//throw new XWSSecurityException(ex);
}
}
return convertToData ((Element)obj,true);
}
}
SecurableSoapMessage secureMsg = filterContext.getSecurableSoapMessage ();
Element element = secureMsg.getElementById (uri);
if(element == null){
throw new URIReferenceException ("Resource with fragment Identifier "+uri+" was not found");
//log;
}
if(_constructor == null){
return convertToData (element,true);
}else{
try{
return (Data)_constructor.newInstance (new Object[] {element,_false});
}catch(Exception ex){
//throw new XWSSecurityException(ex);
}
}
return convertToData (element,true);
}
Data convertToData (final Node node,boolean xpathNodeSet){
final HashSet nodeSet = new HashSet ();
if(xpathNodeSet){
toNodeSet (node,nodeSet);
return new NodeSetData (){
public Iterator iterator (){
return nodeSet.iterator ();
}
};
}else{
return new NodeSetData (){
public Iterator iterator (){
return Collections.singletonList (node).iterator ();
}
};
}
}
@SuppressWarnings("unchecked")
void toNodeSet (final Node rootNode,final Set result){
//handle EKSHA1 under DKT
if (rootNode == null) return;
switch (rootNode.getNodeType ()) {
case Node.ELEMENT_NODE:
result.add (rootNode);
Element el=(Element)rootNode;
if (el.hasAttributes ()) {
NamedNodeMap nl = ((Element)rootNode).getAttributes ();
for (int i=0;i