title: OpenSAML (2.0) EntitiesDescriptor signature validation not working
body: <p>I have no clue how to log a bug to the Shibboleth project, so I'll write some findings I've come across with OpenSAML signature validation. There is an issue related to the way OpenSAML (2.0) attempts to validate signatures in SAML metadata (EntitiesDescriptor).</p>
  
  <p>I was trying to desperately validate the signature in my SAML metadata structure with FilesystemMetadataProvider, however it throws me NullPointerException always. There are some other articles about this issue elsewhere, but nobody seemed to know about the exact reason for it.</p>
  
  <p>Now what I first tried was something like this:</p>
  
  <pre><code>FilesystemMetadataProvider provider = new FilesystemMetadataProvider(new File("metadata.xml"));
  provider.setRequireValidMetadata(true);
  provider.setParserPool(new BasicParserPool());
  provider.initialize();
  EntitiesDescriptor ed = provider.getEntitiesDescriptor("My Servers");
  SignatureValidator validator = new SignatureValidator(getTrustedCredential());
  validator.validate(ed.getSignature());
  </code></pre>
  
  <p>This constantly ends up throwing an exception:</p>
  
  <p>java.lang.NullPointerException at org.opensaml.xml.signature.SignatureValidator.validate(SignatureValidator.java:69)</p>
  
  <p>After some debugging around XMLTooling and OpenSAML classes, I found a reason for the error. The problem seems to be in the way the XMLSignature is handled in org.opensaml.xml.signature.impl.SignatureImpl class:</p>
  
  <pre><code>public void releaseDOM() {
    super.releaseDOM();
    **this.xmlSignature = null;**
    if (this.keyInfo != null) {
      this.keyInfo.releaseChildrenDOM(true);
      this.keyInfo.releaseDOM();
    }
  }
  
  public XMLSignature getXMLSignature() {
    return this.xmlSignature;
  }
  
  public void setXMLSignature(XMLSignature signature) {
    this.xmlSignature = ((XMLSignature)prepareForAssignment(this.xmlSignature, signature));
  }
  </code></pre>
  
  <p>Now the SignatureValidator runs these methods in order setXMLSignature() --> releaseDOM() --> getXMLSignature() which fails to validate EntitiesDescriptor. However, with other signature types this seems to work okay.</p>
  
  <p>As a workaround there were two ways I managed to validate the signature:</p>
  
  <p>1) Reverse engineering the SignatureImpl class and removing "this.xmlSignature = null;" from releaseDOM() method</p>
  
  <p>2) Reimplementing signature validation using XML parsing and unmarshalling (shown below)</p>
  
  <pre><code>File file = new File("metadata.xml");
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  dbf.setNamespaceAware(true);
  DocumentBuilder db = dbf.newDocumentBuilder();
  Document document = db.parse(file);
  UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
  Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(document.getDocumentElement());
  EntitiesDescriptor ed = (EntitiesDescriptor) unmarshaller.unmarshall(document.getDocumentElement());
  SignatureValidator validator = new SignatureValidator(getTrustedCredential());
  validator.validate(ed.getSignature());
  </code></pre>
  
  <p>Anybody else seen this problem?</p>