예제 #1
0
        public string DecryptedPrivateKeyString(string passphrase)
        {
            byte[] decryptedKey = this.DecryptPrivateKeyData(passphrase);

            if (decryptedKey == null)
            {
                //Nothing to decrypt?
                return("");
            }

            string privateKey;

            Key key = null;

            switch (this.PkType)
            {
            case PKType.BTC:
                key        = new Key(decryptedKey);
                privateKey = key.GetWif(Network.Main).ToWif();
                break;

            case PKType.BTC_TestNet:
                key        = new Key(decryptedKey);
                privateKey = key.GetWif(Network.TestNet).ToWif();
                break;

            // Generic failsafe, no parsing/validation
            case PKType.UNSET:
            case PKType.ETH:
            case PKType.CUSTOM:
            default:
                privateKey = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, decryptedKey.AsBuffer());
                break;

            case PKType.Mnemonic:
                // TODO: Hardcoded to english, can add integrated OS detection or drop down for multilang
                string[]      words    = BIP39Helpers.DecodeMnemonicFromEntropy(decryptedKey, Wordlist.English);
                StringBuilder wordList = new StringBuilder();
                foreach (string word in words)
                {
                    wordList.Append($" {word}");
                }
                privateKey = wordList.ToString();
                break;
            }

            return(privateKey);
        }
예제 #2
0
        private void MnemonicProvisionCardButton_Click(object sender, RoutedEventArgs e)
        {
            MnemonicErrorLabel.Content = "";
            MnemonicKeyLabel.Content   = "";

            if (Mnemonicpassphrase.Password.Length == 0 || MnemonicpassphraseConfirmation.Password.Length == 0)
            {
                MnemonicErrorLabel.Content = "A passphrase was not entered.";
                return;
            }

            if (Mnemonicpassphrase.Password != MnemonicpassphraseConfirmation.Password)
            {
                MnemonicErrorLabel.Content = "Passphrases entered did not match.";
                return;
            }

            if (MnemonicEntryTextBox.Text.Length == 0)
            {
                MnemonicErrorLabel.Content = "No private key data to store.";
                return;
            }

            if (CardPkType != PKType.Mnemonic)
            {
                MnemonicErrorLabel.Content = "Invalid application state. Please restart app.";
                return;
            }

            byte[] privateKeyToEncrypt = null;
            byte[] publicKeyData       = CryptographicBuffer.ConvertStringToBinary("Mnemonic seed backed up.", BinaryStringEncoding.Utf8).ToArray();

            try
            {
                privateKeyToEncrypt = BIP39Helpers.GenerateEntropyFromWords(MnemonicEntryTextBox.Text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries), NBitcoin.Wordlist.English);
            }
            // TODO: Implement better exception types to ease debugging
            catch (Exception ex)
            {
                Logger.Log(ex);
                MnemonicErrorLabel.Content = "Failed to automatically parse mnemonic phrase.";
                return;
            }

            if (privateKeyToEncrypt.Length > BChipMemoryLayout_BCHIP.PRIVATEKEY_MAX_DATA)
            {
                CreateKeyErrorLabel.Content =
                    $"Private key was {PrivateKeyTextBox.Text.Length} bytes, {Math.Abs(PrivateKeyTextBox.Text.Length - BChipMemoryLayout_BCHIP.PRIVATEKEY_MAX_DATA)} bytes over the limit.";
                return;
            }

            string friendlyName = MnemonicFriendlyNameTextBox.Text;

            ProvisionMnemonicPhraseViewGrid.Dispatcher.BeginInvoke(new Action(() =>
            {
                ProvisionMnemonicPhraseViewGrid.IsEnabled = false;
            }));

            Task.Run(new Action(() =>
            {
                try
                {
                    UpdateTextLabel(MnemonicKeyLabel, "Setting up bChip! Do not remove card.");

                    // Encrypt data
                    BChipMemoryLayout_BCHIP bchip = LoadedBChips.SmartCardData as BChipMemoryLayout_BCHIP;
                    bchip.EncryptPrivateKeyData(CardPkType, Mnemonicpassphrase.Password, privateKeyToEncrypt, publicKeyData);
                    bchip.SetFriendlyName(friendlyName);

                    using (var context = _contextFactory.Establish(SCardScope.System))
                    {
                        using (var isoReader = new IsoReader(context, LoadedBChips.ReaderName, SCardShareMode.Shared, SCardProtocol.Any))
                        {
                            if (LoadedBChips.AdpuInterface.RequiresInit)
                            {
                                Response initResponse = isoReader.Transmit(LoadedBChips.AdpuInterface.InitCard());
                                if (initResponse.SW1 != 0x90)
                                {
                                    Logger.Log("Error initializing smart card reader");
                                }
                            }

                            var unlockResponse = isoReader.Transmit(LoadedBChips.AdpuInterface.UnblockCard());
                            Logger.Log($"ADPU response from pin request: {unlockResponse.StatusWord:X}");
                            if (unlockResponse.SW1 != 0x90)
                            {
                                UpdateTextLabel(MnemonicKeyLabel, "");
                                UpdateTextLabel(MnemonicErrorLabel, "Could not be unlock bchip for writing.");
                                return;
                            }
                            var writeResponse = isoReader.Transmit(LoadedBChips.AdpuInterface.WriteCard(bchip));
                            Logger.Log($"ADPU response from write card data: {unlockResponse.StatusWord:X}");
                            if (writeResponse.SW1 != 0x90)
                            {
                                UpdateTextLabel(MnemonicKeyLabel, "");
                                UpdateTextLabel(MnemonicErrorLabel, "Failure writing data to the bchip.");
                                return;
                            }
                        }
                    }

                    UpdateTextLabel(MnemonicKeyLabel, string.Empty);
                    ClearTextBox(MnemonicFriendlyNameTextBox);

                    // Done? clear loaded card, reload card
                    LoadedBChips = null;
                    ScanAndLoadConnectedCards();
                }
                catch (Exception ex)
                {
                    Logger.Log(ex);
                }
                finally
                {
                    ProvisionMnemonicPhraseViewGrid.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        ProvisionMnemonicPhraseViewGrid.IsEnabled = true;
                    }));
                }
            }));
        }