/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package de.christofreichardt.jaxws.securitypriceservice;

import de.christofreichardt.diagnosis.AbstractTracer;
import de.christofreichardt.diagnosis.Traceable;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import org.w3c.dom.Node;

/**
 *
 * @author Christof Reichardt
 */
abstract public class XMLDigitalSignature implements Traceable {
  private final Node signature;

  public XMLDigitalSignature(Node signature) {
    this.signature = signature;
  }

  public boolean verify(PublicKey publicKey) throws NoSuchProviderException, MarshalException, XMLSignatureException {
    AbstractTracer tracer = getCurrentTracer();
    tracer.entry("boolean", this, "verify(PublicKey publicKey)");
    
    try {
      XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance("DOM", "XMLDSig");
      DOMValidateContext domValidateContext = new DOMValidateContext(publicKey, this.signature);
      domValidateContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
      domValidateContext.setURIDereferencer(getSoapBodyDereferencer());
      XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext);
      boolean validated = xmlSignature.validate(domValidateContext);
      
      return validated;
    }
    finally {
      tracer.wayout();
    }
  }
  
  abstract public AbstractSoapBodyDereferencer getSoapBodyDereferencer();
}
