All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jcp.xml.dsig.internal.dom.DOMReference Maven / Gradle / Ivy

The newest version!
/*     */ package org.jcp.xml.dsig.internal.dom;
/*     */ 
/*     */ import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
/*     */ import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
/*     */ import com.sun.org.apache.xml.internal.security.utils.Base64;
/*     */ import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
/*     */ import java.io.ByteArrayInputStream;
/*     */ import java.io.InputStream;
/*     */ import java.io.OutputStream;
/*     */ import java.net.URI;
/*     */ import java.net.URISyntaxException;
/*     */ import java.security.MessageDigest;
/*     */ import java.security.NoSuchAlgorithmException;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Arrays;
/*     */ import java.util.Collections;
/*     */ import java.util.List;
/*     */ import java.util.logging.Level;
/*     */ import java.util.logging.Logger;
/*     */ import javax.xml.crypto.Data;
/*     */ import javax.xml.crypto.MarshalException;
/*     */ import javax.xml.crypto.NodeSetData;
/*     */ import javax.xml.crypto.OctetStreamData;
/*     */ import javax.xml.crypto.URIDereferencer;
/*     */ import javax.xml.crypto.URIReferenceException;
/*     */ import javax.xml.crypto.XMLCryptoContext;
/*     */ import javax.xml.crypto.dom.DOMCryptoContext;
/*     */ import javax.xml.crypto.dom.DOMURIReference;
/*     */ import javax.xml.crypto.dsig.DigestMethod;
/*     */ import javax.xml.crypto.dsig.Reference;
/*     */ import javax.xml.crypto.dsig.Transform;
/*     */ import javax.xml.crypto.dsig.TransformException;
/*     */ import javax.xml.crypto.dsig.TransformService;
/*     */ import javax.xml.crypto.dsig.XMLSignContext;
/*     */ import javax.xml.crypto.dsig.XMLSignatureException;
/*     */ import javax.xml.crypto.dsig.XMLValidateContext;
/*     */ import org.jcp.xml.dsig.internal.DigesterOutputStream;
/*     */ import org.w3c.dom.Attr;
/*     */ import org.w3c.dom.Document;
/*     */ import org.w3c.dom.Element;
/*     */ import org.w3c.dom.Node;
/*     */ 
/*     */ public final class DOMReference extends DOMStructure
/*     */   implements Reference, DOMURIReference
/*     */ {
/*  48 */   private static Logger log = Logger.getLogger("org.jcp.xml.dsig.internal.dom");
/*     */   private final DigestMethod digestMethod;
/*     */   private final String id;
/*     */   private final List appliedTransforms;
/*     */   private final List transforms;
/*     */   private final List allTransforms;
/*     */   private final Data appliedTransformData;
/*     */   private Attr here;
/*     */   private final String uri;
/*     */   private final String type;
/*     */   private byte[] digestValue;
/*     */   private byte[] calcDigestValue;
/*     */   private Element refElem;
/*  62 */   private boolean digested = false;
/*  63 */   private boolean validated = false;
/*     */   private boolean validationStatus;
/*     */   private Data derefData;
/*     */   private InputStream dis;
/*     */   private MessageDigest md;
/*     */ 
/*     */   public DOMReference(String uri, String type, DigestMethod dm, List transforms, String id)
/*     */   {
/*  86 */     this(uri, type, dm, null, null, transforms, id, null);
/*     */   }
/*     */ 
/*     */   public DOMReference(String uri, String type, DigestMethod dm, List appliedTransforms, Data result, List transforms, String id)
/*     */   {
/*  91 */     this(uri, type, dm, appliedTransforms, result, transforms, id, null);
/*     */   }
/*     */ 
/*     */   public DOMReference(String uri, String type, DigestMethod dm, List appliedTransforms, Data result, List transforms, String id, byte[] digestValue)
/*     */   {
/*  97 */     if (dm == null) {
/*  98 */       throw new NullPointerException("DigestMethod must be non-null");
/*     */     }
/* 100 */     if ((appliedTransforms == null) || (appliedTransforms.isEmpty())) {
/* 101 */       this.appliedTransforms = Collections.EMPTY_LIST;
/*     */     } else {
/* 103 */       List transformsCopy = new ArrayList(appliedTransforms);
/* 104 */       int i = 0; for (int size = transformsCopy.size(); i < size; i++) {
/* 105 */         if (!(transformsCopy.get(i) instanceof Transform)) {
/* 106 */           throw new ClassCastException("appliedTransforms[" + i + "] is not a valid type");
/*     */         }
/*     */       }
/*     */ 
/* 110 */       this.appliedTransforms = Collections.unmodifiableList(transformsCopy);
/*     */     }
/*     */ 
/* 113 */     if ((transforms == null) || (transforms.isEmpty())) {
/* 114 */       this.transforms = Collections.EMPTY_LIST;
/*     */     } else {
/* 116 */       List transformsCopy = new ArrayList(transforms);
/* 117 */       int i = 0; for (int size = transformsCopy.size(); i < size; i++) {
/* 118 */         if (!(transformsCopy.get(i) instanceof Transform)) {
/* 119 */           throw new ClassCastException("transforms[" + i + "] is not a valid type");
/*     */         }
/*     */       }
/*     */ 
/* 123 */       this.transforms = Collections.unmodifiableList(transformsCopy);
/*     */     }
/* 125 */     List all = new ArrayList(this.appliedTransforms);
/* 126 */     all.addAll(this.transforms);
/* 127 */     this.allTransforms = Collections.unmodifiableList(all);
/* 128 */     this.digestMethod = dm;
/* 129 */     this.uri = uri;
/* 130 */     if ((uri != null) && (!uri.equals(""))) {
/*     */       try {
/* 132 */         new URI(uri);
/*     */       } catch (URISyntaxException e) {
/* 134 */         throw new IllegalArgumentException(e.getMessage());
/*     */       }
/*     */     }
/* 137 */     this.type = type;
/* 138 */     this.id = id;
/* 139 */     if (digestValue != null) {
/* 140 */       this.digestValue = ((byte[])digestValue.clone());
/* 141 */       this.digested = true;
/*     */     }
/* 143 */     this.appliedTransformData = result;
/*     */   }
/*     */ 
/*     */   public DOMReference(Element refElem, XMLCryptoContext context)
/*     */     throws MarshalException
/*     */   {
/* 154 */     Element nextSibling = DOMUtils.getFirstChildElement(refElem);
/* 155 */     List transforms = new ArrayList(5);
/* 156 */     if (nextSibling.getLocalName().equals("Transforms")) {
/* 157 */       Element transformElem = DOMUtils.getFirstChildElement(nextSibling);
/* 158 */       while (transformElem != null) {
/* 159 */         transforms.add(new DOMTransform(transformElem, context));
/* 160 */         transformElem = DOMUtils.getNextSiblingElement(transformElem);
/*     */       }
/* 162 */       nextSibling = DOMUtils.getNextSiblingElement(nextSibling);
/*     */     }
/*     */ 
/* 166 */     Element dmElem = nextSibling;
/* 167 */     this.digestMethod = DOMDigestMethod.unmarshal(dmElem);
/*     */     try
/*     */     {
/* 171 */       Element dvElem = DOMUtils.getNextSiblingElement(dmElem);
/* 172 */       this.digestValue = Base64.decode(dvElem);
/*     */     } catch (Base64DecodingException bde) {
/* 174 */       throw new MarshalException(bde);
/*     */     }
/*     */ 
/* 178 */     this.uri = DOMUtils.getAttributeValue(refElem, "URI");
/* 179 */     this.id = DOMUtils.getAttributeValue(refElem, "Id");
/*     */ 
/* 181 */     this.type = DOMUtils.getAttributeValue(refElem, "Type");
/* 182 */     this.here = refElem.getAttributeNodeNS(null, "URI");
/* 183 */     this.refElem = refElem;
/*     */ 
/* 185 */     if (transforms.isEmpty())
/* 186 */       this.transforms = Collections.EMPTY_LIST;
/*     */     else {
/* 188 */       this.transforms = Collections.unmodifiableList(transforms);
/*     */     }
/* 190 */     this.appliedTransforms = Collections.EMPTY_LIST;
/* 191 */     this.allTransforms = transforms;
/* 192 */     this.appliedTransformData = null;
/*     */   }
/*     */ 
/*     */   public DigestMethod getDigestMethod() {
/* 196 */     return this.digestMethod;
/*     */   }
/*     */ 
/*     */   public String getId() {
/* 200 */     return this.id;
/*     */   }
/*     */ 
/*     */   public String getURI() {
/* 204 */     return this.uri;
/*     */   }
/*     */ 
/*     */   public String getType() {
/* 208 */     return this.type;
/*     */   }
/*     */ 
/*     */   public List getTransforms() {
/* 212 */     return this.allTransforms;
/*     */   }
/*     */ 
/*     */   public byte[] getDigestValue() {
/* 216 */     return this.digestValue == null ? null : (byte[])this.digestValue.clone();
/*     */   }
/*     */ 
/*     */   public byte[] getCalculatedDigestValue() {
/* 220 */     return this.calcDigestValue == null ? null : (byte[])this.calcDigestValue.clone();
/*     */   }
/*     */ 
/*     */   public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
/*     */     throws MarshalException
/*     */   {
/* 226 */     if (log.isLoggable(Level.FINE)) {
/* 227 */       log.log(Level.FINE, "Marshalling Reference");
/*     */     }
/* 229 */     Document ownerDoc = DOMUtils.getOwnerDocument(parent);
/*     */ 
/* 231 */     this.refElem = DOMUtils.createElement(ownerDoc, "Reference", "http://www.w3.org/2000/09/xmldsig#", dsPrefix);
/*     */ 
/* 235 */     DOMUtils.setAttributeID(this.refElem, "Id", this.id);
/* 236 */     DOMUtils.setAttribute(this.refElem, "URI", this.uri);
/* 237 */     DOMUtils.setAttribute(this.refElem, "Type", this.type);
/*     */ 
/* 240 */     if ((!this.transforms.isEmpty()) || (!this.appliedTransforms.isEmpty())) {
/* 241 */       Element transformsElem = DOMUtils.createElement(ownerDoc, "Transforms", "http://www.w3.org/2000/09/xmldsig#", dsPrefix);
/*     */ 
/* 243 */       this.refElem.appendChild(transformsElem);
/* 244 */       int i = 0; for (int size = this.appliedTransforms.size(); i < size; i++) {
/* 245 */         DOMStructure transform = (DOMStructure)this.appliedTransforms.get(i);
/*     */ 
/* 247 */         transform.marshal(transformsElem, dsPrefix, context);
/*     */       }
/* 249 */       int i = 0; for (int size = this.transforms.size(); i < size; i++) {
/* 250 */         DOMStructure transform = (DOMStructure)this.transforms.get(i);
/* 251 */         transform.marshal(transformsElem, dsPrefix, context);
/*     */       }
/*     */ 
/*     */     }
/*     */ 
/* 256 */     ((DOMDigestMethod)this.digestMethod).marshal(this.refElem, dsPrefix, context);
/*     */ 
/* 259 */     if (log.isLoggable(Level.FINE)) {
/* 260 */       log.log(Level.FINE, "Adding digestValueElem");
/*     */     }
/* 262 */     Element digestValueElem = DOMUtils.createElement(ownerDoc, "DigestValue", "http://www.w3.org/2000/09/xmldsig#", dsPrefix);
/*     */ 
/* 264 */     if (this.digestValue != null) {
/* 265 */       digestValueElem.appendChild(ownerDoc.createTextNode(Base64.encode(this.digestValue)));
/*     */     }
/*     */ 
/* 268 */     this.refElem.appendChild(digestValueElem);
/*     */ 
/* 270 */     parent.appendChild(this.refElem);
/* 271 */     this.here = this.refElem.getAttributeNodeNS(null, "URI");
/*     */   }
/*     */ 
/*     */   public void digest(XMLSignContext signContext) throws XMLSignatureException
/*     */   {
/* 276 */     Data data = null;
/* 277 */     if (this.appliedTransformData == null)
/* 278 */       data = dereference(signContext);
/*     */     else {
/* 280 */       data = this.appliedTransformData;
/*     */     }
/* 282 */     byte[] digestInput = transform(data, signContext);
/* 283 */     this.digestValue = digestInput;
/*     */ 
/* 286 */     String encodedDV = Base64.encode(this.digestValue);
/* 287 */     if (log.isLoggable(Level.FINE)) {
/* 288 */       log.log(Level.FINE, "Reference object uri = " + this.uri);
/*     */     }
/* 290 */     Element digestElem = DOMUtils.getLastChildElement(this.refElem);
/* 291 */     if (digestElem == null) {
/* 292 */       throw new XMLSignatureException("DigestValue element expected");
/*     */     }
/* 294 */     DOMUtils.removeAllChildren(digestElem);
/* 295 */     digestElem.appendChild(this.refElem.getOwnerDocument().createTextNode(encodedDV));
/*     */ 
/* 298 */     Boolean cache = (Boolean)signContext.getProperty("javax.xml.dsig.cacheReference");
/*     */ 
/* 300 */     if ((cache != null) && (cache.booleanValue() == true)) {
/* 301 */       this.dis = new ByteArrayInputStream(digestInput);
/* 302 */       this.derefData = data;
/*     */     }
/* 304 */     this.digested = true;
/* 305 */     if (log.isLoggable(Level.FINE))
/* 306 */       log.log(Level.FINE, "Reference digesting completed");
/*     */   }
/*     */ 
/*     */   public boolean validate(XMLValidateContext validateContext)
/*     */     throws XMLSignatureException
/*     */   {
/* 312 */     if (validateContext == null) {
/* 313 */       throw new NullPointerException("validateContext cannot be null");
/*     */     }
/* 315 */     if (this.validated) {
/* 316 */       return this.validationStatus;
/*     */     }
/* 318 */     Data data = dereference(validateContext);
/* 319 */     byte[] digestInput = transform(data, validateContext);
/*     */ 
/* 321 */     this.calcDigestValue = digestInput;
/* 322 */     if (log.isLoggable(Level.FINE)) {
/* 323 */       log.log(Level.FINE, "Expected digest: " + Base64.encode(this.digestValue));
/*     */ 
/* 325 */       log.log(Level.FINE, "Actual digest: " + Base64.encode(this.calcDigestValue));
/*     */     }
/*     */ 
/* 329 */     this.validationStatus = Arrays.equals(this.digestValue, this.calcDigestValue);
/* 330 */     Boolean cache = (Boolean)validateContext.getProperty("javax.xml.dsig.cacheReference");
/*     */ 
/* 332 */     if ((cache != null) && (cache.booleanValue() == true)) {
/* 333 */       this.dis = new ByteArrayInputStream(digestInput);
/* 334 */       this.derefData = data;
/*     */     }
/* 336 */     this.validated = true;
/* 337 */     return this.validationStatus;
/*     */   }
/*     */ 
/*     */   public Data getDereferencedData() {
/* 341 */     return this.derefData;
/*     */   }
/*     */ 
/*     */   public InputStream getDigestInputStream() {
/* 345 */     return this.dis;
/*     */   }
/*     */ 
/*     */   private Data dereference(XMLCryptoContext context) throws XMLSignatureException
/*     */   {
/* 350 */     Data data = null;
/*     */ 
/* 353 */     URIDereferencer deref = context.getURIDereferencer();
/* 354 */     if (deref == null)
/* 355 */       deref = DOMURIDereferencer.INSTANCE;
/*     */     try
/*     */     {
/* 358 */       data = deref.dereference(this, context);
/* 359 */       if (log.isLoggable(Level.FINE)) {
/* 360 */         log.log(Level.FINE, "URIDereferencer class name: " + deref.getClass().getName());
/*     */ 
/* 362 */         log.log(Level.FINE, "Data class name: " + data.getClass().getName());
/*     */       }
/*     */     }
/*     */     catch (URIReferenceException ure) {
/* 366 */       throw new XMLSignatureException(ure);
/*     */     }
/*     */ 
/* 369 */     return data;
/*     */   }
/*     */ 
/*     */   private byte[] transform(Data dereferencedData, XMLCryptoContext context)
/*     */     throws XMLSignatureException
/*     */   {
/* 375 */     Data data = dereferencedData;
/*     */ 
/* 377 */     if (this.md == null) {
/*     */       try {
/* 379 */         this.md = MessageDigest.getInstance("SHA-1");
/*     */       } catch (NoSuchAlgorithmException nsae) {
/* 381 */         throw new XMLSignatureException(nsae);
/*     */       }
/*     */     }
/* 384 */     this.md.reset();
/* 385 */     DigesterOutputStream dos = new DigesterOutputStream(this.md);
/* 386 */     OutputStream os = new UnsyncBufferedOutputStream(dos);
/* 387 */     int i = 0; for (int size = this.transforms.size(); i < size; i++) {
/* 388 */       DOMTransform transform = (DOMTransform)this.transforms.get(i);
/*     */       try {
/* 390 */         if (i < size - 1)
/* 391 */           data = transform.transform(data, context);
/*     */         else
/* 393 */           data = transform.transform(data, context, os);
/*     */       }
/*     */       catch (TransformException te) {
/* 396 */         throw new XMLSignatureException(te);
/*     */       }
/*     */     }
/*     */     try
/*     */     {
/* 401 */       if (data != null)
/*     */       {
/*     */         XMLSignatureInput xi;
/* 403 */         if ((data instanceof ApacheData)) {
/* 404 */           xi = ((ApacheData)data).getXMLSignatureInput();
/*     */         }
/*     */         else
/*     */         {
/*     */           XMLSignatureInput xi;
/* 405 */           if ((data instanceof OctetStreamData)) {
/* 406 */             xi = new XMLSignatureInput(((OctetStreamData)data).getOctetStream());
/*     */           }
/*     */           else
/*     */           {
/*     */             XMLSignatureInput xi;
/* 408 */             if ((data instanceof NodeSetData)) {
/* 409 */               TransformService spi = TransformService.getInstance("http://www.w3.org/TR/2001/REC-xml-c14n-20010315", "DOM");
/*     */ 
/* 411 */               data = spi.transform(data, context);
/* 412 */               xi = new XMLSignatureInput(((OctetStreamData)data).getOctetStream());
/*     */             }
/*     */             else {
/* 415 */               throw new XMLSignatureException("unrecognized Data type");
/*     */             }
/*     */           }
/*     */         }
/*     */         XMLSignatureInput xi;
/* 417 */         xi.updateOutputStream(os);
/*     */       }
/* 419 */       os.flush();
/* 420 */       return dos.getDigestValue();
/*     */     } catch (Exception e) {
/* 422 */       throw new XMLSignatureException(e);
/*     */     }
/*     */   }
/*     */ 
/*     */   public Node getHere() {
/* 427 */     return this.here;
/*     */   }
/*     */ 
/*     */   public boolean equals(Object o) {
/* 431 */     if (this == o) {
/* 432 */       return true;
/*     */     }
/*     */ 
/* 435 */     if (!(o instanceof DOMURIReference)) {
/* 436 */       return false;
/*     */     }
/* 438 */     Reference oref = (DOMURIReference)o;
/*     */ 
/* 440 */     boolean idsEqual = this.id == null ? false : oref.getId() == null ? true : this.id.equals(oref.getId());
/*     */ 
/* 442 */     boolean urisEqual = this.uri == null ? false : oref.getURI() == null ? true : this.uri.equals(oref.getURI());
/*     */ 
/* 444 */     boolean typesEqual = this.type == null ? false : oref.getType() == null ? true : this.type.equals(oref.getType());
/*     */ 
/* 446 */     boolean digestValuesEqual = Arrays.equals(this.digestValue, oref.getDigestValue());
/*     */ 
/* 449 */     return (this.digestMethod.equals(oref.getDigestMethod())) && (idsEqual) && (urisEqual) && (typesEqual) && (this.transforms.equals(oref.getTransforms()));
/*     */   }
/*     */ 
/*     */   boolean isDigested()
/*     */   {
/* 454 */     return this.digested;
/*     */   }
/*     */ }

/* Location:           E:\HYN\Java\trunk\ref\lib-dep\xmldsig\xmldsig.jar
 * Qualified Name:     org.jcp.xml.dsig.internal.dom.DOMReference
 * JD-Core Version:    0.6.2
 */




© 2015 - 2024 Weber Informatics LLC | Privacy Policy