Exemplo n.º 1
0
        private static bool InternalValidate(XElement signatureToValidate, Federation.Federation federation, ICredentialVault vault, bool checkForTrustedCertificates, bool checkRevoked)
        {
            if (signatureToValidate.NodeType != XmlNodeType.Element)
            {
                throw new ModelException("The signature to validate must be a ds:Signature Element!");
            }

            var xml = new XmlDocument();

            xml.Load(signatureToValidate.CreateReader());

            bool isAssertion = false;
            var  nsManager   = NameSpaces.MakeNsManager(xml.NameTable);
            var  sig         = xml.SelectSingleNode("/soap:Envelope/soap:Header/wsse:Security/ds:Signature", nsManager) as XmlElement;

            if (sig == null)
            {
                sig         = xml.SelectSingleNode("/saml:Assertion/ds:Signature", nsManager) as XmlElement;
                isAssertion = true;
                if (sig == null)
                {
                    sig         = xml.GetElementsByTagName("Signature", NameSpaces.ds)[0] as XmlElement;
                    isAssertion = true;
                }
            }
            if (sig == null)
            {
                return(false);
            }
            var signature = new Signature();

            sig = MakeSignatureCheckSamlCompliant(sig);
            signature.LoadXml(sig);
            var cert = signature.KeyInfo.Cast <KeyInfoX509Data>().Select(d => d.Certificates[0] as X509Certificate2).FirstOrDefault(c => c != null);

            if (!ConfigurationManager.AppSettings.AllKeys.Contains("CheckDate") || !ConfigurationManager.AppSettings["CheckDate"].ToLower().Equals("false"))
            {
                //check if certificate is expired or cannot be used yet
                if (!CheckDates(cert))
                {
                    return(false);
                }
            }


            //Check that the certificate used for validation is trusted. If a Federation has been specified
            //the signature must have been created by the STS. If no federation is specified, the
            //certificate must be trusted in the CredentialVault.
            if (checkForTrustedCertificates)
            {
                var trusted = false;
                if (federation != null)
                {
                    trusted = federation.IsValidSTSCertificate(cert);
                }
                else if (vault != null)
                {
                    trusted = vault.IsTrustedCertificate(cert);
                }
                if (!trusted)
                {
                    throw new ModelException("The certificate that signed the security token is not trusted!");
                }
            }
            // check the certificates CRL if the certificate is revoked
            if (checkRevoked)
            {
                CrlCertificateStatusChecker crlChecker = new CrlCertificateStatusChecker();
                var isValid = crlChecker.GetRevocationStatus(cert).IsValid;
                if (!isValid)
                {
                    throw new ModelException("The certificate or one in its certificate chain has been revoked!");
                }
            }

            // check if xml is actually signed with key sent in message
            var signed = new SealSignedXml(signatureToValidate);

            if (isAssertion)
            {
                return(signed.CheckAssertionSignature());
            }
            return(signed.CheckEnvelopeSignature());
        }