protected virtual X509Certificate2 VerifySignature(XElement xml)
{
Contract.Requires(xml != null);
Contract.Ensures(Contract.Result<X509Certificate2>() != null);
if ((Configuration == null) || (Configuration.IssuerTokenResolver == null))
{
throw new SecurityTokenException("No issuer token resolver configured");
}
var xmlElement = xml.ToXmlElement();
var signedXml = new SignedXml(xmlElement);
// find signature
XmlNodeList nodeList = xmlElement.GetElementsByTagName("Signature");
// throw an exception if no signature was found.
if (nodeList.Count <= 0)
{
throw new CryptographicException("Verification failed: No Signature was found in the document.");
}
// throw an exception if more than one signature was found.
if (nodeList.Count > 1)
{
throw new CryptographicException("Verification failed: More that one signature was found for the document.");
}
// load the <signature> node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// resolve the issuer certificate
byte[] thumbprint = Convert.FromBase64String(GetIssuerThumbprint(signedXml));
var identifier = new X509ThumbprintKeyIdentifierClause(thumbprint);
var issuerKey = Configuration.IssuerTokenResolver.ResolveToken(identifier) as X509SecurityToken;
// check the signature
var referenceUri = ((Reference)signedXml.SignedInfo.References[0]).Uri;
if (!signedXml.CheckSignature(issuerKey.Certificate, true)
|| (referenceUri != "" && signedXml.GetIdElement(xmlElement.OwnerDocument, referenceUri) != xmlElement))
{
throw new CryptographicException("Signature verification failed");
}
if (issuerKey.Certificate != null)
{
return issuerKey.Certificate;
}
else
{
throw new CryptographicException("No issuer certificate found");
}
}