mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-23 20:36:44 +00:00
ecies input and output streams
This commit is contained in:
parent
14aa328f6d
commit
981b379615
10 changed files with 161 additions and 6 deletions
|
@ -0,0 +1,47 @@
|
|||
package com.sparrowwallet.sparrow.io;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.sparrowwallet.drongo.crypto.ECKey;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class ECIESInputStream extends FilterInputStream {
|
||||
private boolean decrypted;
|
||||
private final ECKey decryptionKey;
|
||||
private final byte[] encryptionMagic;
|
||||
|
||||
public ECIESInputStream(InputStream in, ECKey decryptionKey, byte[] encryptionMagic) {
|
||||
super(in);
|
||||
|
||||
if(in == null || decryptionKey == null || encryptionMagic == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
this.decryptionKey = decryptionKey;
|
||||
this.encryptionMagic = encryptionMagic;
|
||||
}
|
||||
|
||||
public ECIESInputStream(InputStream in, ECKey decryptionKey) {
|
||||
this(in, decryptionKey, "BIE1".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
ensureDecrypted();
|
||||
return super.read();
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
ensureDecrypted();
|
||||
return super.read(b, off, len);
|
||||
}
|
||||
|
||||
private synchronized void ensureDecrypted() throws IOException {
|
||||
if(!decrypted) {
|
||||
byte[] encrypted = ByteStreams.toByteArray(in);
|
||||
in.close();
|
||||
in = new ByteArrayInputStream(decryptionKey.decryptEcies(encrypted, encryptionMagic));
|
||||
decrypted = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.sparrowwallet.sparrow.io;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.sparrowwallet.drongo.crypto.ECKey;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class ECIESOutputStream extends FilterOutputStream {
|
||||
private final ECKey encryptionKey;
|
||||
private final byte[] encryptionMagic;
|
||||
private final OutputStream encryptedStream;
|
||||
|
||||
public ECIESOutputStream(OutputStream out, ECKey encryptionKey, byte[] encryptionMagic) {
|
||||
super(new ByteArrayOutputStream());
|
||||
|
||||
encryptedStream = out;
|
||||
|
||||
if(encryptionKey == null || encryptionMagic == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
this.encryptionKey = encryptionKey;
|
||||
this.encryptionMagic = encryptionMagic;
|
||||
}
|
||||
|
||||
public ECIESOutputStream(OutputStream in, ECKey encryptionKey) {
|
||||
this(in, encryptionKey, "BIE1".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
byte[] unencrypted = ((ByteArrayOutputStream)out).toByteArray();
|
||||
byte[] encryptedWallet = encryptionKey.encryptEcies(unencrypted, encryptionMagic);
|
||||
ByteStreams.copy(new ByteArrayInputStream(encryptedWallet), encryptedStream);
|
||||
encryptedStream.flush();
|
||||
encryptedStream.close();
|
||||
}
|
||||
}
|
|
@ -83,7 +83,7 @@ public class Electrum implements KeystoreFileImport, SinglesigWalletImport, Mult
|
|||
ScriptType scriptType = null;
|
||||
|
||||
for(ElectrumKeystore ek : ew.keystores.values()) {
|
||||
Keystore keystore = new Keystore(ek.label);
|
||||
Keystore keystore = new Keystore(ek.label != null ? ek.label : "Electrum " + ek.root_fingerprint);
|
||||
if("hardware".equals(ek.type)) {
|
||||
keystore.setSource(KeystoreSource.HW_USB);
|
||||
keystore.setWalletModel(WalletModel.fromType(ek.hw_type));
|
||||
|
@ -98,8 +98,9 @@ public class Electrum implements KeystoreFileImport, SinglesigWalletImport, Mult
|
|||
}
|
||||
keystore.setWalletModel(WalletModel.ELECTRUM);
|
||||
}
|
||||
ExtendedPublicKey xPub = ExtendedPublicKey.fromDescriptor(ek.xpub);
|
||||
keystore.setKeyDerivation(new KeyDerivation(ek.root_fingerprint, ek.derivation));
|
||||
keystore.setExtendedPublicKey(ExtendedPublicKey.fromDescriptor(ek.xpub));
|
||||
keystore.setExtendedPublicKey(xPub);
|
||||
wallet.getKeystores().add(keystore);
|
||||
|
||||
ExtendedPublicKey.XpubHeader xpubHeader = ExtendedPublicKey.XpubHeader.fromXpub(ek.xpub);
|
||||
|
|
|
@ -11,7 +11,7 @@ import org.junit.Test;
|
|||
|
||||
import java.io.*;
|
||||
|
||||
public class ColdcardMultisigTest extends ImportExportTest {
|
||||
public class ColdcardMultisigTest extends IoTest {
|
||||
@Test
|
||||
public void importKeystore1() throws ImportException {
|
||||
ColdcardMultisig ccMultisig = new ColdcardMultisig();
|
||||
|
|
|
@ -6,7 +6,7 @@ import com.sparrowwallet.drongo.wallet.Wallet;
|
|||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ColdcardSinglesigTest extends ImportExportTest {
|
||||
public class ColdcardSinglesigTest extends IoTest {
|
||||
@Test
|
||||
public void testImport() throws ImportException {
|
||||
ColdcardSinglesig ccSingleSig = new ColdcardSinglesig();
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package com.sparrowwallet.sparrow.io;
|
||||
|
||||
import com.sparrowwallet.drongo.crypto.ECKey;
|
||||
import com.sparrowwallet.drongo.policy.PolicyType;
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
public class ECIESInputStreamTest extends IoTest {
|
||||
@Test
|
||||
public void decrypt() throws ImportException {
|
||||
Electrum electrum = new Electrum();
|
||||
ECKey decryptionKey = ECKey.createKeyPbkdf2HmacSha512("pass");
|
||||
Wallet wallet = electrum.importWallet(new InflaterInputStream(new ECIESInputStream(getInputStream("electrum-encrypted"), decryptionKey)));
|
||||
|
||||
Assert.assertEquals(PolicyType.SINGLE, wallet.getPolicyType());
|
||||
Assert.assertEquals(ScriptType.P2WPKH, wallet.getScriptType());
|
||||
Assert.assertEquals(1, wallet.getDefaultPolicy().getNumSignaturesRequired());
|
||||
Assert.assertEquals("pkh(electrum05aba071)", wallet.getDefaultPolicy().getMiniscript().getScript());
|
||||
Assert.assertEquals("05aba071", wallet.getKeystores().get(0).getKeyDerivation().getMasterFingerprint());
|
||||
Assert.assertEquals("m/0'", wallet.getKeystores().get(0).getKeyDerivation().getDerivationPath());
|
||||
Assert.assertEquals("xpub67vv394epQsLhdjNGx7dfgURicP7XwBMuHPTVAMdXcXhDuC9VP8SqVvh2cYqKWm9xoUd6YynWK8JzRcXpmeuZFRH7i1kt8fR9GXoJSiHk1E", wallet.getKeystores().get(0).getExtendedPublicKey().toString());
|
||||
Assert.assertTrue(wallet.isValid());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.sparrowwallet.sparrow.io;
|
||||
|
||||
import com.sparrowwallet.drongo.crypto.ECKey;
|
||||
import com.sparrowwallet.drongo.policy.PolicyType;
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
public class ECIESOutputStreamTest extends IoTest {
|
||||
@Test
|
||||
public void encrypt() throws ImportException, ExportException {
|
||||
Electrum electrum = new Electrum();
|
||||
ECKey decryptionKey = ECKey.createKeyPbkdf2HmacSha512("pass");
|
||||
Wallet wallet = electrum.importWallet(new InflaterInputStream(new ECIESInputStream(getInputStream("electrum-encrypted"), decryptionKey)));
|
||||
|
||||
ECKey encyptionKey = ECKey.fromPublicOnly(decryptionKey);
|
||||
ByteArrayOutputStream dummyFileOutputStream = new ByteArrayOutputStream();
|
||||
electrum.exportWallet(wallet, new DeflaterOutputStream(new ECIESOutputStream(dummyFileOutputStream, encyptionKey)));
|
||||
|
||||
ByteArrayInputStream dummyFileInputStream = new ByteArrayInputStream(dummyFileOutputStream.toByteArray());
|
||||
wallet = electrum.importWallet(new InflaterInputStream(new ECIESInputStream(dummyFileInputStream, decryptionKey)));
|
||||
|
||||
Assert.assertEquals(PolicyType.SINGLE, wallet.getPolicyType());
|
||||
Assert.assertEquals(ScriptType.P2WPKH, wallet.getScriptType());
|
||||
Assert.assertEquals(1, wallet.getDefaultPolicy().getNumSignaturesRequired());
|
||||
Assert.assertEquals("pkh(electrum05aba071)", wallet.getDefaultPolicy().getMiniscript().getScript());
|
||||
Assert.assertEquals("05aba071", wallet.getKeystores().get(0).getKeyDerivation().getMasterFingerprint());
|
||||
Assert.assertEquals("m/0'", wallet.getKeystores().get(0).getKeyDerivation().getDerivationPath());
|
||||
Assert.assertEquals("xpub67vv394epQsLhdjNGx7dfgURicP7XwBMuHPTVAMdXcXhDuC9VP8SqVvh2cYqKWm9xoUd6YynWK8JzRcXpmeuZFRH7i1kt8fR9GXoJSiHk1E", wallet.getKeystores().get(0).getExtendedPublicKey().toString());
|
||||
Assert.assertTrue(wallet.isValid());
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ElectrumTest extends ImportExportTest {
|
||||
public class ElectrumTest extends IoTest {
|
||||
@Test
|
||||
public void testSinglesigImport() throws ImportException {
|
||||
Electrum electrum = new Electrum();
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.sparrowwallet.sparrow.io;
|
|||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class ImportExportTest {
|
||||
public class IoTest {
|
||||
|
||||
protected InputStream getInputStream(String filename) {
|
||||
return this.getClass().getResourceAsStream("/com/sparrowwallet/sparrow/io/" + filename);
|
|
@ -0,0 +1 @@
|
|||
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
|
Loading…
Reference in a new issue