Esempio n. 1
0
        /// <summary>
        /// Signs the specified query string with the certificate found in the
        /// local machine matching the provided friendly name.  The algorithm
        /// is expected to be one of the parameters in the query string.
        /// </summary>
        /// <param name="certFriendlyName">
        /// Friendly Name of the X509Certificate to be retrieved
        /// from the LocalMachine keystore and used to sign the xml document.
        /// Be sure to have appropriate permissions set on the keystore.
        /// </param>
        /// <param name="queryString">Query string to sign.</param>
        /// <returns>
        /// A signed query string where a digital signature is added.
        /// </returns>
        public string SignQueryString(string certFriendlyName, string queryString)
        {
            if (string.IsNullOrEmpty(certFriendlyName))
            {
                throw new Saml2Exception(Resources.SignedQueryStringInvalidCertFriendlyName);
            }

            if (string.IsNullOrEmpty(queryString))
            {
                throw new Saml2Exception(Resources.SignedQueryStringInvalidQueryString);
            }

            char[] queryStringSep = { '&' };
            var    queryParams    = new NameValueCollection();

            foreach (var pairs in queryString.Split(queryStringSep))
            {
                var key   = pairs.Substring(0, pairs.IndexOf("=", StringComparison.Ordinal));
                var value = pairs.Substring(pairs.IndexOf("=", StringComparison.Ordinal) + 1);

                queryParams[key] = value;
            }

            if (string.IsNullOrEmpty(queryParams[Saml2Constants.SignatureAlgorithm]))
            {
                throw new Saml2Exception(Resources.SignedQueryStringSigAlgMissing);
            }

            var cert = m_certificateFactory.GetCertificateByFriendlyName(certFriendlyName, m_logger);

            if (cert == null)
            {
                throw new Saml2Exception(Resources.SignedQueryStringCertNotFound);
            }

            if (!cert.HasPrivateKey)
            {
                throw new Saml2Exception(Resources.SignedQueryStringCertHasNoPrivateKey);
            }

            var signatureAlgorithmUrl = HttpUtility.UrlDecode(queryParams[Saml2Constants.SignatureAlgorithm]);
            var hashAlgorithmName     = GetHashAlgorithmNameFromSignatureAlgorithmUrl(signatureAlgorithmUrl);

            using (var signingKey = cert.GetRSAPrivateKey())
            {
                var privateKey = signingKey;
                var signature  = privateKey.SignData(Encoding.UTF8.GetBytes(queryString), hashAlgorithmName, RSASignaturePadding.Pkcs1);

                var encodedSignature = Convert.ToBase64String(signature);

                var signedQueryString
                    = queryString
                      + "&" + Saml2Constants.Signature
                      + "=" + HttpUtility.UrlEncode(encodedSignature);

                return(signedQueryString);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Signs the specified query string with the certificate found in the
        /// local machine matching the provided friendly name.  The algorithm
        /// is expected to be one of the parameters in the query string.
        /// </summary>
        /// <param name="certFriendlyName">
        /// Friendly Name of the X509Certificate to be retrieved
        /// from the LocalMachine keystore and used to sign the xml document.
        /// Be sure to have appropriate permissions set on the keystore.
        /// </param>
        /// <param name="queryString">Query string to sign.</param>
        /// <returns>
        /// A signed query string where a digital signature is added.
        /// </returns>
        public string SignQueryString(string certFriendlyName, string queryString)
        {
            if (string.IsNullOrEmpty(certFriendlyName))
            {
                throw new Saml2Exception(Resources.SignedQueryStringInvalidCertFriendlyName);
            }

            if (string.IsNullOrEmpty(queryString))
            {
                throw new Saml2Exception(Resources.SignedQueryStringInvalidQueryString);
            }

            char[] queryStringSep = { '&' };
            var    queryParams    = new NameValueCollection();

            foreach (string pairs in queryString.Split(queryStringSep))
            {
                string key   = pairs.Substring(0, pairs.IndexOf("=", StringComparison.Ordinal));
                string value = pairs.Substring(pairs.IndexOf("=", StringComparison.Ordinal) + 1);

                queryParams[key] = value;
            }

            if (string.IsNullOrEmpty(queryParams[Saml2Constants.SignatureAlgorithm]))
            {
                throw new Saml2Exception(Resources.SignedQueryStringSigAlgMissing);
            }

            X509Certificate2 cert = _certificateFactory.GetCertificateByFriendlyName(certFriendlyName);

            if (cert == null)
            {
                throw new Saml2Exception(Resources.SignedQueryStringCertNotFound);
            }

            if (!cert.HasPrivateKey)
            {
                throw new Saml2Exception(Resources.SignedQueryStringCertHasNoPrivateKey);
            }

            string encodedSignature   = string.Empty;
            string signatureAlgorithm = HttpUtility.UrlDecode(queryParams[Saml2Constants.SignatureAlgorithm]);

            if (signatureAlgorithm == Saml2Constants.SignatureAlgorithmRsa)
            {
                var    privateKey = (RSACryptoServiceProvider)cert.PrivateKey;
                byte[] signature  = privateKey.SignData(
                    Encoding.UTF8.GetBytes(queryString),
                    new SHA1CryptoServiceProvider());

                encodedSignature = Convert.ToBase64String(signature);
            }
            else
            {
                throw new Saml2Exception(Resources.SignedQueryStringSigAlgNotSupported);
            }

            string signedQueryString
                = queryString
                  + "&" + Saml2Constants.Signature
                  + "=" + HttpUtility.UrlEncode(encodedSignature);

            return(signedQueryString);
        }