1 59 package org.apache.xml.security.signature; 60 61 62 import java.io.*; 63 import java.math.BigInteger ; 64 import java.util.*; 65 import javax.xml.parsers.DocumentBuilder ; 66 import javax.xml.parsers.DocumentBuilderFactory ; 67 import javax.xml.parsers.ParserConfigurationException ; 68 import javax.xml.transform.TransformerException ; 69 70 import org.w3c.dom.*; 71 import org.w3c.dom.traversal.NodeIterator; 72 import org.xml.sax.InputSource ; 73 import org.xml.sax.SAXException ; 74 75 import org.apache.xml.serialize.OutputFormat; 76 import org.apache.xml.serialize.Serializer; 77 import org.apache.xml.serialize.SerializerFactory; 78 import org.apache.xml.serialize.XMLSerializer; 79 import org.apache.xml.utils.PrefixResolverDefault; 80 import org.apache.xpath.NodeSet; 81 import org.apache.xpath.objects.XObject; 82 import org.apache.xpath.XPath; 83 import org.apache.xpath.XPathAPI; 84 import org.apache.xpath.XPathContext; 85 86 import org.apache.xml.security.algorithms.MessageDigestAlgorithm; 87 import org.apache.xml.security.c14n.*; 88 import org.apache.xml.security.exceptions.*; 89 import org.apache.xml.security.signature.*; 90 import org.apache.xml.security.transforms.*; 91 import org.apache.xml.security.transforms.params.XPathContainer; 92 import org.apache.xml.security.utils.*; 93 import org.apache.xml.security.utils.resolver.*; 94 95 96 97 143 public class Reference extends SignatureElementProxy { 144 145 public static boolean CacheSignedNodes = false; 146 147 148 static org.apache.log4j.Category cat = 149 org.apache.log4j.Category.getInstance(Reference.class.getName()); 150 151 152 public static final String OBJECT_URI = Constants.SignatureSpecNS 153 + Constants._TAG_OBJECT; 154 155 156 public static final String MANIFEST_URI = Constants.SignatureSpecNS 157 + Constants._TAG_MANIFEST; 158 Manifest _manifest = null; 160 XMLSignatureInput _transformsInput; 161 XMLSignatureInput _transformsOutput; 162 164 176 protected Reference( 177 Document doc, String BaseURI, String ReferenceURI, Manifest manifest, Transforms transforms, String messageDigestAlgorithm) 178 throws XMLSignatureException { 179 180 super(doc); 181 182 XMLUtils.addReturnToElement(this._constructionElement); 183 184 this._baseURI = BaseURI; 185 this._manifest = manifest; 186 187 this.setURI(ReferenceURI); 188 189 Element nscontext = XMLUtils.createDSctx(this._doc, "ds"); 194 195 if (transforms != null) { 196 this._constructionElement.appendChild(transforms.getElement()); 197 XMLUtils.addReturnToElement(this._constructionElement); 198 } 199 { 200 MessageDigestAlgorithm mda = 201 MessageDigestAlgorithm.getInstance(this._doc, 202 messageDigestAlgorithm); 203 204 this._constructionElement.appendChild(mda.getElement()); 205 XMLUtils.addReturnToElement(this._constructionElement); 206 } 207 { 208 Element digestValueElement = 209 XMLUtils.createElementInSignatureSpace(this._doc, 210 Constants._TAG_DIGESTVALUE); 211 212 this._constructionElement.appendChild(digestValueElement); 213 XMLUtils.addReturnToElement(this._constructionElement); 214 } 215 } 216 217 227 protected Reference( 228 Document doc, String BaseURI, String ReferenceURI, Manifest manifest, String messageDigestAlgorithm) 229 throws XMLSignatureException { 230 this(doc, BaseURI, ReferenceURI, manifest, (Transforms) null, 231 messageDigestAlgorithm); 232 } 233 234 244 protected Reference( 245 Document doc, String BaseURI, String ReferenceURI, Manifest manifest, Transforms transforms) 246 throws XMLSignatureException { 247 this(doc, BaseURI, ReferenceURI, manifest, transforms, 248 Constants.ALGO_ID_DIGEST_SHA1); 249 } 250 251 260 protected Reference( 261 Document doc, String BaseURI, String ReferenceURI, Manifest manifest) 262 throws XMLSignatureException { 263 this(doc, BaseURI, ReferenceURI, manifest, (Transforms) null, 264 Constants.ALGO_ID_DIGEST_SHA1); 265 } 266 267 275 protected Reference(Element element, String BaseURI, Manifest manifest) 276 throws XMLSecurityException { 277 278 super(element, BaseURI); 279 280 this._manifest = manifest; 281 } 282 283 291 public MessageDigestAlgorithm getMessageDigestAlgorithm() 292 throws XMLSignatureException { 293 294 Element digestMethodElem = this.getChildElementLocalName(0, 295 Constants.SignatureSpecNS, 296 Constants._TAG_DIGESTMETHOD); 297 298 if (digestMethodElem == null) { 299 return null; 300 } 301 302 String uri = digestMethodElem.getAttributeNS(null, Constants._ATT_ALGORITHM); 303 304 return MessageDigestAlgorithm.getInstance(this._doc, uri); 305 } 306 307 312 public void setURI(String URI) { 313 314 if ((this._state == MODE_SIGN) && (URI != null)) { 315 this._constructionElement.setAttributeNS(null, Constants._ATT_URI, URI); 316 } 317 } 318 319 324 public String getURI() { 325 return this._constructionElement.getAttributeNS(null, Constants._ATT_URI); 326 } 327 328 333 public void setId(String Id) { 334 335 if ((this._state == MODE_SIGN) && (Id != null)) { 336 this._constructionElement.setAttributeNS(null, Constants._ATT_ID, Id); 337 IdResolver.registerElementById(this._constructionElement, Id); 338 } 339 } 340 341 346 public String getId() { 347 return this._constructionElement.getAttributeNS(null, Constants._ATT_ID); 348 } 349 350 355 public void setType(String Type) { 356 357 if ((this._state == MODE_SIGN) && (Type != null)) { 358 this._constructionElement.setAttributeNS(null, Constants._ATT_TYPE, Type); 359 } 360 } 361 362 367 public String getType() { 368 return this._constructionElement.getAttributeNS(null, Constants._ATT_TYPE); 369 } 370 371 379 public boolean typeIsReferenceToObject() { 380 381 if ((this.getType() != null) 382 && this.getType().equals(Reference.OBJECT_URI)) { 383 return true; 384 } 385 386 return false; 387 } 388 389 397 public boolean typeIsReferenceToManifest() { 398 399 if ((this.getType() != null) 400 && this.getType().equals(Reference.MANIFEST_URI)) { 401 return true; 402 } 403 404 return false; 405 } 406 407 413 private void setDigestValueElement(byte[] digestValue) 414 throws XMLSignatureException { 415 416 if (this._state == MODE_SIGN) { 417 Element digestValueElement = this.getChildElementLocalName(0, 418 Constants.SignatureSpecNS, 419 Constants._TAG_DIGESTVALUE); 420 NodeList children = digestValueElement.getChildNodes(); 421 422 for (int i = 0; i < children.getLength(); i++) { 423 digestValueElement.removeChild(children.item(i)); 424 } 425 426 String base64codedValue = Base64.encode(digestValue); 427 Text t = this._doc.createTextNode(base64codedValue); 428 429 digestValueElement.appendChild(t); 430 } 431 } 432 433 439 public void generateDigestValue() 440 throws XMLSignatureException, ReferenceNotInitializedException { 441 442 if (this._state == MODE_SIGN) { 443 byte calculatedBytes[] = this.calculateDigest(); 444 445 this.setDigestValueElement(calculatedBytes); 446 } 447 } 448 449 457 protected void dereferenceURIandPerformTransforms() 458 throws ReferenceNotInitializedException, XMLSignatureException { 459 460 try { 461 Attr URIAttr = 462 this._constructionElement.getAttributeNodeNS(null, Constants._ATT_URI); 463 String URI; 464 465 if (URIAttr == null) { 466 URI = null; 467 } else { 468 URI = URIAttr.getNodeValue(); 469 } 470 471 ResourceResolver resolver = ResourceResolver.getInstance(URIAttr, 472 this._baseURI, 473 this._manifest._perManifestResolvers); 474 475 if (resolver == null) { 476 Object exArgs[] = { URI }; 477 478 throw new ReferenceNotInitializedException( 479 "signature.Verification.Reference.NoInput", exArgs); 480 } 481 482 resolver.addProperties(this._manifest._resolverProperties); 483 484 this._transformsInput = resolver.resolve(URIAttr, this._baseURI); 485 486 Transforms transforms = this.getTransforms(); 487 488 if (transforms != null) { 489 this._transformsOutput = 490 transforms.performTransforms(this._transformsInput); 491 } else { 492 this._transformsOutput = this._transformsInput; 493 } 494 495 500 if (!Reference.CacheSignedNodes) { 501 this._transformsInput = new XMLSignatureInput(this._transformsInput.getBytes()); 502 this._transformsOutput = new XMLSignatureInput(this._transformsOutput.getBytes()); 503 } 504 } catch (IOException ex) { 505 throw new ReferenceNotInitializedException("empty", ex); 506 } catch (ResourceResolverException ex) { 507 throw new ReferenceNotInitializedException("empty", ex); 508 } catch (CanonicalizationException ex) { 509 throw new ReferenceNotInitializedException("empty", ex); 510 } catch (InvalidCanonicalizerException ex) { 511 throw new ReferenceNotInitializedException("empty", ex); 512 } catch (TransformationException ex) { 513 throw new ReferenceNotInitializedException("empty", ex); 514 } catch (XMLSecurityException ex) { 515 throw new ReferenceNotInitializedException("empty", ex); 516 } 517 } 518 519 528 public Transforms getTransforms() 529 throws XMLSignatureException, InvalidTransformException, 530 TransformationException, XMLSecurityException { 531 532 Element transformsElement = this.getChildElementLocalName(0, 533 Constants.SignatureSpecNS, 534 Constants._TAG_TRANSFORMS); 535 536 if (transformsElement != null) { 537 Transforms transforms = new Transforms(transformsElement, 538 this._baseURI); 539 540 return transforms; 541 } else { 542 return null; 543 } 544 } 545 546 553 public byte[] getReferencedBytes() 554 throws ReferenceNotInitializedException, XMLSignatureException { 555 556 try { 557 this.dereferenceURIandPerformTransforms(); 558 559 byte[] signedBytes = this.getTransformsOutput().getBytes(); 560 561 return signedBytes; 562 } catch (IOException ex) { 563 throw new ReferenceNotInitializedException("empty", ex); 564 } catch (CanonicalizationException ex) { 565 throw new ReferenceNotInitializedException("empty", ex); 566 } catch (InvalidCanonicalizerException ex) { 567 throw new ReferenceNotInitializedException("empty", ex); 568 } 569 } 570 571 578 private byte[] calculateDigest() 579 throws ReferenceNotInitializedException, XMLSignatureException { 580 581 try { 582 byte[] data = this.getReferencedBytes(); 583 MessageDigestAlgorithm mda = this.getMessageDigestAlgorithm(); 584 585 mda.reset(); 586 mda.update(data); 587 588 byte calculatedDigestValue[] = mda.digest(); 589 590 if (data.length < 20) { 592 cat.debug(new String (data)); 593 } else { 594 cat.debug(new String (data).substring(0, 20) + " ..."); 595 } 596 return calculatedDigestValue; 598 } catch (XMLSecurityException ex) { 599 throw new ReferenceNotInitializedException("empty", ex); 600 } 601 } 602 603 610 public boolean verify() 611 throws ReferenceNotInitializedException, XMLSecurityException { 612 613 Element digestValueElem = this.getChildElementLocalName(0, 614 Constants.SignatureSpecNS, 615 Constants._TAG_DIGESTVALUE); 616 byte[] elemDig = Base64.decode(digestValueElem); 617 byte[] calcDig = this.calculateDigest(); 618 boolean equal = MessageDigestAlgorithm.isEqual(elemDig, calcDig); 619 620 if (!equal) { 621 cat.warn("Verification failed for URI \"" + this.getURI() + "\""); 622 623 if (cat.isDebugEnabled()) { 624 cat.debug("unverifiedDigestValue= " + Base64.encode(elemDig)); 625 cat.debug("calculatedDigestValue= " + Base64.encode(calcDig)); 626 627 636 } 637 } else { 638 cat.info("Verification successful for URI \"" + this.getURI() + "\""); 639 } 640 641 return equal; 642 } 643 644 649 public XMLSignatureInput getTransformsInput() { 650 return this._transformsInput; 651 } 652 653 658 public XMLSignatureInput getTransformsOutput() { 659 return this._transformsOutput; 660 } 661 662 667 public String getBaseLocalName() { 668 return Constants._TAG_REFERENCE; 669 } 670 } 671 | Popular Tags |