Added import/export to the demo app

- discovered private key length was wrong - fixed
- as things are broken anyway, refactored flyway migrations - you'll need to delete ~/jabit.*.db
This commit is contained in:
Christian Basler 2015-07-03 11:28:06 +02:00
parent 65fdd7d408
commit 6f50c200ee
13 changed files with 80 additions and 29 deletions

View File

@ -22,6 +22,7 @@ dependencies {
compile project(':domain')
compile project(':networking')
compile project(':repositories')
compile project(':wif')
compile 'org.slf4j:slf4j-simple:1.7.12'
compile 'args4j:args4j:2.32'
testCompile 'junit:junit:4.11'

View File

@ -16,6 +16,16 @@
package ch.dissem.bitmessage.demo;
import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.networking.NetworkNode;
import ch.dissem.bitmessage.repository.*;
import ch.dissem.bitmessage.wif.WifExporter;
import ch.dissem.bitmessage.wif.WifImporter;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
import java.io.File;
import java.io.IOException;
public class Main {
@ -25,6 +35,40 @@ public class Main {
if (System.getProperty("org.slf4j.simpleLogger.logFile") == null)
System.setProperty("org.slf4j.simpleLogger.logFile", "./jabit.log");
new Application();
CmdLineOptions options = new CmdLineOptions();
CmdLineParser parser = new CmdLineParser(options);
try {
parser.parseArgument(args);
} catch (CmdLineException e) {
parser.printUsage(System.err);
}
if (options.exportWIF != null || options.importWIF != null) {
JdbcConfig jdbcConfig = new JdbcConfig();
BitmessageContext ctx = new BitmessageContext.Builder()
.addressRepo(new JdbcAddressRepository(jdbcConfig))
.inventory(new JdbcInventory(jdbcConfig))
.nodeRegistry(new MemoryNodeRegistry())
.messageRepo(new JdbcMessageRepository(jdbcConfig))
.networkHandler(new NetworkNode())
.port(48444)
.build();
if (options.exportWIF != null) {
new WifExporter(ctx).addAll().write(options.exportWIF);
}
if (options.importWIF != null) {
new WifImporter(ctx, options.importWIF).importAll();
}
} else {
new Application();
}
}
private static class CmdLineOptions {
@Option(name = "-import", usage = "Import from keys.dat or other WIF file.")
private File importWIF;
@Option(name = "-export", usage = "Export to WIF file.")
private File exportWIF;
}
}

View File

@ -17,6 +17,7 @@
package ch.dissem.bitmessage.entity.payload;
import ch.dissem.bitmessage.entity.Streamable;
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
import ch.dissem.bitmessage.exception.DecryptionFailedException;
import ch.dissem.bitmessage.utils.*;
import org.bouncycastle.crypto.BufferedBlockCipher;
@ -37,6 +38,8 @@ import java.io.*;
import java.math.BigInteger;
import java.util.Arrays;
import static ch.dissem.bitmessage.entity.valueobject.PrivateKey.PRIVATE_KEY_SIZE;
public class CryptoBox implements Streamable {
private static final Logger LOG = LoggerFactory.getLogger(CryptoBox.class);
@ -59,7 +62,7 @@ public class CryptoBox implements Streamable {
initializationVector = Security.randomBytes(16);
// 3. Generate a new random EC key pair with private key called r and public key called R.
byte[] r = Security.randomBytes(64);
byte[] r = Security.randomBytes(PRIVATE_KEY_SIZE);
R = Security.createPublicKey(r);
// 4. Do an EC point multiply with public key K and private key r. This gives you public key P.
ECPoint P = K.multiply(Security.keyToBigInt(r)).normalize();

View File

@ -32,8 +32,9 @@ import java.io.*;
* Created by chris on 18.04.15.
*/
public class PrivateKey implements Streamable {
private final byte[] privateSigningKey; // 32 bytes
private final byte[] privateEncryptionKey; // 32 bytes
public static final int PRIVATE_KEY_SIZE = 32;
private final byte[] privateSigningKey;
private final byte[] privateEncryptionKey;
private final Pubkey pubkey;
@ -44,8 +45,8 @@ public class PrivateKey implements Streamable {
byte[] pubEK;
byte[] ripe;
do {
privSK = Security.randomBytes(64);
privEK = Security.randomBytes(64);
privSK = Security.randomBytes(PRIVATE_KEY_SIZE);
privEK = Security.randomBytes(PRIVATE_KEY_SIZE);
pubSK = Security.createPublicKey(privSK).getEncoded(false);
pubEK = Security.createPublicKey(privEK).getEncoded(false);
ripe = Pubkey.getRipe(pubSK, pubEK);

View File

@ -1,9 +0,0 @@
CREATE TABLE Node (
ip BINARY(16) NOT NULL,
port INT NOT NULL,
stream BIGINT NOT NULL,
services BIGINT NOT NULL,
time BIGINT NOT NULL,
PRIMARY KEY (ip, port, stream)
);

View File

@ -34,7 +34,7 @@ CREATE TABLE Message_Label (
);
INSERT INTO Label(label, type, color, ord) VALUES ('Inbox', 'INBOX', X'FF0000FF', 0);
INSERT INTO Label(label, type, color, ord) VALUES ('Drafts', 'DRAFTS', X'FFFF9900', 10);
INSERT INTO Label(label, type, color, ord) VALUES ('Drafts', 'DRAFT', X'FFFF9900', 10);
INSERT INTO Label(label, type, color, ord) VALUES ('Sent', 'SENT', X'FFFFFF00', 20);
INSERT INTO Label(label, type, ord) VALUES ('Unread', 'UNREAD', 90);
INSERT INTO Label(label, type, ord) VALUES ('Trash', 'TRASH', 100);

View File

@ -1 +0,0 @@
UPDATE Label SET type = 'DRAFT' WHERE type = 'DRAFTS';

View File

@ -26,6 +26,8 @@ import org.ini4j.Profile;
import java.io.*;
import java.util.Collection;
import static ch.dissem.bitmessage.entity.valueobject.PrivateKey.PRIVATE_KEY_SIZE;
/**
* @author Christian Basler
*/
@ -38,19 +40,21 @@ public class WifExporter {
this.ini = new Ini();
}
public void addAll() {
public WifExporter addAll() {
for (BitmessageAddress identity : ctx.addresses().getIdentities()) {
addIdentity(identity);
}
return this;
}
public void addAll(Collection<BitmessageAddress> identities) {
public WifExporter addAll(Collection<BitmessageAddress> identities) {
for (BitmessageAddress identity : identities) {
addIdentity(identity);
}
return this;
}
public void addIdentity(BitmessageAddress identity) {
public WifExporter addIdentity(BitmessageAddress identity) {
Profile.Section section = ini.add(identity.getAddress());
section.add("label", identity.getAlias());
section.add("enabled", true);
@ -59,22 +63,26 @@ public class WifExporter {
section.add("payloadlengthextrabytes", identity.getPubkey().getExtraBytes());
section.add("privsigningkey", exportSecret(identity.getPrivateKey().getPrivateSigningKey()));
section.add("privencryptionkey", exportSecret(identity.getPrivateKey().getPrivateEncryptionKey()));
return this;
}
private String exportSecret(byte[] privateKey) {
if (privateKey.length != 32) {
if (privateKey.length != PRIVATE_KEY_SIZE) {
throw new IllegalArgumentException("Private key of length 32 expected, but was " + privateKey.length);
}
byte[] result = new byte[37];
result[0] = (byte) 0x80;
System.arraycopy(privateKey, 0, result, 1, 32);
byte[] hash = Security.doubleSha256(result, 33);
System.arraycopy(hash, 0, result, 33, 4);
System.arraycopy(privateKey, 0, result, 1, PRIVATE_KEY_SIZE);
byte[] hash = Security.doubleSha256(result, PRIVATE_KEY_SIZE + 1);
System.arraycopy(hash, 0, result, PRIVATE_KEY_SIZE + 1, 4);
return Base58.encode(result);
}
public void write(File file) throws IOException {
write(new FileOutputStream(file));
file.createNewFile();
try (FileOutputStream out = new FileOutputStream(file)) {
write(out);
}
}
public void write(OutputStream out) throws IOException {

View File

@ -95,19 +95,22 @@ public class WifImporter {
return identities;
}
public void importAll() {
public WifImporter importAll() {
for (BitmessageAddress identity : identities) {
ctx.addresses().save(identity);
}
return this;
}
public void importAll(Collection<BitmessageAddress> identities) {
public WifImporter importAll(Collection<BitmessageAddress> identities) {
for (BitmessageAddress identity : identities) {
ctx.addresses().save(identity);
}
return this;
}
public void importIdentity(BitmessageAddress identity) {
public WifImporter importIdentity(BitmessageAddress identity) {
ctx.addresses().save(identity);
return this;
}
}

View File

@ -64,6 +64,8 @@ public class WifImporterTest {
assertEquals(320, identity.getPubkey().getNonceTrialsPerByte());
assertEquals(14000, identity.getPubkey().getExtraBytes());
assertNotNull("Private key", identity.getPrivateKey());
assertEquals(32, identity.getPrivateKey().getPrivateEncryptionKey().length);
assertEquals(32, identity.getPrivateKey().getPrivateSigningKey().length);
}
@Test