/// <summary> /// Create signature properties from existing document /// </summary> /// <param name="element"></param> /// <param name="nsm"></param> internal XadesSignatureProperties(XmlElement element, XmlNamespaceManager nsm) { // read from xml XmlElement signedSignatureProperties = element["SignedSignatureProperties", Xades.XadesNamespaceUrl]; // signing time if (DateTime.TryParse(signedSignatureProperties?["SigningTime", Xades.XadesNamespaceUrl]?.InnerText, out DateTime signingTime)) { SigningTime = signingTime; } // signing certificate; currently only one certificate supported //foreach (XmlElement cert in element.SelectNodes("xades:SignedSignatureProperties/xades:SigningCertificate/xades:Cert", nsm)) //{ // TODO: read certificate information and expose as public read-only array //} // signature policy XmlElement signaturePolicyIdentifier = signedSignatureProperties["SignaturePolicyIdentifier", Xades.XadesNamespaceUrl]; XmlElement signaturePolicyImplied = signaturePolicyIdentifier?["SignaturePolicyImplied", Xades.XadesNamespaceUrl]; XmlElement signaturePolicyId = signaturePolicyIdentifier?["SignaturePolicyId", Xades.XadesNamespaceUrl]; if (signaturePolicyImplied != null) { PolicyImplied = true; } else if (signaturePolicyId != null) { PolicyId = ObjectIdentifier.TryParseFromParent(signaturePolicyId, "SigPolicyId", Xades.XadesNamespaceUrl); XmlElement transformChain = signaturePolicyId.SelectSingleNode("ds:Transforms", nsm) as XmlElement; if (transformChain != null) { PolicyTransformChain = new TransformChain(); MethodInfo loadXmlInfo = typeof(TransformChain).GetMethod("LoadXml", BindingFlags.NonPublic | BindingFlags.Instance); loadXmlInfo.Invoke(PolicyTransformChain, new object[] { transformChain }); } DigestAlgAndValue digestInfo = DigestAlgAndValue.TryParse(signaturePolicyId["SigPolicyHash", Xades.XadesNamespaceUrl]); PolicyDigestMethod = digestInfo.Algorithm; PolicyDigest = digestInfo.Digest; XmlElement signaturePolicyQualifiers = signaturePolicyIdentifier["SigPolicyQualifiers", Xades.XadesNamespaceUrl]; if (signaturePolicyQualifiers != null) { PolicyURIs = signaturePolicyQualifiers.SelectNodes("xades:SigPolicyQualifier/xades:SPURI", nsm).OfType <XmlElement>().Select(x => x.InnerText).ToList(); //PolicyNotices = signaturePolicyQualifiers.SelectNodes("xades:SigPolicyQualifier/xades:SPUserNotice", nsm).OfType<XmlElement>().Select(x => new PolicyUserNotice(x)).ToList(); } } }
public static DigestAlgAndValue TryParse(XmlElement element) { if (element == null) { return(null); } DigestAlgAndValue result = new DigestAlgAndValue(); result.Algorithm = element["DigestMethod", SignedXml.XmlDsigNamespaceUrl]?.GetAttribute("Algorithm"); string hash = element["DigestValue", SignedXml.XmlDsigNamespaceUrl]?.Value; if (hash != null) { result.Digest = Convert.FromBase64String(hash); } return(result); }
/// <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); }