Пример #1
0
        static async Task <(int err, byte[] sig)> VerifyUser(string key_name, string contentToSign)
        {
            if (await KeyCredentialManager.IsSupportedAsync() == false)
            {
                await(new MessageDialog("KeyCredentialManager not supported")).ShowAsync();
                return(ERR_VERIFY_HELLO_NOT_SUPPORTED, null);
            }

            var key = await KeyCredentialManager.OpenAsync(key_name);

            if (key.Status != KeyCredentialStatus.Success)
            {
                return(CredentialStatusToExitCode(key.Status), null);
            }

            var buf     = CryptographicBuffer.ConvertStringToBinary(contentToSign, BinaryStringEncoding.Utf8);
            var signRes = await key.Credential.RequestSignAsync(buf);

            if (signRes.Status != KeyCredentialStatus.Success)
            {
                return(CredentialStatusToExitCode(key.Status), null);
            }

            byte[] sig;
            CryptographicBuffer.CopyToByteArray(signRes.Result, out sig);
            return(0, sig);
        }
Пример #2
0
        /// <summary>
        /// Check if a ms passport account exists
        /// </summary>
        /// <exception cref="UserCancelledException"></exception>
        /// <exception cref="UserPrefersPasswordException"></exception>
        /// <exception cref="UnknownException"></exception>
        /// <exception cref="AggregateException"></exception>
        /// <param name="accountId">The id of the account to check</param>
        /// <returns>true if the account exists</returns>
        public static bool PassportAccountExists(string accountId)
        {
            // Try to get the account
            Task <KeyCredentialRetrievalResult> task = Task.Run(async() => await KeyCredentialManager.OpenAsync(accountId));

            // Check the result
            switch (task.Result.Status)
            {
            case KeyCredentialStatus.Success:
                // The account was found
                return(true);

            case KeyCredentialStatus.NotFound:
                // The account was not found
                return(false);

            case KeyCredentialStatus.UserCanceled:
                // The operation was cancelled by the user
                throw new UserCancelledException();

            case KeyCredentialStatus.UserPrefersPassword:
                // The user prefers a password
                throw new UserPrefersPasswordException();

            default:
                // An unknwon error occurred
                throw new UnknownException();
            }
        }
Пример #3
0
        public async Task <Result> SignInWithWindowsHelloAsync()
        {
            string userName = AppSettings.Current.UserName;

            if (IsWindowsHelloEnabled(userName))
            {
                var retrieveResult = await KeyCredentialManager.OpenAsync(userName);

                if (retrieveResult.Status == KeyCredentialStatus.Success)
                {
                    var credential      = retrieveResult.Credential;
                    var challengeBuffer = CryptographicBuffer.DecodeFromBase64String("challenge");
                    var result          = await credential.RequestSignAsync(challengeBuffer);

                    if (result.Status == KeyCredentialStatus.Success)
                    {
                        UpdateAuthenticationStatus(true);
                        return(Result.Ok());
                    }
                    return(Result.Error("Windows Hello", $"Cannot sign in with Windows Hello: {result.Status}"));
                }
                return(Result.Error("Windows Hello", $"Cannot sign in with Windows Hello: {retrieveResult.Status}"));
            }
            return(Result.Error("Windows Hello", "Windows Hello is not enabled for current user."));
        }
Пример #4
0
        public const int ERR_CREAT_KEY_EXISTS = 170; // Avoid reserved exit codes of UNIX

        static async Task <(int err, string pubKey)> CreatePublicKey(string key_name)
        {
            int err;
            var createRes = await KeyCredentialManager.RequestCreateAsync(key_name, KeyCredentialCreationOption.FailIfExists);

            IBuffer pubKey;

            if (createRes.Status == KeyCredentialStatus.CredentialAlreadyExists)
            {
                var existing = await KeyCredentialManager.OpenAsync(key_name);

                if (existing.Status != KeyCredentialStatus.Success)
                {
                    return(ERR_CREAT_FAIL, null);
                }
                err    = ERR_CREAT_KEY_EXISTS;
                pubKey = existing.Credential.RetrievePublicKey();
            }
            else if (createRes.Status != KeyCredentialStatus.Success)
            {
                return(ERR_CREAT_FAIL, null);
            }
            else
            {
                err    = 0;
                pubKey = createRes.Credential.RetrievePublicKey();
            }
            var pem = String.Format("-----BEGIN PUBLIC KEY-----\n{0}\n-----END PUBLIC KEY-----\n", CryptographicBuffer.EncodeToBase64String(pubKey));

            return(err, pem);
        }
Пример #5
0
        public static async Task <bool> UnlinkAccount(string userId)
        {
            var retrieveResult = await KeyCredentialManager.OpenAsync(userId);

            if (retrieveResult.Status != KeyCredentialStatus.Success)
            {
                return(false);
            }

            KeyCredential userCredential = retrieveResult.Credential;

            string publicKeyHint = CalculatePublicKeyHint(userCredential.RetrievePublicKey());

            var unlinkResult = await PlayFab.PlayFabClientAPI.UnlinkWindowsHelloAsync(new UnlinkWindowsHelloAccountRequest
            {
                PublicKeyHint = publicKeyHint
            });

            if (unlinkResult.Error != null)
            {
                MessageDialog message = new MessageDialog($"Error while un-linking: {unlinkResult.Error.Error} {unlinkResult.Error.ErrorMessage}");
                await message.ShowAsync();
            }

            return(unlinkResult.Error == null);
        }
Пример #6
0
        private async Task <bool> SignInWithHelloAsync()
        {
            LookupUser();

            // Open the existing user key credential.
            KeyCredentialRetrievalResult retrieveResult = await KeyCredentialManager.OpenAsync(userId);

            if (retrieveResult.Status != KeyCredentialStatus.Success)
            {
                return(false);
            }

            KeyCredential userCredential = retrieveResult.Credential;

            // Request a challenge from the server.
            JsonValue jsonChallenge = await JsonRequest.Create()
                                      .AddString("userId", userId)
                                      .AddString("publicKeyHint", publicKeyHint)
                                      .PostAsync("api/Authentication/RequestChallenge");

            if (jsonChallenge == null)
            {
                return(false);
            }

            // Sign the challenge using the user's KeyCredential.
            IBuffer challengeBuffer = CryptographicBuffer.DecodeFromBase64String(jsonChallenge.GetString());
            KeyCredentialOperationResult opResult = await userCredential.RequestSignAsync(challengeBuffer);

            if (opResult.Status != KeyCredentialStatus.Success)
            {
                return(false);
            }

            // Get the signature.
            IBuffer signatureBuffer = opResult.Result;

            // Send the signature back to the server to confirm our identity.
            // The publicKeyHint tells the server which public key to use to verify the signature.
            JsonValue jsonResult = await JsonRequest.Create()
                                   .AddString("userId", userId)
                                   .AddString("publicKeyHint", publicKeyHint)
                                   .AddString("signature", CryptographicBuffer.EncodeToBase64String(signatureBuffer))
                                   .PostAsync("api/Authentication/SubmitResponse");

            if (jsonResult == null)
            {
                return(false);
            }

            return(jsonResult.GetBoolean());
        }
Пример #7
0
        private async Task <IBuffer> GetPassportAuthenticationMessage(IBuffer message, string accountId)
        {
            KeyCredentialRetrievalResult openKeyResult = await KeyCredentialManager.OpenAsync(accountId);

            if (openKeyResult.Status == KeyCredentialStatus.Success)
            {
                KeyCredential userKey   = openKeyResult.Credential;
                IBuffer       publicKey = userKey.RetrievePublicKey();

                KeyCredentialOperationResult signResult = await userKey.RequestSignAsync(message);

                if (signResult.Status == KeyCredentialStatus.Success)
                {
                    return(signResult.Result);
                }
                else if (signResult.Status == KeyCredentialStatus.UserCanceled)
                {
                    // User cancelled the Passport PIN entry.
                    //
                    // We will return null below this and the username/password
                    // sign in form will show.
                }
                else if (signResult.Status == KeyCredentialStatus.NotFound)
                {
                    // Must recreate Passport key
                }
                else if (signResult.Status == KeyCredentialStatus.SecurityDeviceLocked)
                {
                    // Can't use Passport right now, remember that hardware failed and suggest restart
                }
                else if (signResult.Status == KeyCredentialStatus.UnknownError)
                {
                    // Can't use Passport right now, try again later
                }

                return(null);
            }
            else if (openKeyResult.Status == KeyCredentialStatus.NotFound)
            {
                // Passport key lost, need to recreate it
                //textblock_PassportStatusText.Text = "Microsoft Passport is almost ready!\nPlease go to Windows Settings and set up a PIN to use it.";
                //grid_PassportStatus.Background = new SolidColorBrush(Color.FromArgb(255, 50, 170, 207));
                //button_PassportSignIn.IsEnabled = false;

                m_passportAvailable = false;
            }
            else
            {
                // Can't use Passport right now, try again later
            }
            return(null);
        }
Пример #8
0
        public static async void RemovePassportAccountAsync(UserAccount account)
        {
            //Open the account with Windows Hello
            KeyCredentialRetrievalResult keyOpenResult = await KeyCredentialManager.OpenAsync(account.Username);

            if (keyOpenResult.Status == KeyCredentialStatus.Success)
            {
                // In the real world you would send key information to server to unregister
                AuthService.AuthService.Instance.PassportRemoveUser(account.UserId);
            }

            //Then delete the account from the machines list of Passport Accounts
            await KeyCredentialManager.DeleteAsync(account.Username);
        }
Пример #9
0
        /// <summary>
        /// Function to be called when user requests deleting their account.
        /// Checks the KeyCredentialManager to see if there is a Passport for the current user
        /// Then deletes the local key associated with the Passport.
        /// </summary>
        public static async void RemovePassportAccountAsync(Account account)
        {
            // Open the account with Passport
            KeyCredentialRetrievalResult keyOpenResult = await KeyCredentialManager.OpenAsync(account.Username);

            if (keyOpenResult.Status == KeyCredentialStatus.Success)
            {
                // In the real world you would send key information to server to unregister
                //e.g. RemovePassportAccountOnServer(account);
            }

            // Then delete the account from the machines list of Passport Accounts
            await KeyCredentialManager.DeleteAsync(account.Username);
        }
Пример #10
0
        /// <summary>
        /// Checks the KeyCredentialManager to see if there is a Passport for the current user and
        /// sends the informaton to the server to unregister it.
        ///
        /// Then deletes the local key associated with the Passport.
        /// </summary>
        private async void PassportDelete()
        {
            KeyCredentialRetrievalResult keyOpenResult = await KeyCredentialManager.OpenAsync(activeAccount.Email);

            if (keyOpenResult.Status == KeyCredentialStatus.Success)
            {
                var userKey   = keyOpenResult.Credential;
                var publicKey = userKey.RetrievePublicKey();

                // Send key information to server to unregister it
                DeletePassportServerSide();
            }

            await KeyCredentialManager.DeleteAsync(activeAccount.Email);
        }
Пример #11
0
        /// <summary>
        /// Attempts to sign a message using the Passport key on the system for the accountId passed.
        /// </summary>
        /// <param name="message">The message to be signed</param>
        /// <param name="accountId">The account id for the Passport key we are using to sign</param>
        /// <returns>Boolean representing if creating the Passport authentication message succeeded</returns>
        private async Task <IBuffer> GetPassportAuthenticationMessage(IBuffer message, string accountId)
        {
            KeyCredentialRetrievalResult openKeyResult = await KeyCredentialManager.OpenAsync(accountId);

            if (openKeyResult.Status == KeyCredentialStatus.Success)
            {
                KeyCredential userKey   = openKeyResult.Credential;
                IBuffer       publicKey = userKey.RetrievePublicKey();

                KeyCredentialOperationResult signResult = await userKey.RequestSignAsync(message);

                if (signResult.Status == KeyCredentialStatus.Success)
                {
                    return(signResult.Result);
                }
                else if (signResult.Status == KeyCredentialStatus.UserCanceled)
                {
                    // User cancelled the Passport PIN entry.
                    //
                    // We will return null below this and the username/password
                    // sign in form will show.
                }
                else if (signResult.Status == KeyCredentialStatus.NotFound)
                {
                    // Must recreate Passport key
                }
                else if (signResult.Status == KeyCredentialStatus.SecurityDeviceLocked)
                {
                    // Can't use Passport right now, remember that hardware failed and suggest restart
                }
                else if (signResult.Status == KeyCredentialStatus.UnknownError)
                {
                    // Can't use Passport right now, try again later
                }

                return(null);
            }
            else if (openKeyResult.Status == KeyCredentialStatus.NotFound)
            {
                // Passport key lost, need to recreate it
            }
            else
            {
                // Can't use Passport right now, try again later
            }
            return(null);
        }
        /// <summary>
        /// 认证用户授权
        /// </summary>
        /// <returns></returns>
        public static async Task <AuthenticatorState> VerifyUserAsync()
        {
            if (await CheckSupportAsync().ConfigureAwait(false))
            {
                if (ApplicationData.Current.LocalSettings.Values["WindowsHelloPublicKeyForUser"] is string PublicKey)
                {
                    KeyCredentialRetrievalResult RetrievalResult = await KeyCredentialManager.OpenAsync(CredentialName);

                    switch (RetrievalResult.Status)
                    {
                    case KeyCredentialStatus.Success:
                    {
                        KeyCredentialOperationResult OperationResult = await RetrievalResult.Credential.RequestSignAsync(CryptographicBuffer.ConvertStringToBinary(ChallengeText, BinaryStringEncoding.Utf8));

                        if (OperationResult.Status == KeyCredentialStatus.Success)
                        {
                            var Algorithm = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaSignPkcs1Sha256);
                            var Key       = Algorithm.ImportPublicKey(CryptographicBuffer.DecodeFromHexString(PublicKey));
                            return(CryptographicEngine.VerifySignature(Key, CryptographicBuffer.ConvertStringToBinary(ChallengeText, BinaryStringEncoding.Utf8), OperationResult.Result) ? AuthenticatorState.VerifyPassed : AuthenticatorState.VerifyFailed);
                        }
                        else
                        {
                            return(AuthenticatorState.UnknownError);
                        }
                    }

                    case KeyCredentialStatus.NotFound:
                    {
                        return(AuthenticatorState.CredentialNotFound);
                    }

                    default:
                    {
                        return(AuthenticatorState.UnknownError);
                    }
                    }
                }
                else
                {
                    return(AuthenticatorState.UserNotRegistered);
                }
            }
            else
            {
                return(AuthenticatorState.WindowsHelloUnsupport);
            }
        }
Пример #13
0
        public static async Task <bool> GetPassportAuthenticationMessageAsync(UserAccount account)
        {
            KeyCredentialRetrievalResult openKeyResult = await KeyCredentialManager.OpenAsync(account.Username);

            if (openKeyResult.Status == KeyCredentialStatus.Success)
            {
                return(true);
            }
            else if (openKeyResult.Status == KeyCredentialStatus.NotFound)
            {
                if (await CreatePassportKeyAsync(account.UserId, account.Username))
                {
                    return(await GetPassportAuthenticationMessageAsync(account));
                }
            }
            // Can't use Passport right now, try again later
            return(false);
        }
Пример #14
0
        /// <summary>
        /// Checks the KeyCredentialManager to see if there is a Passport for the current user and
        /// sends the informaton to the server to unregister it.
        ///
        /// Then deletes the local key associated with the Passport.
        /// </summary>
        private async void PassportDelete()
        {
            KeyCredentialRetrievalResult keyOpenResult = await KeyCredentialManager.OpenAsync(activeAccount.Email);

            if (keyOpenResult.Status == KeyCredentialStatus.Success)
            {
                var userKey   = keyOpenResult.Credential;
                var publicKey = userKey.RetrievePublicKey();

                // Send key information to server to unregister it
                DeletePassportServerSide();
            }

            await KeyCredentialManager.DeleteAsync(activeAccount.Email);

            rootPage.NotifyUser("User " + activeAccount.Email + " deleted.", NotifyType.StatusMessage);
            button_Forget.IsEnabled = false;
            button_Forget.Content   = "User Forgotten.";
        }
Пример #15
0
        public async void Load()
        {
            try
            {
                if (await KeyCredentialManager.IsSupportedAsync())
                {
                    var result = await KeyCredentialManager.OpenAsync(Helper.AppName);

                    if (result.Credential != null)
                    {
                        var signResult = await result.Credential.RequestSignAsync(CryptographicBuffer.ConvertStringToBinary(DeviceHelper.PackageName, BinaryStringEncoding.Utf8));

                        if (signResult.Status == KeyCredentialStatus.Success)
                        {
                            Unlock();
                        }
                        else
                        {
                            BiometricsButton.Visibility = Visibility.Visible;
                        }
                    }
                    else
                    {
                        var creationResult = await KeyCredentialManager.RequestCreateAsync(Helper.AppName, KeyCredentialCreationOption.ReplaceExisting);

                        if (creationResult.Status == KeyCredentialStatus.Success)
                        {
                            Unlock();
                        }
                        else
                        {
                            BiometricsButton.Visibility = Visibility.Visible;
                        }
                    }
                }
                else
                {
                    PassText.Focus(FocusState.Keyboard);
                }
            }
            catch { }
        }
Пример #16
0
        private async Task <byte[]> GetSignedKeyAsync(string keyPhrase)
        {
            var openKeyResult = await KeyCredentialManager.OpenAsync(AccountId);

            if (openKeyResult.Status == KeyCredentialStatus.Success)
            {
                var userKey = openKeyResult.Credential;
                var buffer  = CryptographicBuffer.ConvertStringToBinary(
                    keyPhrase, BinaryStringEncoding.Utf8
                    );

                var signResult = await userKey.RequestSignAsync(buffer);

                if (signResult.Status == KeyCredentialStatus.Success)
                {
                    return(signResult.Result.ToArray());
                }
            }
            return(null);
        }
Пример #17
0
        public static async Task <bool> RegisterWindowsHello(string userId)
        {
            // Check if the user already exists and if so log them in.
            KeyCredentialRetrievalResult retrieveResult = await KeyCredentialManager.OpenAsync(userId);

            if (retrieveResult.Status == KeyCredentialStatus.Success)
            {
                return(await SignInWithHelloAsync(userId, retrieveResult));
            }

            // Create the key credential with Passport APIs
            IBuffer publicKey = await CreatePassportKeyCredentialAsync(userId);

            if (publicKey != null)
            {
                // Register the public key and attestation of the key credential with the server
                // In a real-world scenario, this would likely also include:
                // - Certificate chain for attestation endorsement if available
                // - Status code of the Key Attestation result : Included / retrieved later / retry type
                if (await RegisterPassportCredentialWithServerAsync(publicKey, userId))
                {
                    // Remember that this is the user whose credentials have been registered
                    // with the server.
                    ApplicationData.Current.LocalSettings.Values["userId"] = userId;

                    // Registration successful. Continue to the signed-in state.
                    return(true);
                }
                else
                {
                    // Delete the failed credentials from the device.
                    await Util.TryDeleteCredentialAccountAsync(userId);

                    MessageDialog message = new MessageDialog("Failed to register with the server.");
                    await message.ShowAsync();
                }
            }

            return(false);
        }
Пример #18
0
        /// <summary>
        /// Attempts to sign a message using the Passport key on the system for the accountId passed.
        /// </summary>
        /// <returns>Boolean representing if creating the Passport authentication message succeeded</returns>
        public static async Task <bool> GetPassportAuthenticationMessageAsync(Account account)
        {
            KeyCredentialRetrievalResult openKeyResult = await KeyCredentialManager.OpenAsync(account.Username);

            // Calling OpenAsync will allow the user access to what is available in the app and will not require user credentials again.
            // If you wanted to force the user to sign in again you can use the following:
            // var consentResult = await Windows.Security.Credentials.UI.UserConsentVerifier.RequestVerificationAsync(account.Username);
            // This will ask for the either the password of the currently signed in Microsoft Account or the PIN used for Microsoft Passport.

            if (openKeyResult.Status == KeyCredentialStatus.Success)
            {
                // If OpenAsync has succeeded, the next thing to think about is whether the client application requires access to backend services.
                // If it does here you would Request a challenge from the Server. The client would sign this challenge and the server
                // would check the signed challenge. If it is correct it would allow the user access to the backend.
                // You would likely make a new method called RequestSignAsync to handle all this
                // e.g. RequestSignAsync(openKeyResult);
                // Refer to the second Microsoft Passport sample for information on how to do this.

                // For this sample there is not concept of a server implemented so just return true.
                return(true);
            }
            else if (openKeyResult.Status == KeyCredentialStatus.NotFound)
            {
                // If the _account is not found at this stage. It could be one of two errors.
                // 1. Microsoft Passport has been disabled
                // 2. Microsoft Passport has been disabled and re-enabled cause the Microsoft Passport Key to change.
                // Calling CreatePassportKey and passing through the account will attempt to replace the existing Microsoft Passport Key for that account.
                // If the error really is that Microsoft Passport is disabled then the CreatePassportKey method will output that error.
                if (await CreatePassportKeyAsync(account.Username))
                {
                    // If the Passport Key was again successfully created, Microsoft Passport has just been reset.
                    // Now that the Passport Key has been reset for the _account retry sign in.
                    return(await GetPassportAuthenticationMessageAsync(account));
                }
            }

            // Can't use Passport right now, try again later
            return(false);
        }
Пример #19
0
        private async void Biometrics_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var result = await KeyCredentialManager.OpenAsync(Strings.Resources.AppName);

                if (result.Credential != null)
                {
                    var signResult = await result.Credential.RequestSignAsync(CryptographicBuffer.ConvertStringToBinary(Package.Current.Id.Name, BinaryStringEncoding.Utf8));

                    if (signResult.Status == KeyCredentialStatus.Success)
                    {
                        Unlock();
                    }
                    else
                    {
                        Field.Focus(FocusState.Keyboard);
                    }
                }
                else
                {
                    var creationResult = await KeyCredentialManager.RequestCreateAsync(Strings.Resources.AppName, KeyCredentialCreationOption.ReplaceExisting);

                    if (creationResult.Status == KeyCredentialStatus.Success)
                    {
                        Unlock();
                    }
                    else
                    {
                        Field.Focus(FocusState.Keyboard);
                    }
                }
            }
            catch
            {
                Field.Focus(FocusState.Keyboard);
            }
        }
Пример #20
0
        public async Task <bool> AuthenticateAsync()
        {
            // Waits that the app's window gets the focus. This allows to avoid having the icon in the task bar
            // blinking orange when windows hello starts. It might distracts the user.
            await _windowFocusAwaiter.Task.ConfigureAwait(false);

            if (!await IsWindowsHelloEnabledAsync()
                .ConfigureAwait(true)) // run on the current context.
            {
                _logger.LogEvent(AuthenticateEvent, "Success == False; Windows Hello isn't enabled.");
                return(false);
            }

            // Get credentials for current user and app
            KeyCredentialRetrievalResult result = await KeyCredentialManager.OpenAsync(KeyCredentialManagerName);

            if (result.Credential != null)
            {
                // Prompt the user to authenticate.
                KeyCredentialOperationResult signResult = await result.Credential.RequestSignAsync(CryptographicBuffer.ConvertStringToBinary(KeyCredentialManagerName, BinaryStringEncoding.Utf8));

                if (signResult.Status == KeyCredentialStatus.Success)
                {
                    _logger.LogEvent(AuthenticateEvent, "Success == True");
                    return(true);
                }

                _logger.LogEvent(AuthenticateEvent, "Success == False");
                return(false);
            }

            // No previous saved credentials found, let's create them (this will also prompt the user to authenticate).
            KeyCredentialRetrievalResult creationResult = await KeyCredentialManager.RequestCreateAsync(KeyCredentialManagerName, KeyCredentialCreationOption.ReplaceExisting);

            _logger.LogEvent(AuthenticateEvent, $"Success == {creationResult.Status == KeyCredentialStatus.Success}");
            return(creationResult.Status == KeyCredentialStatus.Success);
        }
        private static async Task <bool> AuthenticateUsingWindowsHello()
        {
            if (await KeyCredentialManager.IsSupportedAsync())
            {
                // Get credentials for current user and app
                var result = await KeyCredentialManager.OpenAsync("GitIt-Hello");

                if (result.Credential != null)
                {
                    var signResult =
                        await result.Credential.RequestSignAsync(CryptographicBuffer.ConvertStringToBinary("LoginAuth",
                                                                                                           BinaryStringEncoding.Utf8));

                    return(signResult.Status == KeyCredentialStatus.Success);
                }

                // If no credentials found create one
                var creationResult = await KeyCredentialManager.RequestCreateAsync("GitIt-Hello",
                                                                                   KeyCredentialCreationOption.ReplaceExisting);

                return(creationResult.Status == KeyCredentialStatus.Success);
            }
            return(false);
        }
Пример #22
0
 /// <summary>
 /// Opens a Microsoft Key credential.
 /// </summary>
 /// <param name="credentialName">Name of the credential to be opened.</param>
 /// <returns>KeyCredentialRetrievalResult object with all the information.</returns>
 internal static async Task <KeyCredentialRetrievalResult> OpenCredential(string credentialName)
 {
     return(await KeyCredentialManager.OpenAsync(credentialName));
 }
Пример #23
0
        /// <summary>
        /// Get the public key of the windiws hello account
        /// </summary>
        /// <param name="accountId">The id of the account to use</param>
        /// <exception cref="UserCancelledException"></exception>
        /// <exception cref="AccountNotFoundException"></exception>
        /// <exception cref="UnknownException"></exception>
        /// <exception cref="AggregateException"></exception>
        /// <returns>A passport result, storing the public key in its buffer</returns>
        public static byte[] GetPublicKey(string accountId)
        {
            // Try to get the account
            Task <KeyCredentialRetrievalResult> task            = Task.Run(async() => await KeyCredentialManager.OpenAsync(accountId));
            KeyCredentialRetrievalResult        retrievalResult = task.Result;

            // Check the KeyCredentialRetrievalResult status
            switch (retrievalResult.Status)
            {
            case KeyCredentialStatus.Success:
                // Get the user's credential
                KeyCredential userCredential = retrievalResult.Credential;

                // Get the public key
                IBuffer publicKey = userCredential.RetrievePublicKey();

                // Copy the public key to the PassportResult's buffer
                CryptographicBuffer.CopyToByteArray(publicKey, out byte[] buffer);

                // The operation was successful
                return(buffer);

            case KeyCredentialStatus.UserCanceled:
                // User cancelled the Passport enrollment process
                throw new UserCancelledException();

            case KeyCredentialStatus.NotFound:
                // The account was not found
                throw new AccountNotFoundException();

            default:
                // An unknown error occurred
                throw new UnknownException();
            }
        }
Пример #24
0
        public static async Task <bool> SignInWithHelloAsync(string userId, KeyCredentialRetrievalResult retrieveResult = null)
        {
            // Open the existing user key credential.
            if (retrieveResult == null)
            {
                retrieveResult = await KeyCredentialManager.OpenAsync(userId);
            }

            if (retrieveResult.Status != KeyCredentialStatus.Success)
            {
                return(false);
            }

            KeyCredential userCredential = retrieveResult.Credential;

            string publicKeyHint = CalculatePublicKeyHint(userCredential.RetrievePublicKey());

            var challengeResult = await PlayFab.PlayFabClientAPI.GetWindowsHelloChallengeAsync(new GetWindowsHelloChallengeRequest
            {
                PublicKeyHint = publicKeyHint,
                TitleId       = PlayFab.PlayFabSettings.TitleId
            });

            if (challengeResult.Error != null)
            {
                // TODO: Failed to get a challenge, handle the error
                MessageDialog message = new MessageDialog($"Error during getting challenge: {challengeResult.Error.Error}");
                await message.ShowAsync();

                return(false);
            }

            // Sign the challenge using the user's KeyCredential.
            IBuffer challengeBuffer = CryptographicBuffer.DecodeFromBase64String(challengeResult.Result.Challenge);
            KeyCredentialOperationResult opResult = await userCredential.RequestSignAsync(challengeBuffer);

            if (opResult.Status != KeyCredentialStatus.Success)
            {
                MessageDialog message = new MessageDialog("Failed to have user sign the challenge string.");
                await message.ShowAsync();

                return(false);
            }

            // Get the signature.
            IBuffer signatureBuffer = opResult.Result;

            // Send the signature back to the server to confirm our identity.
            // The publicKeyHint tells the server which public key to use to verify the signature.
            var loginResult = await PlayFab.PlayFabClientAPI.LoginWithWindowsHelloAsync(new LoginWithWindowsHelloRequest
            {
                ChallengeSignature = CryptographicBuffer.EncodeToBase64String(signatureBuffer),
                PublicKeyHint      = publicKeyHint
            });

            if (loginResult.Error != null)
            {
                MessageDialog message = new MessageDialog($"Error during login: {loginResult.Error.Error}");
                await message.ShowAsync();

                return(false);
            }

            return(true);
        }
Пример #25
0
        private async void Path_Auth()
        {
            // check if KeyCredentialManager can be used
            if (await KeyCredentialManager.IsSupportedAsync() == false)
            {
                await(new MessageDialog("KeyCredentialManager not supported")).ShowAsync();
                return;
            }

            // retrieve private key for sign
            KeyCredentialRetrievalResult res =
                await KeyCredentialManager.OpenAsync("key1");

            if (res.Status == KeyCredentialStatus.Success)
            {
                //
                // If it is present, we request sign for some data
                //

                // convert string to binary buffer
                var inputbuf =
                    CryptographicBuffer.ConvertStringToBinary(
                        "Test Data 1", BinaryStringEncoding.Utf8);

                // sign using retrieved private key
                // (Windows Hello is diplayed here !)
                KeyCredentialOperationResult signRes = await res.Credential.RequestSignAsync(inputbuf);

                //KeyCredentialAttestationResult signRes = await res.Credential.GetAttestationAsync();

                /*
                 * // get the base64 encoded data to cryptographically sign
                 * string base64encSignature =
                 * CryptographicBuffer.EncodeToBase64String(signRes.Result);
                 * await (new MessageDialog(base64encSignature)).ShowAsync();
                 */
                if (signRes.Status == KeyCredentialStatus.Success)
                {
                    // ナビゲーション フレームを使用して前のページに戻ります
                    if (this.Frame != null && this.Frame.CanGoBack)
                    {
                        this.Frame.GoBack();
                    }
                    else if (this.Frame != null)
                    {
                        //this.Frame.Navigate(typeof(Browser.MainBrowser));
                        this.Frame.Navigate(typeof(Browser.Browser1));
                    }
                }
                else
                {
                    // get the base64 encoded data to cryptographically sign
                    //string base64encSignature = CryptographicBuffer.EncodeToBase64String(signRes.Result);
                    await(new MessageDialog("キャンセルしました")).ShowAsync();
                    //await (new MessageDialog(base64encSignature)).ShowAsync();
                }
            }
            else if (res.Status == KeyCredentialStatus.NotFound)
            {
                //
                // If the credential is not found, we create it.
                //

                // Create the credential
                // (Windows Hello is diplayed here !)
                KeyCredentialRetrievalResult createRes =
                    await KeyCredentialManager.RequestCreateAsync("key1",
                                                                  KeyCredentialCreationOption.ReplaceExisting);

                if (createRes.Status == KeyCredentialStatus.Success)
                {
                    // ナビゲーション フレームを使用して前のページに戻ります
                    if (this.Frame != null && this.Frame.CanGoBack)
                    {
                        this.Frame.GoBack();
                    }
                    else if (this.Frame != null)
                    {
                        //this.Frame.Navigate(typeof(Browser.MainBrowser));
                        this.Frame.Navigate(typeof(Browser.Browser1));
                    }
                }
                else
                {
                    // get the base64 encoded data to cryptographically sign
                    //string base64encSignature = CryptographicBuffer.EncodeToBase64String(signRes.Result);
                    await(new MessageDialog("キャンセルしました")).ShowAsync();
                    //await (new MessageDialog(base64encSignature)).ShowAsync();
                }

                /*
                 * // if the status is success, retrieve the public key.
                 * if (createRes.Status == KeyCredentialStatus.Success)
                 * {
                 * var pubKey = createRes.Credential.RetrievePublicKey();
                 * AsymmetricKeyAlgorithmProvider alg =
                 *  AsymmetricKeyAlgorithmProvider.OpenAlgorithm(
                 *    AsymmetricAlgorithmNames.RsaPkcs1);
                 * CryptographicKey ckey = alg.ImportPublicKey(pubKey);
                 * // for ex, CryptographicEngine.VerifySignature() using this CryptographicKey
                 * // (This time, just showing the keysize)
                 * var dialog = new MessageDialog(string.Format("Key size is {0}", ckey.KeySize));
                 * await dialog.ShowAsync();
                 * }
                 */
            }
            else
            {
                await(new MessageDialog("Unknown error !")).ShowAsync();
            }
        }
Пример #26
0
        /// <summary>
        /// Sign a challenge using windows hello
        /// </summary>
        /// <param name="accountId">The id of the account to use</param>
        /// <param name="challenge">The challenge to sign</param>
        /// <exception cref="SignOperationFailedException"></exception>
        /// <exception cref="UserCancelledException"></exception>
        /// <exception cref="AccountNotFoundException"></exception>
        /// <exception cref="UnknownException"></exception>
        /// <exception cref="AggregateException"></exception>
        /// <returns>A passport result, storing the signed challenge in its buffer</returns>
        public static byte[] PassportSign(string accountId, byte[] challenge)
        {
            // Try to open the account
            Task <KeyCredentialRetrievalResult> task           = Task.Run(async() => await KeyCredentialManager.OpenAsync(accountId));
            KeyCredentialRetrievalResult        retrieveResult = task.Result;

            // Check the KeyCredentialRetrievalResult status
            switch (retrieveResult.Status)
            {
            case KeyCredentialStatus.Success:
                // Get the users credential
                KeyCredential userCredential = retrieveResult.Credential;

                // Convert the challenge to an IBuffer and sign the challenge
                IBuffer challengeBuffer = CryptographicBuffer.CreateFromByteArray(challenge);
                Task <KeyCredentialOperationResult> opTask = Task.Run(async() =>
                                                                      await userCredential.RequestSignAsync(challengeBuffer));
                KeyCredentialOperationResult opResult = opTask.Result;

                // Check the KeyCredentialOperationResult status
                if (opResult.Status == KeyCredentialStatus.Success)
                {
                    // Get the signature
                    IBuffer signatureBuffer = opResult.Result;

                    // Copy the signature to the PassportResult's buffer
                    CryptographicBuffer.CopyToByteArray(signatureBuffer, out byte[] buffer);
                    // The operation was successful
                    return(buffer);
                }
                else
                {
                    // The sign operation failed
                    throw new SignOperationFailedException();
                }

            case KeyCredentialStatus.UserCanceled:
                // User cancelled the Passport enrollment process
                throw new UserCancelledException();

            case KeyCredentialStatus.NotFound:
                // The account was not found
                throw new AccountNotFoundException();

            default:
                // An unknown error occurred
                throw new UnknownException();
            }
        }
        /// <summary>
        /// Retrieve the password to use to open the given database
        /// </summary>
        /// <param name="databaseName">name of the database</param>
        /// <returns>credentials to use to open this database</returns>
        public async static Task <PasswordParameter> GetDatabasePasswordAsync(string databaseName)
        {
            PasswordParameter credentials = null;

            // Try to use Windows Hello
            if (SettingsViewModel.Instance.WindowsHelloEnabled &&
                await KeyCredentialManager.IsSupportedAsync()
                )
            {
                // Try to open an already generated Windows Hello credentials
                var passportCredentials = await KeyCredentialManager.OpenAsync(WINDOWS_HELLO_SERVICE_NAME);

                if (passportCredentials.Status == KeyCredentialStatus.Success)
                {
                    var signRes = await passportCredentials.Credential.RequestSignAsync(
                        CryptographicBuffer.ConvertStringToBinary("LoginAuth", BinaryStringEncoding.Utf8));

                    if (signRes.Status == KeyCredentialStatus.Success)
                    {
                        // User confirmed its identity, retrieve the credentials from the system Password Vault
                        try
                        {
                            credentials = await LoadDatabasePasswordAsync(databaseName);
                        }
                        catch (Exception)
                        {
                            // Prompt for credentials, then store them
                            PasswordParameter password = await ShowPasswordDialogAsync(databaseName);

                            StoreDatabasePassword(databaseName, password);
                            credentials = password;
                        }
                    }
                    else if (signRes.Status == KeyCredentialStatus.UserCanceled)
                    {
                        // User cancelled the credential
                        throw new TaskCanceledException();
                    }
                }
                else
                {
                    // No credentials available, need to create it
                    var passportCredentialCreation = await KeyCredentialManager.RequestCreateAsync(WINDOWS_HELLO_SERVICE_NAME, KeyCredentialCreationOption.FailIfExists);

                    if (passportCredentialCreation.Status == KeyCredentialStatus.Success ||
                        passportCredentialCreation.Status == KeyCredentialStatus.CredentialAlreadyExists)
                    {
                        // Prompt for credentials, then store them
                        PasswordParameter password = await ShowPasswordDialogAsync(databaseName);

                        StoreDatabasePassword(databaseName, password);
                        credentials = password;
                    }
                    else if (passportCredentialCreation.Status == KeyCredentialStatus.UserCanceled)
                    {
                        // User cancelled the credential
                        throw new TaskCanceledException();
                    }
                }
            }

            if (credentials == null)
            {
                // No Windows Hello, use standard password
                credentials = await ShowPasswordDialogAsync(databaseName);
            }
            return(credentials);
        }