public static KeyType DeriveNewKey(string sSha) { NBitcoin.Mnemonic m = new NBitcoin.Mnemonic(sSha); ExtKey k = m.DeriveExtKey(null); KeyType k1 = new KeyType(); k1.PrivKey = k.PrivateKey.GetWif(Network.BiblepayTest).ToWif().ToString(); k1.PubKey = k.ScriptPubKey.GetDestinationAddress(Network.BiblepayTest).ToString(); return(k1); }
private void ProvisionCardButton_Click(object sender, RoutedEventArgs e) { CreateKeyErrorLabel.Content = ""; CreatingKeyLabel.Content = ""; if (passphrase.Password.Length == 0 || passphraseConfirmation.Password.Length == 0) { CreateKeyErrorLabel.Content = "A passphrase was not entered."; return; } if (passphrase.Password != passphraseConfirmation.Password) { CreateKeyErrorLabel.Content = "Passphrases entered did not match."; return; } if (PrivateKeyTextBox.Text.Length == 0) { CreateKeyErrorLabel.Content = "No private key data to store."; return; } if (CardPkType == PKType.BTC || CardPkType == PKType.BTC_TestNet) { // Check if we are importing a user's wif or mnemonic, update public key field // to allow the user to confirm if (CardGeneratedKey.GetBitcoinSecret(Network).ToWif() != PrivateKeyTextBox.Text) { try { NBitcoin.Key importedKey = null; int spacesDetected = PrivateKeyTextBox.Text.Count(a => a == ' '); // Check for mnemonic if (spacesDetected >= 11) { NBitcoin.Mnemonic mnemonic = new NBitcoin.Mnemonic(PrivateKeyTextBox.Text); // Force bitcoin and first address importedKey = mnemonic.DeriveExtKey().Derive(KeyPath.Parse("m/44'/0'/0'/0/0")).PrivateKey; } else { // Check for wif importedKey = NBitcoin.Key.Parse(PrivateKeyTextBox.Text); } // Replace CardGeneratedKey with imported key. Only valid for bitcoin addresses. CardGeneratedKey = importedKey; PublicKeyTextBox.Text = importedKey.PubKey.GetAddress(Network).ToString(); PrivateKeyTextBox.Text = importedKey.GetBitcoinSecret(Network).ToWif(); CreatingKeyLabel.Content = "Key data imported, ready to setup your bChip."; return; } catch (Exception ex) { Logger.Log(ex); CreateKeyErrorLabel.Content = "Failed to automatically parse private key data."; return; } } } byte[] privateKeyToEncrypt = null; byte[] publicKeyData = null; if (CardGeneratedKey != null) { // Users can optionally remove the public key portion, so we'll skip saving it. if (PublicKeyTextBox.Text.Length > 0) { publicKeyData = CardGeneratedKey.PubKey.ToBytes(); } byte[] privateKeyBytes = CardGeneratedKey.GetWif(Network.Main).ToBytes(); // Always seem to get an extra bit at the end... if (privateKeyBytes.Length == 33 && privateKeyBytes[32] == 0x1) { privateKeyToEncrypt = privateKeyBytes.Take(32).ToArray(); } else { privateKeyToEncrypt = privateKeyBytes; } } else { if (PublicKeyTextBox.Text.Length > 0) { publicKeyData = CryptographicBuffer.ConvertStringToBinary(PublicKeyTextBox.Text, BinaryStringEncoding.Utf8).ToArray(); } privateKeyToEncrypt = CryptographicBuffer.ConvertStringToBinary(PrivateKeyTextBox.Text, BinaryStringEncoding.Utf8).ToArray(); } 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; } if (publicKeyData != null) { if (publicKeyData.Length > BChipMemoryLayout_BCHIP.PUBKEY_MAX_DATA) { CreateKeyErrorLabel.Content = $"Public key was {PublicKeyTextBox.Text.Length} bytes, {Math.Abs(PublicKeyTextBox.Text.Length - BChipMemoryLayout_BCHIP.PUBKEY_MAX_DATA)} bytes over the limit."; return; } } string friendlyName = FriendlyNameTextBox.Text; ProvisionNewKeysViewGrid.Dispatcher.BeginInvoke(new Action(() => { ProvisionNewKeysViewGrid.IsEnabled = false; })); Task.Run(new Action(() => { try { UpdateTextLabel(CreatingKeyLabel, "Setting up bChip! Do not remove card."); // Encrypt data BChipMemoryLayout_BCHIP bchip = LoadedBChips.SmartCardData as BChipMemoryLayout_BCHIP; bchip.EncryptPrivateKeyData(CardPkType, passphrase.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(CreatingKeyLabel, ""); UpdateTextLabel(CreateKeyErrorLabel, "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.StatusWord != 0x00009000) { UpdateTextLabel(CreatingKeyLabel, ""); UpdateTextLabel(CreateKeyErrorLabel, "Failure writing data to the bchip."); return; } } } UpdateTextLabel(CreatingKeyLabel, string.Empty); ClearTextBox(FriendlyNameTextBox); // Done? clear loaded card, reload card LoadedBChips = null; ChangePageUi(PageToShow.NoCard, null); ScanAndLoadConnectedCards(); } catch (Exception ex) { Logger.Log(ex); } finally { ProvisionNewKeysViewGrid.Dispatcher.BeginInvoke(new Action(() => { ProvisionNewKeysViewGrid.IsEnabled = true; })); } })); }