/// <summary>
        /// Tries to sign and verify a bit of test data using the given certificate.
        /// This will cause the security subsystem to grant the calling app access
        /// to the certificate's private key for the current session.
        ///
        /// </summary>
        /// <param name="selectedCertificate">The X.509 Certificate for which access is required</param>
        /// <returns>True on successful signing and verification, false otherwise.</returns>
        private static bool VerifyCertificateKeyAccess(Certificate selectedCertificate)
        {
            bool VerifyResult = false;              // default to access failure
            var  keyPairTask  = PersistedKeyProvider.OpenKeyPairFromCertificateAsync(
                selectedCertificate, HashAlgorithmNames.Sha1,
                CryptographicPadding.RsaPkcs1V15).AsTask();

            keyPairTask.Wait();
            CryptographicKey keyPair = keyPairTask.Result;
            String           buffer  = "Data to sign";
            IBuffer          Data    = CryptographicBuffer.ConvertStringToBinary(buffer, BinaryStringEncoding.Utf16BE);

            try
            {
                // sign the data by using the key
                var signedDataTask = CryptographicEngine.SignAsync(keyPair, Data).AsTask();
                signedDataTask.Wait();
                IBuffer Signed = signedDataTask.Result;
                VerifyResult = CryptographicEngine.VerifySignature(keyPair, Data, Signed);
            }
            catch (Exception exp)
            {
                Debug.WriteLine("Verification Failed. Exception Occurred : {0}", exp.Message);
                // default result is false so drop through to exit.
            }

            return(VerifyResult);
        }
        public static async Task <string> CreateDeviceAuthChallengeResponseAsync(IDictionary <string, string> challengeData)
        {
            string      authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\"";
            Certificate certificate        = null;

            try
            {
                certificate = await FindCertificate(challengeData).ConfigureAwait(false);
            }
            catch (AdalException ex)
            {
                if (ex.ErrorCode == AdalError.DeviceCertificateNotFound)
                {
                    return(await Task.FromResult(string.Format(CultureInfo.InvariantCulture, @"PKeyAuth Context=""{0}"",Version=""{1}""", challengeData["Context"], challengeData["Version"])).ConfigureAwait(false));
                }
            }
            DeviceAuthJWTResponse response = new DeviceAuthJWTResponse(challengeData["SubmitUrl"],
                                                                       challengeData["nonce"], Convert.ToBase64String(certificate.GetCertificateBlob().ToArray()));
            IBuffer input = CryptographicBuffer.ConvertStringToBinary(response.GetResponseToSign(),
                                                                      BinaryStringEncoding.Utf8);
            CryptographicKey keyPair = await
                                       PersistedKeyProvider.OpenKeyPairFromCertificateAsync(certificate, HashAlgorithmNames.Sha256,
                                                                                            CryptographicPadding.RsaPkcs1V15).AsTask().ConfigureAwait(false);

            IBuffer signed = await CryptographicEngine.SignAsync(keyPair, input).AsTask().ConfigureAwait(false);

            string signedJwt = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", response.GetResponseToSign(),
                                             Base64UrlEncoder.Encode(signed.ToArray()));
            string authToken = string.Format(CultureInfo.InvariantCulture, " AuthToken=\"{0}\"", signedJwt);

            return(string.Format(CultureInfo.InvariantCulture, authHeaderTemplate, authToken, challengeData["Context"], challengeData["Version"]));
        }
Esempio n. 3
0
        public static async Task <bool> VerifyCertificateKeyAccess(Certificate selectedCertificate)
        {
            bool             VerifyResult = false; // default to access failure
            CryptographicKey keyPair      = await PersistedKeyProvider.OpenKeyPairFromCertificateAsync(
                selectedCertificate, HashAlgorithmNames.Sha1,
                CryptographicPadding.RsaPkcs1V15);

            String  buffer = "Data to sign";
            IBuffer Data   = CryptographicBuffer.ConvertStringToBinary(buffer, BinaryStringEncoding.Utf16BE);

            try
            {
                //sign the data by using the key
                IBuffer Signed = await CryptographicEngine.SignAsync(keyPair, Data);

                VerifyResult = CryptographicEngine.VerifySignature(keyPair, Data, Signed);
            }
            catch (Exception exp)
            {
                System.Diagnostics.Debug.WriteLine("Verification Failed. Exception Occurred : {0}", exp.Message);
                // default result is false so drop through to exit.
            }

            return(VerifyResult);
        }
Esempio n. 4
0
        private void GetTokenResponse(object Sender, IqResultEventArgs e)
        {
            object[] P = (object[])e.State;
#if WINDOWS_UWP
            Certificate Certificate = (Certificate)P[0];
#else
            X509Certificate2 Certificate = (X509Certificate2)P[0];
#endif
            XmlElement E = e.FirstElement;

            if (e.Ok && E != null && E.LocalName == "getTokenChallenge" && E.NamespaceURI == NamespaceProvisioningToken)
            {
                int    SeqNr     = XML.Attribute(E, "seqnr", 0);
                string Challenge = E.InnerText;
                byte[] Bin       = System.Convert.FromBase64String(Challenge);

#if WINDOWS_UWP
                CryptographicKey Key = PersistedKeyProvider.OpenPublicKeyFromCertificate(Certificate,
                                                                                         Certificate.SignatureHashAlgorithmName, CryptographicPadding.RsaPkcs1V15);
                IBuffer Buffer = CryptographicBuffer.CreateFromByteArray(Bin);
                Buffer = CryptographicEngine.Decrypt(Key, Buffer, null);
                CryptographicBuffer.CopyToByteArray(Buffer, out Bin);
                string Response = System.Convert.ToBase64String(Bin);
#else
                Bin = Certificate.GetRSAPrivateKey().Decrypt(Bin, RSAEncryptionPadding.Pkcs1);
                string Response = System.Convert.ToBase64String(Bin);
#endif

                this.client.SendIqGet(this.provisioningServerAddress, "<getTokenChallengeResponse xmlns='" + NamespaceProvisioningToken + "' seqnr='" +
                                      SeqNr.ToString() + "'>" + Response + "</getTokenChallengeResponse>",
                                      this.GetTokenChallengeResponse, P);
            }
        }
        public bool TryCreateDeviceAuthChallengeResponseAsync(HttpResponseHeaders headers, Uri endpointUri, out string responseHeader)
        {
            responseHeader = string.Empty;
            Certificate certificate        = null;
            string      authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\"";

            if (!DeviceAuthHelper.IsDeviceAuthChallenge(headers))
            {
                return(false);
            }
            if (!DeviceAuthHelper.CanOSPerformPKeyAuth())
            {
                responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(headers);
                return(false);
            }

            IDictionary <string, string> challengeData = DeviceAuthHelper.ParseChallengeData(headers);

            if (!challengeData.ContainsKey("SubmitUrl"))
            {
                challengeData["SubmitUrl"] = endpointUri.AbsoluteUri;
            }

            try
            {
                certificate = Task.FromResult(FindCertificateAsync(challengeData)).Result.Result;
            }
            catch (MsalException ex)
            {
                if (ex.ErrorCode == MsalError.DeviceCertificateNotFound)
                {
                    responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(headers);
                    return(true);
                }
            }

            DeviceAuthJWTResponse responseJWT = new DeviceAuthJWTResponse(challengeData["SubmitUrl"],
                                                                          challengeData["nonce"], Convert.ToBase64String(certificate.GetCertificateBlob().ToArray()));
            IBuffer input = CryptographicBuffer.ConvertStringToBinary(responseJWT.GetResponseToSign(),
                                                                      BinaryStringEncoding.Utf8);
            CryptographicKey keyPair =
                Task.FromResult(PersistedKeyProvider.OpenKeyPairFromCertificateAsync(certificate, HashAlgorithmNames.Sha256, CryptographicPadding.RsaPkcs1V15)).Result.GetResults();

            IBuffer signed = Task.FromResult(CryptographicEngine.SignAsync(keyPair, input)).Result.GetResults();

            string signedJwt = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", responseJWT.GetResponseToSign(),
                                             Base64UrlHelpers.Encode(signed.ToArray()));
            string authToken = string.Format(CultureInfo.InvariantCulture, " AuthToken=\"{0}\"", signedJwt);

            responseHeader = string.Format(CultureInfo.InvariantCulture, authHeaderTemplate, authToken, challengeData["Context"], challengeData["Version"]);
            return(true);
        }
Esempio n. 6
0
        public async Task <string> CreateDeviceAuthChallengeResponse(IDictionary <string, string> challengeData)
        {
            string authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\"";

            Certificate certificate = await FindCertificate(challengeData);

            DeviceAuthJWTResponse response = new DeviceAuthJWTResponse(challengeData["SubmitUrl"],
                                                                       challengeData["nonce"], Convert.ToBase64String(certificate.GetCertificateBlob().ToArray()));
            IBuffer input = CryptographicBuffer.ConvertStringToBinary(response.GetResponseToSign(),
                                                                      BinaryStringEncoding.Utf8);
            CryptographicKey keyPair = await
                                       PersistedKeyProvider.OpenKeyPairFromCertificateAsync(certificate, HashAlgorithmNames.Sha256,
                                                                                            CryptographicPadding.RsaPkcs1V15);

            IBuffer signed = await CryptographicEngine.SignAsync(keyPair, input);

            string signedJwt = string.Format(CultureInfo.CurrentCulture, "{0}.{1}", response.GetResponseToSign(),
                                             Base64UrlEncoder.Encode(signed.ToArray()));
            string authToken = string.Format(CultureInfo.CurrentCulture, " AuthToken=\"{0}\"", signedJwt);

            return(string.Format(authHeaderTemplate, authToken, challengeData["Context"], challengeData["Version"]));
        }
Esempio n. 7
0
        /// <summary>
        /// Gets the private key for the certificate matching the specified selector.
        /// </summary>
        /// <remarks>
        /// Gets the private key for the first certificate that matches the specified selector.
        /// </remarks>
        /// <returns>The private key on success; otherwise <c>null</c>.</returns>
        /// <param name="selector">The search criteria for the private key.</param>
        protected virtual async Task <AsymmetricKeyParameter> GetPrivateKeyAsync(IX509Selector selector)
        {
            // first we need to find the certificate...
            var match = selector as X509CertStoreSelector;
            var query = new CertificateQuery();

            if (match == null)
            {
                return(null);
            }

            if (match.Certificate != null)
            {
                query.Thumbprint = HexDecode(match.Certificate.GetFingerprint());
            }

            if (match.Issuer != null)
            {
                query.IssuerName = match.Issuer.ToString();
            }

            var certificates = await CertificateStores.FindAllAsync(query);

            var certificate = certificates.FirstOrDefault();

            if (certificate == null)
            {
                return(null);
            }

            // now get the key

            // TODO: what hash algo/padding do we want? does it matter?
            var key = await PersistedKeyProvider.OpenKeyPairFromCertificateAsync(certificate, HashAlgorithmNames.Sha256, CryptographicPadding.RsaPkcs1V15);

            var buffer = key.Export(CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey);

            return(LoadPrivateKey(buffer));
        }
Esempio n. 8
0
        private void TokenChallengeHandler(object Sender, IqEventArgs e)
        {
            XmlElement     E         = e.Query;
            string         Token     = XML.Attribute(E, "token");
            string         Challenge = E.InnerText;
            CertificateUse Use;

            lock (this.certificates)
            {
                if (!this.certificates.TryGetValue(Token, out Use) || (DateTime.Now - Use.LastUse).TotalMinutes > 1)
                {
                    throw new ForbiddenException("Token not recognized.", e.IQ);
                }
            }

            if (Use.LocalCertificate != null)
            {
                byte[] Bin = System.Convert.FromBase64String(Challenge);

#if WINDOWS_UWP
                CryptographicKey Key = PersistedKeyProvider.OpenPublicKeyFromCertificate(Use.LocalCertificate,
                                                                                         Use.LocalCertificate.SignatureHashAlgorithmName, CryptographicPadding.RsaPkcs1V15);
                IBuffer Buffer = CryptographicBuffer.CreateFromByteArray(Bin);
                Buffer = CryptographicEngine.Decrypt(Key, Buffer, null);
                CryptographicBuffer.CopyToByteArray(Buffer, out Bin);
                string Response = System.Convert.ToBase64String(Bin);
#else
                Bin = Use.LocalCertificate.GetRSAPrivateKey().Decrypt(Bin, RSAEncryptionPadding.Pkcs1);
                string Response = System.Convert.ToBase64String(Bin);
#endif

                e.IqResult("<tokenChallengeResponse xmlns='" + NamespaceProvisioningToken + "'>" + Response + "</tokenChallengeResponse>");
            }
            else
            {
                this.client.SendIqGet(Use.RemoteCertificateJid, e.Query.OuterXml, this.ForwardedTokenChallengeResponse, e);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// This is the click handler for the 'RunSample' button.  It is responsible for executing the sample code.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void RunSample_Click(object sender, RoutedEventArgs e)
        {
            Certificate selectedCertificate = null;
            string      verifyselection     = VerifyCert.SelectionBoxItem.ToString();

            //get the selected certificate
            if (CertificateList.SelectedIndex >= 0 && CertificateList.SelectedIndex < certList.Count)
            {
                selectedCertificate = certList[CertificateList.SelectedIndex];
            }

            if (selectedCertificate == null)
            {
                ViewCertText.Text = "Please select a certificate first.";
                return;
            }

            // a certificate was selected, do the desired operation
            if (verifyselection.Equals("Verify Certificate"))
            {
                //Build the chain
                var chain = await selectedCertificate.BuildChainAsync(null, null);

                //Validate the chain
                var result = chain.Validate();
                verifytext = "\n Verification Result :" + result.ToString();
            }
            else if (verifyselection.Equals("Sign/Verify using certificate key"))
            {
                // get private key
                CryptographicKey keyPair = await PersistedKeyProvider.OpenKeyPairFromCertificateAsync(selectedCertificate, HashAlgorithmNames.Sha1, CryptographicPadding.RsaPkcs1V15);

                String  cookie = "Some Data to sign";
                IBuffer Data   = CryptographicBuffer.ConvertStringToBinary(cookie, BinaryStringEncoding.Utf16BE);

                try
                {
                    //sign the data by using the key
                    IBuffer Signed  = CryptographicEngine.Sign(keyPair, Data);
                    bool    bresult = CryptographicEngine.VerifySignature(keyPair, Data, Signed);

                    if (bresult == true)
                    {
                        verifytext = "\n Verification Result : Successfully signed and verified signature";
                    }
                    else
                    {
                        verifytext = "\n Verification Result : Verify Signature Failed";
                    }
                }
                catch (Exception exp)
                {
                    verifytext = "\n Verification Failed. Exception Occurred :" + exp.Message;
                }
            }
            else if (verifyselection.Equals("Sign/Verify using CMS based format"))
            {
                IInputStream pdfInputstream;
                InMemoryRandomAccessStream originalData = new InMemoryRandomAccessStream();
                //Populate the new memory stream
                pdfInputstream = originalData.GetInputStreamAt(0);
                CmsSignerInfo signer = new CmsSignerInfo();
                signer.Certificate       = selectedCertificate;
                signer.HashAlgorithmName = HashAlgorithmNames.Sha1;
                IList <CmsSignerInfo> signers = new List <CmsSignerInfo>();

                signers.Add(signer);
                try
                {
                    IBuffer signature = await CmsDetachedSignature.GenerateSignatureAsync(pdfInputstream, signers, null);

                    CmsDetachedSignature cmsSignedData = new CmsDetachedSignature(signature);
                    pdfInputstream = originalData.GetInputStreamAt(0);
                    SignatureValidationResult validationResult = await cmsSignedData.VerifySignatureAsync(pdfInputstream);

                    if (SignatureValidationResult.Success == validationResult)
                    {
                        verifytext = "\n Verification Result : Successfully signed and verified Signature";
                    }
                    else
                    {
                        verifytext = "\n Verification Result : Verify Signature using CMS based format Failed";
                    }
                }
                catch (Exception exp)
                {
                    verifytext = "\n Verification Failed. Exception Occurred :" + exp.Message;
                }
            }
            else if (verifyselection.Equals("Get certificate and show details"))
            {
                DisplayCertificate(selectedCertificate);
            }

            ViewCertText.Text += verifytext;
            verifytext         = string.Empty;
        }