private Xades(XmlElement element) { _document = element.OwnerDocument; _signedXml = new XadesSignedXml(_document); _signedXml.LoadXml(element); CanonicalizationMethod = _signedXml.SignedInfo.CanonicalizationMethod; SignatureMethod = _signedXml.SignedInfo.SignatureMethod; XmlNamespaceManager nsm = new XmlNamespaceManager(new NameTable()); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); nsm.AddNamespace("xades", XadesNamespaceUrl); // find the xades reference _referenceIndex = new Dictionary <Reference, XadesReference>(); References = new List <XadesReference>(); foreach (Reference reference in _signedXml.SignedInfo.References) { if (reference.Type == Xades.XadesReferenceType && reference.Uri[0] == '#') { XmlElement signedProperties = element.SelectSingleNode($"//xades:SignedProperties[@Id='{reference.Uri.Substring(1)}']", nsm) as XmlElement; if (signedProperties != null) { _signedProperties = signedProperties; _referenceIndex[reference] = null; continue; } } // external reference XadesReference xadesReference = new XadesReference(reference); _referenceIndex[reference] = xadesReference; References.Add(xadesReference); } if (_signedProperties == null) { return; } // parse signature policy SignatureProperties = new XadesSignatureProperties(_signedProperties, nsm); // create xades files foreach (XadesReference item in References) { item.ParseProperties(_signedProperties, nsm); } }
/// <summary> /// Check Xades signature; SignedXml.CheckSignature would do all the work, but does not provide detailed feedback /// </summary> /// <param name="certificate"></param> /// <param name="resolver"></param> /// <returns></returns> public bool CheckSignature(out X509Certificate2 certificate, UriResolverDelegate resolver = null) { certificate = null; if (_signedXml == null) { return(false); } // find appropriate public key and verify signature bool ValidSignedInfo = false; foreach (KeyValuePair <AsymmetricAlgorithm, X509Certificate2> algInfo in GetPublicKeys(_signedXml.KeyInfo)) { if (_checkSignedInfo(_signedXml, algInfo.Key)) { ValidSignedInfo = true; certificate = algInfo.Value; break; } } // verify reference hashes bool validReferences = true; bool ValidSignedProperties = false; foreach (Reference reference in _signedXml.SignedInfo.References) { byte[] digest = CalculateHash(reference, resolver); bool validReference = reference.DigestValue.SequenceEqual(digest); // store result XadesReference xadesReference = _referenceIndex[reference]; if (xadesReference == null) { ValidSignedProperties = validReference; } else { xadesReference.IsValid = validReference; } validReferences = validReference && validReferences; } return(ValidSignedInfo && validReferences && ValidSignedProperties); }