/*
*
* Copyright 2014 http://Bither.net
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* /
*/
package net.bither.viewsystem.froms;
import net.bither.Bither;
import net.bither.bitherj.BitherjSettings;
import net.bither.bitherj.core.Address;
import net.bither.bitherj.core.AddressManager;
import net.bither.bitherj.core.HDMKeychain;
import net.bither.bitherj.crypto.ECKey;
import net.bither.bitherj.crypto.EncryptedData;
import net.bither.bitherj.crypto.SecureCharSequence;
import net.bither.bitherj.crypto.bip38.Bip38;
import net.bither.bitherj.exception.AddressFormatException;
import net.bither.bitherj.factory.ImportHDSeed;
import net.bither.bitherj.factory.ImportPrivateKey;
import net.bither.bitherj.qrcode.QRCodeUtil;
import net.bither.bitherj.utils.PrivateKeyUtil;
import net.bither.bitherj.utils.Utils;
import net.bither.factory.ImportHDSeedDesktop;
import net.bither.factory.ImportListener;
import net.bither.factory.ImportPrivateKeyDesktop;
import net.bither.fonts.AwesomeIcon;
import net.bither.languages.MessageKey;
import net.bither.preference.UserPreference;
import net.bither.qrcode.IReadQRCode;
import net.bither.qrcode.IScanQRCode;
import net.bither.qrcode.SelectQRCodePanel;
import net.bither.qrcode.SelectTransportQRCodePanel;
import net.bither.utils.KeyUtil;
import net.bither.utils.LocaliserUtils;
import net.bither.viewsystem.base.Buttons;
import net.bither.viewsystem.base.Panels;
import net.bither.viewsystem.dialogs.DialogProgress;
import net.bither.viewsystem.dialogs.ImportBIP38PrivateTextDialog;
import net.bither.viewsystem.dialogs.ImportPrivateTextDialog;
import net.bither.viewsystem.dialogs.MessageDialog;
import net.bither.viewsystem.listener.ICheckPasswordListener;
import net.bither.viewsystem.listener.IDialogPasswordListener;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.util.List;
public class ImportPrivateKeyPanel extends WizardPanel {
private JButton btnQRCode;
private JButton btnBIP38QRCode;
private JButton btnPrivateKey;
private JButton btnBIP38;
private JButton btnHDMColdSeed;
private JButton btnHDMColdPhras;
private JButton btnHDAccountSeed;
private JButton btnHDAccountPhras;
private String bip38DecodeString;
private JButton btnClone;
private DialogProgress dp;
public ImportPrivateKeyPanel() {
super(MessageKey.IMPORT, AwesomeIcon.FA_SIGN_IN);
dp = new DialogProgress();
}
@Override
public void initialiseContent(JPanel panel) {
panel.setLayout(new MigLayout(
Panels.migXYLayout(),
"[][][][][]", // Column constraints
"[][][][][][][][][][][]" // Row constraints
));
btnQRCode = Buttons.newQRCodeButton(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
closePanel();
onQRCode();
}
}, MessageKey.IMPORT_PRIVATE_KEY_QRCODE);
btnPrivateKey = Buttons.newFileTextButton(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
closePanel();
importPrivateText();
}
}, MessageKey.IMPORT_PRIVATE_KEY_TEXT);
btnBIP38QRCode = Buttons.newQRCodeButton(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
closePanel();
onBIP38QRCode();
}
}, MessageKey.IMPORT_BIP38_PRIVATE_KEY_QRCODE);
btnBIP38 = Buttons.newFileTextButton(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
closePanel();
ImportBIP38PrivateTextDialog importBIP38PrivateTextDialog = new ImportBIP38PrivateTextDialog();
importBIP38PrivateTextDialog.pack();
importBIP38PrivateTextDialog.setVisible(true);
}
}, MessageKey.IMPORT_BIP38_PRIVATE_KEY_TEXT);
btnHDMColdSeed = Buttons.newNormalButton(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
closePanel();
onColdSeedQRCode();
}
}, MessageKey.import_hdm_cold_seed_qr_code, AwesomeIcon.QRCODE);
btnHDMColdPhras = Buttons.newNormalButton(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
closePanel();
RestoreWalletSeedPhrasePanel restoreWalletSeedPhrasePanel = new RestoreWalletSeedPhrasePanel(ImportHDSeed.ImportHDSeedType.HDMColdPhrase);
restoreWalletSeedPhrasePanel.showPanel();
}
}, MessageKey.import_hdm_cold_seed_phrase, AwesomeIcon.BITBUCKET);
btnHDAccountSeed = Buttons.newNormalButton(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
closePanel();
onHDAccountSeedQRCode();
}
}, MessageKey.import_hd_account_seed_qr_code, AwesomeIcon.QRCODE);
btnHDAccountPhras = Buttons.newNormalButton(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
closePanel();
RestoreWalletSeedPhrasePanel restoreWalletSeedPhrasePanel = new RestoreWalletSeedPhrasePanel(ImportHDSeed.ImportHDSeedType.HDSeedPhrase);
restoreWalletSeedPhrasePanel.showPanel();
}
}, MessageKey.import_hd_account_seed_phrase, AwesomeIcon.BITBUCKET);
btnClone = Buttons.newNormalButton(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
SelectTransportQRCodePanel selectTransportQRCodePanel = new SelectTransportQRCodePanel(new IScanQRCode() {
@Override
public void handleResult(String result, IReadQRCode readQRCode) {
readQRCode.close();
PasswordPanel dialogPassword = new PasswordPanel(
new CloneFromPasswordListenerI(result));
dialogPassword.setCheckPre(false);
dialogPassword.setTitle(LocaliserUtils.getString("clone_from_password"));
dialogPassword.showPanel();
}
});
selectTransportQRCodePanel.showPanel();
}
}, MessageKey.CLONE_QRCODE, AwesomeIcon.DOWNLOAD);
panel.add(btnQRCode, "align center,cell 2 1 ,grow,wrap");
panel.add(btnPrivateKey, "align center,cell 2 2,grow,wrap");
panel.add(btnBIP38QRCode, "align center,cell 2 3,grow,wrap");
panel.add(btnBIP38, "align center,cell 2 4,grow,wrap");
if (UserPreference.getInstance().getAppMode() == BitherjSettings.AppMode.COLD
) {
if (AddressManager.getInstance().getHdmKeychain() == null) {
panel.add(btnHDMColdSeed, "align center,cell 2 5,grow,wrap");
panel.add(btnHDMColdPhras, "align center,cell 2 6,grow,wrap");
if (AddressManager.getInstance().getPrivKeyAddresses().size() == 0) {
panel.add(btnClone, "align center,cell 2 7,grow,wrap");
}
}
} else {
if (AddressManager.getInstance().getHdAccount() == null) {
panel.add(btnHDAccountSeed, "align center,cell 2 5,grow,wrap");
panel.add(btnHDAccountPhras, "align center,cell 2 6,grow,wrap");
}
}
}
private void onHDAccountSeedQRCode() {
SelectQRCodePanel qrCodePanel = new SelectQRCodePanel(new IScanQRCode() {
public void handleResult(final String result, IReadQRCode readQRCode) {
if (QRCodeUtil.verifyBitherQRCode(result)) {
if (result.indexOf(QRCodeUtil.HD_QR_CODE_FLAG) == 0) {
readQRCode.close();
PasswordPanel dialogPassword = new PasswordPanel(
new ImportHDAccountSeedPasswordListener(result));
dialogPassword.setCheckPre(false);
dialogPassword.setCheckPasswordListener(new ICheckPasswordListener() {
@Override
public boolean checkPassword(SecureCharSequence password) {
String keyString = result.substring(1);
String[] passwordSeeds = QRCodeUtil.splitOfPasswordSeed(keyString);
String encreyptString = Utils.joinString(new String[]{passwordSeeds[0], passwordSeeds[1], passwordSeeds[2]}, QRCodeUtil.QR_CODE_SPLIT);
EncryptedData encryptedData = new EncryptedData(encreyptString);
byte[] result = null;
try {
result = encryptedData.decrypt(password);
} catch (Exception e) {
e.printStackTrace();
}
return result != null;
}
});
dialogPassword.setTitle(LocaliserUtils.getString("import_private_key_qr_code_password"));
dialogPassword.showPanel();
} else {
new MessageDialog(LocaliserUtils.getString("import_hdm_cold_seed_format_error")).showMsg();
}
} else {
readQRCode.reTry("");
}
}
});
qrCodePanel.showPanel();
}
private void onColdSeedQRCode() {
SelectQRCodePanel qrCodePanel = new SelectQRCodePanel(new IScanQRCode() {
public void handleResult(final String result, IReadQRCode readQRCode) {
if (QRCodeUtil.verifyBitherQRCode(result)) {
if (result.indexOf(QRCodeUtil.HDM_QR_CODE_FLAG) == 0) {
readQRCode.close();
PasswordPanel dialogPassword = new PasswordPanel(
new ImportHDSeedPasswordListener(result));
dialogPassword.setCheckPre(false);
dialogPassword.setCheckPasswordListener(new ICheckPasswordListener() {
@Override
public boolean checkPassword(SecureCharSequence password) {
String keyString = result.substring(1);
String[] passwordSeeds = QRCodeUtil.splitOfPasswordSeed(keyString);
String encreyptString = Utils.joinString(new String[]{passwordSeeds[0], passwordSeeds[1], passwordSeeds[2]}, QRCodeUtil.QR_CODE_SPLIT);
EncryptedData encryptedData = new EncryptedData(encreyptString);
byte[] result = null;
try {
result = encryptedData.decrypt(password);
} catch (Exception e) {
e.printStackTrace();
}
return result != null;
}
});
dialogPassword.setTitle(LocaliserUtils.getString("import_private_key_qr_code_password"));
dialogPassword.showPanel();
} else {
new MessageDialog(LocaliserUtils.getString("import_hdm_cold_seed_format_error")).showMsg();
}
} else {
readQRCode.reTry("");
}
}
});
qrCodePanel.showPanel();
}
private void onQRCode() {
SelectQRCodePanel qrCodePanel = new SelectQRCodePanel(new IScanQRCode() {
public void handleResult(final String result, IReadQRCode readQRCode) {
if (QRCodeUtil.verifyBitherQRCode(result)) {
readQRCode.close();
PasswordPanel dialogPassword = new PasswordPanel(new ImportPrivateKeyPasswordListenerI(result, false));
dialogPassword.setCheckPre(false);
dialogPassword.setCheckPasswordListener(new ICheckPasswordListener() {
@Override
public boolean checkPassword(SecureCharSequence password) {
ECKey ecKey = PrivateKeyUtil.getECKeyFromSingleString(result, password);
boolean result = ecKey != null;
return result;
}
});
dialogPassword.showPanel();
} else {
readQRCode.reTry("");
}
}
});
qrCodePanel.showPanel();
}
private class ImportPrivateKeyPasswordListenerI implements IDialogPasswordListener {
private String content;
private boolean isFromBip38;
public ImportPrivateKeyPasswordListenerI(String content, boolean isFromBip38) {
this.content = content;
this.isFromBip38 = isFromBip38;
}
@Override
public void onPasswordEntered(SecureCharSequence password) {
if (password == null) {
return;
}
if (isFromBip38) {
PasswordPanel dialogPassword = new PasswordPanel(walletIDialogPasswordListener);
dialogPassword.showPanel();
} else {
ImportPrivateKeyDesktop importPrivateKey = new ImportPrivateKeyDesktop(
ImportPrivateKey.ImportPrivateKeyType.BitherQrcode, content, password);
importPrivateKey.importPrivateKey();
}
}
}
private IDialogPasswordListener walletIDialogPasswordListener = new IDialogPasswordListener() {
@Override
public void onPasswordEntered(SecureCharSequence password) {
if (password == null) {
return;
}
ImportPrivateKeyDesktop importPrivateKey = new ImportPrivateKeyDesktop(
ImportPrivateKey.ImportPrivateKeyType.Bip38, bip38DecodeString, password);
importPrivateKey.importPrivateKey();
}
};
private void onBIP38QRCode() {
SelectQRCodePanel qrCodePanel = new SelectQRCodePanel(new IScanQRCode() {
public void handleResult(final String result, IReadQRCode readQRCode) {
boolean isBIP38Key = false;
try {
isBIP38Key = Bip38.isBip38PrivateKey(result);
} catch (AddressFormatException e) {
e.printStackTrace();
}
if (isBIP38Key) {
readQRCode.close();
PasswordPanel dialogPassword = new PasswordPanel(new ImportPrivateKeyPasswordListenerI(result, true));
dialogPassword.setCheckPre(false);
dialogPassword.setCheckPasswordListener(new ICheckPasswordListener() {
@Override
public boolean checkPassword(SecureCharSequence password) {
try {
bip38DecodeString = Bip38.decrypt(result, password).toString();
return bip38DecodeString != null;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
});
dialogPassword.showPanel();
} else {
readQRCode.reTry("");
}
}
});
qrCodePanel.showPanel();
}
private void importPrivateText() {
ImportPrivateTextDialog importPrivateTextDialog = new ImportPrivateTextDialog();
importPrivateTextDialog.pack();
importPrivateTextDialog.setVisible(true);
}
private class ImportHDAccountSeedPasswordListener implements IDialogPasswordListener {
private String content;
public ImportHDAccountSeedPasswordListener(String content) {
this.content = content;
}
@Override
public void onPasswordEntered(SecureCharSequence password) {
if (password == null) {
return;
}
ImportHDSeedDesktop importHDSeedAndroid = new ImportHDSeedDesktop
(ImportHDSeed.ImportHDSeedType.HDSeedQRCode, content, null, password, new ImportListener() {
@Override
public void importSuccess() {
}
});
importHDSeedAndroid.importHDSeed();
}
}
private class ImportHDSeedPasswordListener implements IDialogPasswordListener {
private String content;
public ImportHDSeedPasswordListener(String content) {
this.content = content;
}
@Override
public void onPasswordEntered(SecureCharSequence password) {
if (password == null) {
return;
}
ImportHDSeedDesktop importHDSeedAndroid = new ImportHDSeedDesktop
(content, password, new ImportListener() {
@Override
public void importSuccess() {
}
});
importHDSeedAndroid.importHDMColdSeed();
}
}
private class CloneFromPasswordListenerI implements IDialogPasswordListener {
private String content;
public CloneFromPasswordListenerI(String content) {
this.content = content;
}
@Override
public void onPasswordEntered(SecureCharSequence password) {
if (password == null) {
return;
}
CloneThread cloneThread = new CloneThread(content, password);
cloneThread.start();
}
}
private class CloneThread extends Thread {
private String content;
private SecureCharSequence password;
public CloneThread(String content, SecureCharSequence password) {
this.content = content;
this.password = password;
}
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
}
});
List<Address> addressList = PrivateKeyUtil.getECKeysFromBackupString(content, password);
HDMKeychain hdmKeychain = PrivateKeyUtil.getHDMKeychain(content, password);
if ((addressList == null || addressList.size() == 0) && (hdmKeychain == null)) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
dp.dispose();
new MessageDialog(LocaliserUtils.getString("clone_from_failed")).showMsg();
}
});
return;
}
KeyUtil.addAddressListByDesc(addressList);
if (hdmKeychain != null) {
KeyUtil.setHDKeyChain(hdmKeychain);
}
password.wipe();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
dp.dispose();
new MessageDialog(LocaliserUtils.getString("clone_from_success")).showMsg();
closePanel();
Bither.refreshFrame();
}
});
}
}
}