private byte[] CalculateHash(Reference reference, UriResolverDelegate resolver) { if (reference.Uri == null || reference.Uri.Length == 0 || reference.Uri[0] == '#') { return((byte[])_calculateHashValue.Invoke(reference, new object[] { _document, null })); } try { Stream stream; if (resolver != null) { stream = resolver(Uri.UnescapeDataString(reference.Uri)); } else { using (WebClient wc = new WebClient()) stream = wc.OpenRead(reference.Uri); } return(XadesUtils.CalculateHash(stream, reference.TransformChain, reference.DigestMethod)); } catch (Exception) { return(new byte[0]); } }
/// <summary> /// Check signature policy hash /// </summary> /// <param name="stream"></param> /// <returns></returns>` public bool CheckPolicyHash(Stream stream) { byte[] digest = XadesUtils.CalculateHash(stream, PolicyTransformChain, PolicyDigestMethod); return(digest.SequenceEqual(PolicyDigest)); }
/// <summary> /// Create <SignedSignatureProperties> /// </summary> /// <param name="document"></param> /// <returns></returns> internal XmlElement CreateXadesSignatureProperties(XmlDocument document, X509Certificate2 certificate, SignatureType xadesVersion) { XmlElement signatureProperties = document.CreateElement("SignedSignatureProperties", Xades.XadesNamespaceUrl); // signing time; required for 1.1.1 if (SigningTime.HasValue || xadesVersion < SignatureType.Xades132) { signatureProperties.CreateChild("SigningTime", Xades.XadesNamespaceUrl, (SigningTime ?? DateTime.Now).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")); } // signing certificate; can be omitted >= 1.3.2 if (IncludeSigningCertificate || xadesVersion < SignatureType.Xades132) { XmlElement signingCertificate = signatureProperties.CreateChild("SigningCertificate", Xades.XadesNamespaceUrl); XmlElement signingCert = signingCertificate.CreateChild("Cert", Xades.XadesNamespaceUrl); // certificate digest HashAlgorithm hashAlg = CryptoConfig.CreateFromName(CertificateDigest) as HashAlgorithm; if (hashAlg == null) { throw new CryptographicException("Invalid digest method"); } DigestAlgAndValue certDigest = new DigestAlgAndValue() { Algorithm = CertificateDigest, Digest = hashAlg.ComputeHash(certificate.RawData) }; signingCert.AppendChild(certDigest.CreateXml(signingCert, "CertDigest", Xades.XadesNamespaceUrl)); // certificate issuer XmlElement issuerSerial = signingCert.CreateChild("IssuerSerial", Xades.XadesNamespaceUrl); issuerSerial.CreateChild("X509IssuerName", SignedXml.XmlDsigNamespaceUrl, certificate.Issuer); issuerSerial.CreateChild("X509SerialNumber", SignedXml.XmlDsigNamespaceUrl, XadesUtils.ToDecimal(XadesUtils.HexToBytes(certificate.SerialNumber))); } // signature policy; can be omitted >= 1.3.2 XmlElement sigPolicyId = PolicyId?.GetObjectIdentifier(document, "SigPolicyId", Xades.XadesNamespaceUrl); if (PolicyImplied || xadesVersion < SignatureType.Xades132 || sigPolicyId != null) { XmlElement signaturePolicyIdentifier = signatureProperties.CreateChild("SignaturePolicyIdentifier", Xades.XadesNamespaceUrl); // policy implied if specified (or policyid not specified) if (PolicyImplied || sigPolicyId == null) { signaturePolicyIdentifier.CreateChild("SignaturePolicyImplied", Xades.XadesNamespaceUrl); } else if (sigPolicyId != null) { XmlElement signaturePolicyId = signaturePolicyIdentifier.CreateChild("SignaturePolicyId", Xades.XadesNamespaceUrl); signaturePolicyId.AppendChild(sigPolicyId); if (PolicyTransformChain != null && PolicyTransformChain.Count > 0) { MethodInfo getXmlInfo = typeof(TransformChain).GetMethod("GetXml", BindingFlags.NonPublic | BindingFlags.Instance); signaturePolicyId.AppendChild((XmlElement)getXmlInfo.Invoke(PolicyTransformChain, new object[] { document, SignedXml.XmlDsigNamespaceUrl })); } if (PolicyDigest == null) { CalculatePolicyHash(PolicyURIs.FirstOrDefault() ?? PolicyId.Identifier); } DigestAlgAndValue policyHash = new DigestAlgAndValue() { Algorithm = PolicyDigestMethod, Digest = PolicyDigest }; policyHash.CreateXml(signaturePolicyId, "SigPolicyHash", Xades.XadesNamespaceUrl); XmlElement sigPolicyQualifiers = document.CreateElement("SigPolicyQualifiers", Xades.XadesNamespaceUrl); if (PolicyURIs != null && PolicyURIs.Count > 0) { foreach (string uri in PolicyURIs) { sigPolicyQualifiers.CreateChild("SigPolicyQualifier", Xades.XadesNamespaceUrl).CreateChild("SPURI", Xades.XadesNamespaceUrl, uri); } } if (PolicyNotices != null && PolicyNotices.Count > 0) { foreach (PolicyUserNotice notice in PolicyNotices) { notice.CreateXml(sigPolicyQualifiers.CreateChild("SigPolicyQualifier", Xades.XadesNamespaceUrl)); } } if (sigPolicyQualifiers.ChildNodes.Count > 0) { signaturePolicyId.AppendChild(sigPolicyQualifiers); } } } return(signatureProperties); }
/// <summary> /// Update hash value from stream /// </summary> /// <param name="stream"></param> public void CalculatePolicyHash(Stream stream) { PolicyDigest = XadesUtils.CalculateHash(stream, PolicyTransformChain, PolicyDigestMethod); }