コード例 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="X509CertificateCredentials"/> class.
        /// </summary>
        /// <remarks>The X509Certificate2 argument should have private key in order to sign the message.</remarks>
        /// <param name="certificate">The X509Certificate2 object.</param>
        public X509CertificateCredentials(X509Certificate2 certificate)
            : base(null, true)
        {
            EwsUtilities.ValidateParam(certificate, "certificate");

            if (!certificate.HasPrivateKey)
            {
                throw new ServiceValidationException(Strings.CertificateHasNoPrivateKey);
            }

            this.certificate = certificate;

            string certId = WSSecurityUtilityIdSignedXml.GetUniqueId();

            this.SecurityToken = string.Format(
                X509CertificateCredentials.BinarySecurityTokenFormat,
                certId,
                Convert.ToBase64String(this.certificate.GetRawCertData()));

            SafeXmlDocument doc = new SafeXmlDocument();

            doc.PreserveWhitespace = true;
            doc.LoadXml(string.Format(X509CertificateCredentials.KeyInfoClauseFormat, certId));
            this.keyInfoClause = new KeyInfoNode(doc.DocumentElement);
        }
コード例 #2
0
        private static AsymmetricAlgorithm GetTrustedSigner(KeyInfoClause clause, IdentityProvider identityProvider)
        {
            // Check certificate specifications
            if (clause is KeyInfoX509Data)
            {
                var cert = XmlSignatureUtils.GetCertificateFromKeyInfo((KeyInfoX509Data)clause);

                if (!CertificateSatisfiesSpecifications(identityProvider, cert))
                {
                    return(null);
                }
            }

            return(XmlSignatureUtils.ExtractKey(clause));
        }
コード例 #3
0
        /// <summary>
        /// Attempts to retrieve an asymmetric key from the KeyInfoClause given as parameter.
        /// </summary>
        /// <param name="keyInfoClause"></param>
        /// <returns>null if the key could not be found.</returns>
        public static AsymmetricAlgorithm ExtractKey(KeyInfoClause keyInfoClause)
        {
            if (keyInfoClause is RSAKeyValue)
            {
                RSAKeyValue key = (RSAKeyValue)keyInfoClause;
                return(key.Key);
            }
            else if (keyInfoClause is KeyInfoX509Data)
            {
                X509Certificate2 cert = GetCertificateFromKeyInfo((KeyInfoX509Data)keyInfoClause);

                return(cert != null ? cert.PublicKey.Key : null);
            }

            return(null);
        }
コード例 #4
0
        /**
         * Signs the xml with XAdES BES using the enveloped mode, with optional xpath transform (see XmlSignatureAppearance).
         * @param sap the XmlSignatureAppearance
         * @param externalSignature  the interface providing the actual signing
         * @param chain the certificate chain
         * @param includeSignaturePolicy if true SignaturePolicyIdentifier will be included (XAdES-EPES)
         * @throws GeneralSecurityException
         * @throws IOException
         * @throws DocumentException
         */
        public static void SignXades(XmlSignatureAppearance sap, IExternalSignature externalSignature, X509Certificate[] chain,
                                     bool includeSignaturePolicy)
        {
            VerifyArguments(sap, externalSignature);
            String contentReferenceId = SecurityConstants.Reference_ + GetRandomId();
            String signedPropertiesId = SecurityConstants.SignedProperties_ + GetRandomId();
            String signatureId        = SecurityConstants.Signature_ + GetRandomId();

            XmlDocument doc = sap.GetXmlLocator().GetDocument();

            doc.XmlResolver = null;
            KeyInfoClause     keyInfo    = GenerateKeyInfo(chain, sap);
            List <XmlElement> references = new List <XmlElement>(2);

            XmlElement signature = GenerateSignatureElement(sap.GetXmlLocator(), signatureId, true);

            String[] signaturePolicy = null;
            if (includeSignaturePolicy)
            {
                signaturePolicy = new String[2];
                if (externalSignature.GetEncryptionAlgorithm().Equals(SecurityConstants.RSA))
                {
                    signaturePolicy[0] = SecurityConstants.OID_RSA_SHA1;
                    signaturePolicy[1] = SecurityConstants.OID_RSA_SHA1_DESC;
                }
                else
                {
                    signaturePolicy[0] = SecurityConstants.OID_DSA_SHA1;
                    signaturePolicy[1] = SecurityConstants.OID_DSA_SHA1_DESC;
                }
            }

            XmlElement signedProperty;
            XmlElement dsObject = GenerateXadesObject(sap, signatureId, contentReferenceId, signedPropertiesId, signaturePolicy, out signedProperty);

            references.Add(GenerateCustomReference(doc, signedProperty, "#" + signedPropertiesId, SecurityConstants.SignedProperties_Type, null));
            references.Add(GenerateContentReference(doc, sap, contentReferenceId));

            Sign(signature, sap.GetXmlLocator(), externalSignature, references, dsObject, keyInfo);

            sap.Close();
        }
コード例 #5
0
        /**
         * Signs the xml with XAdES BES using the enveloped mode, with optional xpath transform (see XmlSignatureAppearance).
         * @param sap the XmlSignatureAppearance
         * @param externalSignature  the interface providing the actual signing
         * @param chain the certificate chain
         * @throws GeneralSecurityException
         * @throws IOException
         * @throws DocumentException
         */
        public static void SignXadesBes(XmlSignatureAppearance sap, IExternalSignature externalSignature, X509Certificate[] chain)
        {
            VerifyArguments(sap, externalSignature);
            String contentReferenceId = SecurityConstants.Reference_ + GetRandomId();
            String signedPropertiesId = SecurityConstants.SignedProperties_ + GetRandomId();
            String signatureId        = SecurityConstants.Signature_ + GetRandomId();

            XmlDocument       doc        = sap.GetXmlLocator().GetDocument();
            KeyInfoClause     keyInfo    = GenerateKeyInfo(chain, sap);
            List <XmlElement> references = new List <XmlElement>(2);

            XmlElement signature = GenerateSignatureElement(sap.GetXmlLocator(), signatureId, true);
            XmlElement signedProperty;
            XmlElement dsObject = GenerateXadesBesObject(sap, signatureId, contentReferenceId, signedPropertiesId, out signedProperty);

            references.Add(GenerateCustomReference(doc, signedProperty, "#" + signedPropertiesId, SecurityConstants.SignedProperties_Type, null));
            references.Add(GenerateContentReference(doc, sap, contentReferenceId));

            Sign(signature, sap.GetXmlLocator(), externalSignature, references, dsObject, keyInfo);

            sap.Close();
        }
コード例 #6
0
ファイル: XmlSignatureUtils.cs プロジェクト: shawnspeak/SAML2
        /// <summary>
        /// Attempts to retrieve an asymmetric key from the KeyInfoClause given as parameter.
        /// </summary>
        /// <param name="keyInfoClause">The key info clause.</param>
        /// <returns>null if the key could not be found.</returns>
        public static AsymmetricAlgorithm ExtractKey(KeyInfoClause keyInfoClause)
        {
            if (keyInfoClause is RSAKeyValue)
            {
                var key = (RSAKeyValue)keyInfoClause;
                return(key.Key);
            }

            if (keyInfoClause is KeyInfoX509Data)
            {
                var cert = GetCertificateFromKeyInfo((KeyInfoX509Data)keyInfoClause);
                return(cert?.PublicKey.Key);
            }

            if (keyInfoClause is DSAKeyValue)
            {
                var key = (DSAKeyValue)keyInfoClause;
                return(key.Key);
            }

            return(null);
        }
コード例 #7
0
ファイル: xmldsig.cs プロジェクト: Tsalex71/mono-1
    static void DumpKeyInfoClause(KeyInfoClause kic)
    {
        KeyInfoName kn = kic as KeyInfoName;

        if (kn != null)
        {
            Console.WriteLine("*** KeyInfoName ***");
            Console.WriteLine("Value: " + kn.Value);
            return;
        }
        KeyInfoX509Data k509 = kic as KeyInfoX509Data;

        if (k509 != null)
        {
            Console.WriteLine("*** KeyInfoX509Data ***");
            Console.WriteLine("Certificates : " + k509.Certificates);
            Console.WriteLine("CRL : " + k509.CRL);
            Console.WriteLine("IssuerSerials : " + k509.IssuerSerials);
            Console.WriteLine("SubjectKeyIds : " + k509.SubjectKeyIds);
            Console.WriteLine("SubjectNames : " + k509.SubjectNames);
            return;
        }
    }
コード例 #8
0
 public void AddClause(KeyInfoClause clause)
 {
 }
コード例 #9
0
        /**
         * Signs the xml using the enveloped mode, with optional xpath transform (see XmlSignatureAppearance).
         * @param sap the XmlSignatureAppearance
         * @param externalSignature  the interface providing the actual signing
         * @param keyInfo KeyInfo for verification
         * @throws GeneralSecurityException
         * @throws IOException
         * @throws DocumentException
         */
        public static void SignXmlDSig(XmlSignatureAppearance sap, IExternalSignature externalSignature, KeyInfoClause keyInfo)
        {
            VerifyArguments(sap, externalSignature);
            List <XmlElement> references = new List <XmlElement>(1);

            references.Add(GenerateContentReference(sap.GetXmlLocator().GetDocument(), sap, null));

            XmlElement signature = GenerateSignatureElement(sap.GetXmlLocator(), null, false);

            Sign(signature, sap.GetXmlLocator(), externalSignature, references, null, keyInfo);
            sap.Close();
        }
コード例 #10
0
        private static void Sign(XmlElement signature, IXmlLocator xmlLocator, IExternalSignature externalSignature,
                                 List <XmlElement> references, XmlElement dsObject, KeyInfoClause keyInfo)
        {
            XmlDocument originalDoc = xmlLocator.GetDocument();

            if (signature == null)
            {
                throw new InvalidOperationException();
            }

            XmlElement signedInfo = originalDoc.CreateElement("SignedInfo", SecurityConstants.XMLDSIG_URI);

            signature.AppendChild(signedInfo);

            XmlElement canonicalizationMethod = originalDoc.CreateElement("CanonicalizationMethod", SecurityConstants.XMLDSIG_URI);

            canonicalizationMethod.SetAttribute("Algorithm", SecurityConstants.XMLDSIG_URI_C14N);
            signedInfo.AppendChild(canonicalizationMethod);

            XmlElement signatureMethod = originalDoc.CreateElement("SignatureMethod", SecurityConstants.XMLDSIG_URI);

            if (externalSignature.GetEncryptionAlgorithm().Equals(SecurityConstants.RSA))
            {
                signatureMethod.SetAttribute("Algorithm", SecurityConstants.XMLDSIG_URI_RSA_SHA1);
            }
            else if (externalSignature.GetEncryptionAlgorithm().Equals(SecurityConstants.DSA))
            {
                signatureMethod.SetAttribute("Algorithm", SecurityConstants.XMLDSIG_URI_DSA_SHA1);
            }
            signedInfo.AppendChild(signatureMethod);

            foreach (XmlElement reference in references)
            {
                signedInfo.AppendChild(reference);
            }

            //if append Signature to original document upper - reference digest will be incorrect.
            originalDoc.DocumentElement.AppendChild(signature);

            XmlElement signedInfoDigest = (XmlElement)signedInfo.CloneNode(true);

            NormalizeNamespaces(signedInfo.CreateNavigator(), signedInfoDigest.CreateNavigator());
            XmlDocument signedInfoDoc = new XmlDocument(originalDoc.NameTable);

            signedInfoDoc.LoadXml(signedInfoDigest.OuterXml);
            byte[] byteRange = CalculateC14nByteRange(signedInfoDoc);

            //Sign with ExternalSignature
            String valueBase64 = Convert.ToBase64String(externalSignature.Sign(byteRange));

            XmlElement signatureValue = originalDoc.CreateElement("SignatureValue", SecurityConstants.XMLDSIG_URI);

            signatureValue.AppendChild(originalDoc.CreateTextNode(valueBase64));

            signature.AppendChild(signatureValue);

            if (keyInfo != null)
            {
                XmlElement keyInfoElement = originalDoc.CreateElement("KeyInfo", SecurityConstants.XMLDSIG_URI);
                keyInfoElement.AppendChild(originalDoc.ImportNode(keyInfo.GetXml(), true));
                signature.AppendChild(keyInfoElement);
            }

            if (dsObject != null)
            {
                signature.AppendChild(dsObject);
            }

            xmlLocator.SetDocument(originalDoc);
        }
コード例 #11
0
ファイル: XmlDSigTest.cs プロジェクト: zeespogeira/itextsharp
        public static bool VerifyPackageSignature(String xml)
        {
            XmlDocument xmlDocument = new XmlDocument();

            xmlDocument.PreserveWhitespace = true;
            xmlDocument.Load(new XmlTextReader(xml));

            XmlElement signatureElement = (XmlElement)xmlDocument.GetElementsByTagName("Signature")[0];
            XmlElement signedInfo       = (XmlElement)signatureElement.GetElementsByTagName("SignedInfo")[0];

            byte[] signedInfoByteRange = CalculateC14nByteRange(signedInfo, xmlDocument);

            XmlNodeList references = signatureElement.GetElementsByTagName("Reference");


            foreach (XmlElement reference in references)
            {
                String uri = reference.GetAttribute("URI");
                if (String.IsNullOrEmpty(uri)) // main reference
                {
                    signatureElement.ParentNode.RemoveChild(signatureElement);
                    XmlNodeList transforms = signatureElement.GetElementsByTagName("Transform");
                    if (transforms.Count > 1) // second transform is Xpath Filter 2.0
                    {
                        XmlElement          xpathFilterTransform = (XmlElement)transforms[1];
                        XmlNamespaceManager namespaceManager     = new XmlNamespaceManager(new NameTable());
                        namespaceManager.AddNamespace("xdp", "http://ns.adobe.com/xdp/");
                        XmlNodeList nodelist = xmlDocument.SelectNodes(xpathFilterTransform.InnerText, namespaceManager);
                        if (!VerifyElement((XmlElement)nodelist[0], xmlDocument, reference))
                        {
                            return(false);
                        }
                        //for correct work with SignedXml class
                        xpathFilterTransform.ParentNode.RemoveChild(xpathFilterTransform);
                    }
                    else
                    {
                        if (!VerifyElement(null, xmlDocument, reference))
                        {
                            return(false);
                        }
                    }

                    // revert
                    xmlDocument.DocumentElement.AppendChild(signatureElement);
                }
                else // SignedProperties reference
                {
                    XmlElement signedProperties = (XmlElement)signatureElement.GetElementsByTagName("xades:SignedProperties")[0];
                    if (!VerifyElement(signedProperties, xmlDocument, reference))
                    {
                        return(false);
                    }
                }
            }

            SignedXml signedXml = new SignedXml(xmlDocument);

            signedXml.LoadXml(signatureElement);

            IEnumerator   keyInfoClauses = signedXml.KeyInfo.GetEnumerator(); keyInfoClauses.MoveNext();
            KeyInfoClause keyInfo        = (KeyInfoClause)keyInfoClauses.Current;

            bool result = false;

            if (keyInfo is RSAKeyValue)
            {
                result = ((RSACryptoServiceProvider)((RSAKeyValue)keyInfo).Key).VerifyData(signedInfoByteRange, "SHA1", signedXml.SignatureValue);
            }
            else if (keyInfo is KeyInfoX509Data)
            {
                AsymmetricAlgorithm rsa = ((X509Certificate2)(((KeyInfoX509Data)keyInfo).Certificates[0])).PublicKey.Key;
                result = ((RSACryptoServiceProvider)rsa).VerifyData(signedInfoByteRange, "SHA1", signedXml.SignatureValue);
            }

            return(result);
        }
コード例 #12
0
ファイル: XadesVerifier.cs プロジェクト: egelke/xades
        /// <summary>
        /// Verify any XAdES (-BES, -T) signature.
        /// </summary>
        /// <remarks>
        /// Requires the XAdES QualifyingProperties and not the signature, it will resolve the signature itself.
        /// </remarks>
        /// <param name="doc">The document for which the </param>
        /// <param name="xadesProps">The XAdES 1.4.1 QualifyingProperties xml-element</param>
        /// <returns>The (useful) information of the signature and xades properties</returns>
        /// <exception cref="ArgumentNullException">When the xades props param is null</exception>
        /// <exception cref="InvalidXadesException">When the XAdES isn't correctly formatted</exception>
        /// <exception cref="XadesValidationException">When the signature isn't valid</exception>
        /// <exception cref="NotSupportedException">When a XAdES or the signature contains unsupported sections</exception>
        public SignatureInfo Verify(XmlDocument doc, XmlElement xadesProps)
        {
            XadesForm form = XadesForm.XadesBes;

            if (doc == null)
            {
                throw new ArgumentNullException("doc", "The doc argument can't be null");
            }
            if (xadesProps == null)
            {
                throw new ArgumentNullException("xadesProps", "The xades props argument can't be null");
            }

            //check if we get a valid xades-props
            //TODO:support QualifyingPropertiesReference
            if (xadesProps.LocalName != "QualifyingProperties" || xadesProps.NamespaceURI != Extra.XadesTools.NS)
            {
                throw new InvalidXadesException("The provider xades properties aren't actually xades properties");
            }

            //Get the corresponding signature of the xades props
            String targetRef;

            if (xadesProps.Attributes["Target"] == null)
            {
                throw new InvalidXadesException("the XAdES Properties has no Target attribute defined");
            }
            targetRef = xadesProps.Attributes["Target"].Value;
            if (targetRef == null || !targetRef.StartsWith("#"))
            {
                throw new InvalidXadesException("the XAdES Properties has an invalid Target attribute value");
            }
            var signatureNode = (XmlElement)xadesProps.OwnerDocument.SelectSingleNode("//ds:Signature[@Id='" + targetRef.Substring(1) + "']", nsMgr);

            if (signatureNode == null)
            {
                throw new InvalidXadesException("The signature referenced by the XAdES Properties was not found (Target-attribute)");
            }

            //Load the signature
            var signature = new SignedXml(doc);

            signature.LoadXml(signatureNode);
            signature.SafeCanonicalizationMethods.Add(OptionalDeflateTransform.AlgorithmUri);

            //check if the signature contains a reference to the xades signed props.
            var xadesRef          = new Reference();
            var signedPropsIdAttr = (XmlAttribute)xadesProps.SelectSingleNode("./xades:SignedProperties/@Id", nsMgr);

            if (signedPropsIdAttr == null)
            {
                throw new InvalidXadesException("The xades Signed Properties do not have an Id which should be referenced in the signature");
            }
            var xadesRefNode = (XmlElement)signatureNode.SelectSingleNode("./ds:SignedInfo/ds:Reference[@Type='http://uri.etsi.org/01903#SignedProperties']", nsMgr);

            if (xadesRefNode == null)
            {
                throw new InvalidXadesException("The signature referenced by the XAdES Properties does not contain a reference element of te type 'http://uri.etsi.org/01903#SignedProperties'");
            }
            xadesRef.LoadXml(xadesRefNode);
            if (xadesRef.Uri != ("#" + signedPropsIdAttr.Value))
            {
                throw new InvalidXadesException("The Signed Properties references does not reference the signed properties");
            }

            //Check for illegal transforms in the reference to the xades signed props
            foreach (Transform t in xadesRef.TransformChain)
            {
                if (t.GetType() != typeof(XmlDsigC14NTransform) && t.GetType() != typeof(XmlDsigExcC14NTransform))
                {
                    throw new InvalidXadesException(String.Format("The signed property reference does contain a transform that isn't allowed {0}", t.Algorithm));
                }
            }

            //Get the provided certificates
            X509Certificate2Collection includedCerts = new X509Certificate2Collection();
            IEnumerator keyInfo = signature.Signature.KeyInfo.GetEnumerator();

            while (keyInfo.MoveNext())
            {
                KeyInfoClause clause = (KeyInfoClause)keyInfo.Current;
                if (clause.GetType() == typeof(KeyInfoX509Data))
                {
                    KeyInfoX509Data x509 = (KeyInfoX509Data)clause;
                    includedCerts.AddRange((X509Certificate2[])x509.Certificates.ToArray(typeof(X509Certificate2)));
                }
                else
                {
                    throw new NotSupportedException("Only X509Data is supported");
                }
            }
            if (includedCerts == null || includedCerts.Count == 0)
            {
                throw new InvalidXadesException("No certificates where found in the the signature key info");
            }

            //Check if any of the verified certificates is used for the signature
            bool                       valid       = false;
            X509Certificate2           signingCert = null;
            X509Certificate2Enumerator vce         = includedCerts.GetEnumerator();

            while (!valid && vce.MoveNext())
            {
                signingCert = vce.Current;
                AsymmetricAlgorithm key = (AsymmetricAlgorithm)signingCert.GetRSAPublicKey() ?? signingCert.GetECDsaPublicKey();
                valid = signature.CheckSignature(key);
            }
            if (!valid)
            {
                throw new XadesValidationException("The signature is invalid");
            }

            //Verify the manifests if present.
            List <ManifestResult> manifestResults = new List <ManifestResult>();

            if (VerifyManifest)
            {
                XmlNodeList manifestNodes = signatureNode.SelectNodes("./ds:Object/ds:Manifest", nsMgr);
                foreach (XmlNode manifestNode in manifestNodes)
                {
                    if (manifestNode.Attributes["Id"] == null)
                    {
                        throw new NotSupportedException("The Xades library only supports manifests with and Id");
                    }

                    int         manifestRefIndex = 0;
                    String      manifestId       = manifestNode.Attributes["Id"].Value;
                    XmlNodeList manifestRefNodes = manifestNode.SelectNodes("./ds:Reference", nsMgr);
                    foreach (XmlNode manifestRefNode in manifestRefNodes)
                    {
                        Reference manifestRef = new Reference();
                        manifestRef.LoadXml((XmlElement)manifestRefNode);
                        byte[] orgValue = manifestRef.DigestValue;

                        SignedXml signatureTmp = new SignedXml(doc);
                        signatureTmp.AddReference(manifestRef);
                        try
                        {
                            signatureTmp.ComputeSignature(new HMACMD5()); //we don't need the signature, so it can be as weak as it wants.
                        }
                        catch (CryptographicException ce)
                        {
                            throw new InvalidXadesException("The the reference " + manifestRefIndex + " of manifest " + manifestNode.Attributes["Id"].Value + " can't be validated", ce);
                        }

                        ManifestResultStatus status;
                        if (orgValue.SequenceEqual(manifestRef.DigestValue))
                        {
                            status = ManifestResultStatus.Valid;
                        }
                        else
                        {
                            status = ManifestResultStatus.Invalid;
                        }
                        String xpath = String.Format("//ds:Signature[@Id='{0}']/ds:Object/ds:Manifest[@Id='{1}']/ds:Reference[{2}]", targetRef.Substring(1), manifestId, ++manifestRefIndex);
                        manifestResults.Add(new ManifestResult(xpath, status));
                    }
                }
            }

            //Signing time retrieval
            DateTimeOffset?signingTime        = null;
            XmlNode        signingTimeTxtNode = xadesProps.SelectSingleNode("./xades:SignedProperties/xades:SignedSignatureProperties/xades:SigningTime/text()", nsMgr);

            if (signingTimeTxtNode != null)
            {
                DateTimeOffset signingTimeValue;
                if (!DateTimeOffset.TryParse(signingTimeTxtNode.Value, CultureInfo.InvariantCulture, DateTimeStyles.None, out signingTimeValue))
                {
                    throw new InvalidXadesException("Signing time provided in the xades information isn't valid");
                }
                signingTime = signingTimeValue;
            }

            //TODO:check for EPES.

            //check time-stamp
            XmlNodeList timestamps = xadesProps.SelectNodes("./xades:UnsignedProperties/xades:UnsignedSignatureProperties/xades:SignatureTimeStamp", nsMgr);

            if (timestamps != null && timestamps.Count > 0)
            {
                form = form | XadesForm.XadesT;
                foreach (XmlNode timestamp in timestamps)
                {
                    XmlNode timestampC14NAlgoNode = timestamp.SelectSingleNode("./ds:CanonicalizationMethod/@Algorithm", nsMgr);
                    if (timestampC14NAlgoNode == null)
                    {
                        new InvalidXadesException("Canonicalization method missing in the signature timestamp");
                    }

                    var signatureValue = (XmlElement)signatureNode.SelectSingleNode("./ds:SignatureValue", nsMgr);
                    if (signatureValue == null)
                    {
                        throw new InvalidXadesException("Can't find the signature value for the signature timestamp");
                    }

                    var timestampC14NAlgo = (Transform)CryptoConfig.CreateFromName(timestampC14NAlgoNode.Value);
                    if (timestampC14NAlgo == null || timestampC14NAlgo.GetType() != typeof(XmlDsigC14NTransform) && timestampC14NAlgo.GetType() != typeof(XmlDsigExcC14NTransform))
                    {
                        throw new InvalidXadesException(String.Format("The signature timestamp has a canonicalization method that isn't allowed {0}", timestampC14NAlgoNode.Value));
                    }

                    //Serialize because the C14N overloads which accepts lists is totally wrong (it C14N's the document)
                    MemoryStream stream = new MemoryStream();
                    using (var writer = XmlWriter.Create(stream))
                    {
                        signatureValue.WriteTo(writer);
                    }
                    stream.Seek(0, SeekOrigin.Begin);

                    //Canonicalize the signature value
                    timestampC14NAlgo.LoadInput(stream);
                    var canonicalized = (Stream)timestampC14NAlgo.GetOutput(typeof(Stream));

                    XmlNode timestampValueTxtNode = timestamp.SelectSingleNode("./xades:EncapsulatedTimeStamp/text()", nsMgr);
                    if (timestampValueTxtNode != null)
                    {
                        //Get the timestamp token
                        TimeStampToken tst = Convert.FromBase64String(timestampValueTxtNode.Value).ToTimeStampToken();

                        if (!tst.IsMatch(canonicalized))
                        {
                            throw new XadesValidationException("The timestamp doesn't match the signature value");
                        }

                        //verify the time-stamp
                        Timestamp ts = tst.Validate(ExtraStore);
                        if (ts.TimestampStatus.Count(x => x.Status != X509ChainStatusFlags.NoError) > 0)
                        {
                            throw new XadesValidationException(String.Format("The timestamp TSA has an invalid status {0}: {1}",
                                                                             ts.TimestampStatus[0].Status, ts.TimestampStatus[0].StatusInformation));
                        }
                        foreach (ChainElement chainE in ts.CertificateChain.ChainElements)
                        {
                            if (chainE.ChainElementStatus.Count(x => x.Status != X509ChainStatusFlags.NoError) > 0)
                            {
                                throw new XadesValidationException(String.Format("The timestamp TSA chain contains an invalid certificate '{0}' ({1}: {2})",
                                                                                 chainE.Certificate.Subject, chainE.ChainElementStatus[0].Status, chainE.ChainElementStatus[0].StatusInformation));
                            }
                        }

                        //check the timestamp token against the signing time.
                        DateTime tsTime = ts.Time;
                        if (signingTime != null)
                        {
                            DateTime signingTimeUtc = signingTime.Value.UtcDateTime;
                            if (Math.Abs((tsTime - signingTimeUtc).TotalSeconds) > TimestampGracePeriod.TotalSeconds)
                            {
                                throw new XadesValidationException("The signature timestamp it to old with regards to the signing time");
                            }
                        }
                        else
                        {
                            signingTime = tsTime;
                        }
                    }
                    else
                    {
                        //TODO:support xml timestamps
                        throw new NotSupportedException("Only Encapsulated timestamps are supported");
                    }
                }
            }

            //check check the chain
            Chain chain = signingCert.BuildChain(signingTime == null ? DateTime.UtcNow : signingTime.Value.UtcDateTime,
                                                 includedCerts);

            if (chain.ChainStatus.Count(x => x.Status != X509ChainStatusFlags.NoError) > 0)
            {
                throw new XadesValidationException(String.Format("The signing certificate chain is invalid ({0}: {1})",
                                                                 chain.ChainStatus[0].Status, chain.ChainStatus[0].StatusInformation));
            }

            //Select the correct certificate based on the xades-bes info
            XmlNodeList signedCerts = xadesProps.SelectNodes("./xades:SignedProperties/xades:SignedSignatureProperties/xades:SigningCertificate/xades:Cert", nsMgr);

            //TODO:Support the fact that it is also legal to sign the KeyInfo (G.2.2.1)
            if (signedCerts.Count == 0)
            {
                throw new InvalidXadesException("No signing certificates provided in the xades information");
            }

            //Find certs via signed info, checking with hash.
            X509Certificate2Collection unsignedChainCerts = new X509Certificate2Collection(chain.ChainElements.Select(c => c.Certificate).ToArray());

            foreach (XmlNode signedCert in signedCerts)
            {
                XmlNode issuerTxtNode = signedCert.SelectSingleNode("./xades:IssuerSerial/ds:X509IssuerName/text()", nsMgr);
                if (issuerTxtNode == null)
                {
                    throw new InvalidXadesException("Xades information does not contain an issuer name for the signing certificate");
                }
                XmlNode serialNumberTxtNode = signedCert.SelectSingleNode("./xades:IssuerSerial/ds:X509SerialNumber/text()", nsMgr);
                if (serialNumberTxtNode == null)
                {
                    throw new InvalidXadesException("Xades information does not contain an serial number for the signing certificate");
                }

                X509Certificate2Collection certsSameIssuer = unsignedChainCerts.Find(X509FindType.FindByIssuerDistinguishedName, issuerTxtNode.Value, false);
                if (certsSameIssuer.Count == 0)
                {
                    throw new InvalidXadesException(String.Format("Xades provided signed certificate {0} ({1}) can't be found in the chain", serialNumberTxtNode.Value, issuerTxtNode.Value));
                }
                X509Certificate2Collection exactCerts = certsSameIssuer.Find(X509FindType.FindBySerialNumber, serialNumberTxtNode.Value, false);
                if (exactCerts.Count == 0)
                {
                    throw new InvalidXadesException(String.Format("Xades provided signed certificate {0} ({1}) can't be found in the chain", serialNumberTxtNode.Value, issuerTxtNode.Value));
                }
                if (exactCerts.Count > 1)
                {
                    throw new InvalidXadesException(String.Format("Xades provided signed certificate {0} ({1}) can be found more then once in the chain", serialNumberTxtNode.Value, issuerTxtNode.Value));
                }

                XmlNode digestMethodTxtNode = signedCert.SelectSingleNode("./xades:CertDigest/ds:DigestMethod/@Algorithm", nsMgr);
                if (digestMethodTxtNode == null)
                {
                    throw new InvalidXadesException("Xades information does not contain the digest method for the signing certificate");
                }
                XmlNode digestValueTxtNode = signedCert.SelectSingleNode("./xades:CertDigest/ds:DigestValue/text()", nsMgr);
                if (digestValueTxtNode == null)
                {
                    throw new InvalidXadesException("Xades information does not contain the digest value for the signing certificate");
                }

                HashAlgorithm algo;
                try
                {
                    algo = (HashAlgorithm)CryptoConfig.CreateFromName(digestMethodTxtNode.Value);
                }
                catch (Exception e)
                {
                    throw new InvalidXadesException("The provided digest method of the signing certificate in xades isn't valid or isn't supported", e);
                }
                String digestValueReal = Convert.ToBase64String(algo.ComputeHash(exactCerts[0].GetRawCertData()));
                if (digestValueTxtNode.Value != digestValueReal)
                {
                    throw new XadesValidationException("The certificate of the key info isn't correct according to the certificate info in xades");
                }

                unsignedChainCerts.Remove(exactCerts[0]);
            }

            //has the end cert being signed?
            if (unsignedChainCerts.Contains(signingCert))
            {
                throw new XadesValidationException(String.Format("Signing certificate not part of the signature"));
            }
            //TODO::add some kind of warning or option to test for all.

            return(new SignatureInfo(form, signingCert, signingTime, manifestResults.ToArray()));
        }
コード例 #13
0
ファイル: MakeXmlSignature.cs プロジェクト: tbrion/itextsharp
 /**
  * Signs the xml using the enveloped mode, with optional xpath transform (see XmlSignatureAppearance).
  * @param sap the XmlSignatureAppearance
  * @param externalSignature  the interface providing the actual signing
  * @param keyInfo KeyInfo for verification
  * @throws GeneralSecurityException
  * @throws IOException
  * @throws DocumentException
  */
 public static void signXmlDSig(XmlSignatureAppearance sap,
                                IExternalSignature externalSignature, KeyInfoClause keyInfo)
 {
     throw new NotImplementedException("Xml signatures are not supported yet");
 }
コード例 #14
0
ファイル: xmldsig.cs プロジェクト: nlhepler/mono
	static void DumpKeyInfoClause (KeyInfoClause kic) 
	{
		KeyInfoName kn = kic as KeyInfoName;
		if (kn != null) {
			Console.WriteLine ("*** KeyInfoName ***");
			Console.WriteLine ("Value: " + kn.Value);
			return;
		}
		KeyInfoX509Data k509 = kic as KeyInfoX509Data;
		if (k509 != null) {
			Console.WriteLine ("*** KeyInfoX509Data ***");
			Console.WriteLine ("Certificates : " + k509.Certificates);
			Console.WriteLine ("CRL : " + k509.CRL);
			Console.WriteLine ("IssuerSerials : " + k509.IssuerSerials);
			Console.WriteLine ("SubjectKeyIds : " + k509.SubjectKeyIds);
			Console.WriteLine ("SubjectNames : " + k509.SubjectNames);
			return;
		}
	}
コード例 #15
0
	public void AddClause(KeyInfoClause clause) {}