Fixes and improvements, SystemTest still broken

This commit is contained in:
2017-06-16 07:03:12 +02:00
parent 1d3340a547
commit 894e0ff724
62 changed files with 1364 additions and 1276 deletions

View File

@ -15,5 +15,6 @@ dependencies {
compile 'org.ini4j:ini4j:0.5.4'
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:2.7.21'
testCompile 'com.nhaarman:mockito-kotlin:1.4.0'
testCompile project(':cryptography-bc')
}

View File

@ -1,106 +0,0 @@
/*
* Copyright 2015 Christian Basler
*
* 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 ch.dissem.bitmessage.wif;
import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.exception.ApplicationException;
import ch.dissem.bitmessage.utils.Base58;
import org.ini4j.Ini;
import org.ini4j.Profile;
import java.io.*;
import java.util.Collection;
import static ch.dissem.bitmessage.entity.valueobject.PrivateKey.PRIVATE_KEY_SIZE;
import static ch.dissem.bitmessage.utils.Singleton.cryptography;
/**
* @author Christian Basler
*/
public class WifExporter {
private final BitmessageContext ctx;
private final Ini ini;
public WifExporter(BitmessageContext ctx) {
this.ctx = ctx;
this.ini = new Ini();
}
public WifExporter addAll() {
for (BitmessageAddress identity : ctx.addresses().getIdentities()) {
addIdentity(identity);
}
return this;
}
public WifExporter addAll(Collection<BitmessageAddress> identities) {
for (BitmessageAddress identity : identities) {
addIdentity(identity);
}
return this;
}
public WifExporter addIdentity(BitmessageAddress identity) {
Profile.Section section = ini.add(identity.getAddress());
section.add("label", identity.getAlias());
section.add("enabled", true);
section.add("decoy", false);
if (identity.isChan()) {
section.add("chan", identity.isChan());
}
section.add("noncetrialsperbyte", identity.getPubkey().getNonceTrialsPerByte());
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 != 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, PRIVATE_KEY_SIZE);
byte[] hash = cryptography().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 {
file.createNewFile();
try (FileOutputStream out = new FileOutputStream(file)) {
write(out);
}
}
public void write(OutputStream out) throws IOException {
ini.store(out);
}
@Override
public String toString() {
StringWriter writer = new StringWriter();
try {
ini.store(writer);
} catch (IOException e) {
throw new ApplicationException(e);
}
return writer.toString();
}
}

View File

@ -0,0 +1,103 @@
/*
* Copyright 2017 Christian Basler
*
* 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.
*/
/*
* Copyright 2015 Christian Basler
*
* 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 ch.dissem.bitmessage.wif
import ch.dissem.bitmessage.BitmessageContext
import ch.dissem.bitmessage.entity.BitmessageAddress
import ch.dissem.bitmessage.entity.valueobject.PrivateKey.Companion.PRIVATE_KEY_SIZE
import ch.dissem.bitmessage.utils.Base58
import ch.dissem.bitmessage.utils.Singleton.cryptography
import org.ini4j.Ini
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStream
import java.io.StringWriter
/**
* @author Christian Basler
*/
class WifExporter(private val ctx: BitmessageContext) {
private val ini = Ini()
fun addAll(): WifExporter {
ctx.addresses.getIdentities().forEach { addIdentity(it) }
return this
}
fun addAll(identities: Collection<BitmessageAddress>): WifExporter {
identities.forEach { addIdentity(it) }
return this
}
fun addIdentity(identity: BitmessageAddress): WifExporter {
val section = ini.add(identity.address)
section.add("label", identity.alias)
section.add("enabled", true)
section.add("decoy", false)
if (identity.isChan) {
section.add("chan", identity.isChan)
}
section.add("noncetrialsperbyte", identity.pubkey!!.nonceTrialsPerByte)
section.add("payloadlengthextrabytes", identity.pubkey!!.extraBytes)
section.add("privsigningkey", exportSecret(identity.privateKey!!.privateSigningKey))
section.add("privencryptionkey", exportSecret(identity.privateKey!!.privateEncryptionKey))
return this
}
private fun exportSecret(privateKey: ByteArray): String {
if (privateKey.size != PRIVATE_KEY_SIZE) {
throw IllegalArgumentException("Private key of length 32 expected, but was " + privateKey.size)
}
val result = ByteArray(37)
result[0] = 0x80.toByte()
System.arraycopy(privateKey, 0, result, 1, PRIVATE_KEY_SIZE)
val hash = cryptography().doubleSha256(result, PRIVATE_KEY_SIZE + 1)
System.arraycopy(hash, 0, result, PRIVATE_KEY_SIZE + 1, 4)
return Base58.encode(result)
}
fun write(file: File) {
file.createNewFile()
FileOutputStream(file).use { out -> write(out) }
}
fun write(out: OutputStream) {
ini.store(out)
}
override fun toString(): String {
val writer = StringWriter()
ini.store(writer)
return writer.toString()
}
}

View File

@ -1,119 +0,0 @@
/*
* Copyright 2015 Christian Basler
*
* 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 ch.dissem.bitmessage.wif;
import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.entity.payload.Pubkey;
import ch.dissem.bitmessage.factory.Factory;
import ch.dissem.bitmessage.utils.Base58;
import org.ini4j.Ini;
import org.ini4j.Profile;
import java.io.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import static ch.dissem.bitmessage.utils.Singleton.cryptography;
/**
* @author Christian Basler
*/
public class WifImporter {
private static final byte WIF_FIRST_BYTE = (byte) 0x80;
private static final int WIF_SECRET_LENGTH = 37;
private final BitmessageContext ctx;
private final List<BitmessageAddress> identities = new LinkedList<>();
public WifImporter(BitmessageContext ctx, File file) throws IOException {
this(ctx, new FileInputStream(file));
}
public WifImporter(BitmessageContext ctx, String data) throws IOException {
this(ctx, new ByteArrayInputStream(data.getBytes("utf-8")));
}
public WifImporter(BitmessageContext ctx, InputStream in, Pubkey.Feature... features) throws IOException {
this.ctx = ctx;
Ini ini = new Ini();
ini.load(in);
for (Entry<String, Profile.Section> entry : ini.entrySet()) {
if (!entry.getKey().startsWith("BM-"))
continue;
Profile.Section section = entry.getValue();
BitmessageAddress address = Factory.createIdentityFromPrivateKey(
entry.getKey(),
getSecret(section.get("privsigningkey")),
getSecret(section.get("privencryptionkey")),
Long.parseLong(section.get("noncetrialsperbyte")),
Long.parseLong(section.get("payloadlengthextrabytes")),
Pubkey.Feature.bitfield(features)
);
if (section.containsKey("chan")) {
address.setChan(Boolean.parseBoolean(section.get("chan")));
}
address.setAlias(section.get("label"));
identities.add(address);
}
}
private byte[] getSecret(String walletImportFormat) throws IOException {
byte[] bytes = Base58.decode(walletImportFormat);
if (bytes[0] != WIF_FIRST_BYTE)
throw new IOException("Unknown format: 0x80 expected as first byte, but secret " + walletImportFormat +
" was " + bytes[0]);
if (bytes.length != WIF_SECRET_LENGTH)
throw new IOException("Unknown format: " + WIF_SECRET_LENGTH +
" bytes expected, but secret " + walletImportFormat + " was " + bytes.length + " long");
byte[] hash = cryptography().doubleSha256(bytes, 33);
for (int i = 0; i < 4; i++) {
if (hash[i] != bytes[33 + i]) throw new IOException("Hash check failed for secret " + walletImportFormat);
}
return Arrays.copyOfRange(bytes, 1, 33);
}
public List<BitmessageAddress> getIdentities() {
return identities;
}
public WifImporter importAll() {
for (BitmessageAddress identity : identities) {
ctx.addresses().save(identity);
}
return this;
}
public WifImporter importAll(Collection<BitmessageAddress> identities) {
for (BitmessageAddress identity : identities) {
ctx.addresses().save(identity);
}
return this;
}
public WifImporter importIdentity(BitmessageAddress identity) {
ctx.addresses().save(identity);
return this;
}
}

View File

@ -0,0 +1,126 @@
/*
* Copyright 2017 Christian Basler
*
* 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.
*/
/*
* Copyright 2015 Christian Basler
*
* 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 ch.dissem.bitmessage.wif
import ch.dissem.bitmessage.BitmessageContext
import ch.dissem.bitmessage.entity.BitmessageAddress
import ch.dissem.bitmessage.entity.payload.Pubkey
import ch.dissem.bitmessage.exception.ApplicationException
import ch.dissem.bitmessage.factory.Factory
import ch.dissem.bitmessage.utils.Base58
import ch.dissem.bitmessage.utils.Singleton.cryptography
import org.ini4j.Ini
import java.io.ByteArrayInputStream
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.util.*
/**
* @author Christian Basler
*/
class WifImporter constructor(
private val ctx: BitmessageContext,
`in`: InputStream,
vararg features: Pubkey.Feature
) {
private val identities = LinkedList<BitmessageAddress>()
constructor(ctx: BitmessageContext, file: File) : this(ctx, FileInputStream(file))
constructor(ctx: BitmessageContext, data: String) : this(ctx, ByteArrayInputStream(data.toByteArray(charset("utf-8"))))
init {
val ini = Ini()
ini.load(`in`)
for ((key, section) in ini) {
if (!key.startsWith("BM-"))
continue
val address = Factory.createIdentityFromPrivateKey(
key,
getSecret(section["privsigningkey"] ?: throw ApplicationException("privsigningkey missing for $key")),
getSecret(section["privencryptionkey"] ?: throw ApplicationException("privencryptionkey missing for $key")),
section["noncetrialsperbyte"]?.toLongOrNull() ?: throw ApplicationException("noncetrialsperbyte missing for $key"),
section["payloadlengthextrabytes"]?.toLongOrNull() ?: throw ApplicationException("payloadlengthextrabytes missing for $key"),
Pubkey.Feature.bitfield(*features)
)
if (section.containsKey("chan")) {
address.isChan = java.lang.Boolean.parseBoolean(section["chan"])
}
address.alias = section["label"]
identities.add(address)
}
}
private fun getSecret(walletImportFormat: String): ByteArray {
val bytes = Base58.decode(walletImportFormat)
if (bytes[0] != WIF_FIRST_BYTE)
throw ApplicationException("Unknown format: 0x80 expected as first byte, but secret " + walletImportFormat +
" was " + bytes[0])
if (bytes.size != WIF_SECRET_LENGTH)
throw ApplicationException("Unknown format: " + WIF_SECRET_LENGTH +
" bytes expected, but secret " + walletImportFormat + " was " + bytes.size + " long")
val hash = cryptography().doubleSha256(bytes, 33)
(0..3)
.filter { hash[it] != bytes[33 + it] }
.forEach { throw ApplicationException("Hash check failed for secret " + walletImportFormat) }
return Arrays.copyOfRange(bytes, 1, 33)
}
fun getIdentities(): List<BitmessageAddress> {
return identities
}
fun importAll(): WifImporter {
identities.forEach { ctx.addresses.save(it) }
return this
}
fun importAll(identities: Collection<BitmessageAddress>): WifImporter {
identities.forEach { ctx.addresses.save(it) }
return this
}
fun importIdentity(identity: BitmessageAddress): WifImporter {
ctx.addresses.save(identity)
return this
}
companion object {
private const val WIF_FIRST_BYTE = 0x80.toByte()
private const val WIF_SECRET_LENGTH = 37
}
}

View File

@ -1,107 +0,0 @@
/*
* Copyright 2015 Christian Basler
*
* 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 ch.dissem.bitmessage.wif;
import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.ports.*;
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class WifExporterTest {
private AddressRepository repo = mock(AddressRepository.class);
private BitmessageContext ctx;
private WifImporter importer;
private WifExporter exporter;
@Before
public void setUp() throws Exception {
ctx = new BitmessageContext.Builder()
.cryptography(BouncyCryptography.INSTANCE)
.networkHandler(mock(NetworkHandler.class))
.inventory(mock(Inventory.class))
.messageRepo(mock(MessageRepository.class))
.powRepo(mock(ProofOfWorkRepository.class))
.nodeRegistry(mock(NodeRegistry.class))
.addressRepo(repo)
.build();
importer = new WifImporter(ctx, getClass().getClassLoader().getResourceAsStream("nuked.dat"));
assertEquals(81, importer.getIdentities().size());
exporter = new WifExporter(ctx);
}
@Test
public void testAddAll() throws Exception {
when(repo.getIdentities()).thenReturn(importer.getIdentities());
exporter.addAll();
String result = exporter.toString();
int count = 0;
for (int i = 0; i < result.length(); i++) {
if (result.charAt(i) == '[') count++;
}
assertEquals(importer.getIdentities().size(), count);
}
@Test
public void testAddAllFromCollection() throws Exception {
exporter.addAll(importer.getIdentities());
String result = exporter.toString();
int count = 0;
for (int i = 0; i < result.length(); i++) {
if (result.charAt(i) == '[') count++;
}
assertEquals(importer.getIdentities().size(), count);
}
@Test
public void testAddIdentity() throws Exception {
String expected = "[BM-2DAjcCFrqFrp88FUxExhJ9kPqHdunQmiyn]" + System.lineSeparator() +
"label = Nuked Address" + System.lineSeparator() +
"enabled = true" + System.lineSeparator() +
"decoy = false" + System.lineSeparator() +
"noncetrialsperbyte = 320" + System.lineSeparator() +
"payloadlengthextrabytes = 14000" + System.lineSeparator() +
"privsigningkey = 5KU2gbe9u4rKJ8PHYb1rvwMnZnAJj4gtV5GLwoYckeYzygWUzB9" + System.lineSeparator() +
"privencryptionkey = 5KHd4c6cavd8xv4kzo3PwnVaYuBgEfg7voPQ5V97aZKgpYBXGck" + System.lineSeparator() +
System.lineSeparator();
importer = new WifImporter(ctx, expected);
exporter.addIdentity(importer.getIdentities().get(0));
assertEquals(expected, exporter.toString());
}
@Test
public void ensureChanIsAdded() throws Exception {
String expected = "[BM-2cW67GEKkHGonXKZLCzouLLxnLym3azS8r]" + System.lineSeparator() +
"label = general" + System.lineSeparator() +
"enabled = true" + System.lineSeparator() +
"decoy = false" + System.lineSeparator() +
"chan = true" + System.lineSeparator() +
"noncetrialsperbyte = 1000" + System.lineSeparator() +
"payloadlengthextrabytes = 1000" + System.lineSeparator() +
"privsigningkey = 5Jnbdwc4u4DG9ipJxYLznXSvemkRFueQJNHujAQamtDDoX3N1eQ" + System.lineSeparator() +
"privencryptionkey = 5JrDcFtQDv5ydcHRW6dfGUEvThoxCCLNEUaxQfy8LXXgTJzVAcq" + System.lineSeparator() +
System.lineSeparator();
BitmessageAddress chan = ctx.joinChan("general", "BM-2cW67GEKkHGonXKZLCzouLLxnLym3azS8r");
exporter.addIdentity(chan);
assertEquals(expected, exporter.toString());
}
}

View File

@ -0,0 +1,122 @@
/*
* Copyright 2017 Christian Basler
*
* 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.
*/
/*
* Copyright 2015 Christian Basler
*
* 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 ch.dissem.bitmessage.wif
import ch.dissem.bitmessage.BitmessageContext
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography
import ch.dissem.bitmessage.ports.AddressRepository
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.whenever
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
class WifExporterTest {
private val repo = mock<AddressRepository>()
private lateinit var ctx: BitmessageContext
private lateinit var importer: WifImporter
private lateinit var exporter: WifExporter
@Before
fun setUp() {
ctx = BitmessageContext.Builder()
.cryptography(BouncyCryptography())
.networkHandler(mock())
.inventory(mock())
.messageRepo(mock())
.powRepo(mock())
.nodeRegistry(mock())
.addressRepo(repo)
.listener { }
.build()
importer = WifImporter(ctx, javaClass.classLoader.getResourceAsStream("nuked.dat"))
assertEquals(81, importer.getIdentities().size)
exporter = WifExporter(ctx)
}
@Test
fun `ensure all identities in context are added`() {
whenever(repo.getIdentities()).thenReturn(importer.getIdentities())
exporter.addAll()
val result = exporter.toString()
var count = 0
for (i in 0..result.length - 1) {
if (result[i] == '[') count++
}
assertEquals(importer.getIdentities().size, count)
}
@Test
fun `ensure all from a collection are added`() {
exporter.addAll(importer.getIdentities())
val result = exporter.toString()
var count = 0
for (i in 0..result.length - 1) {
if (result[i] == '[') count++
}
assertEquals(importer.getIdentities().size, count)
}
@Test
fun `ensure identity is added`() {
val expected = "[BM-2DAjcCFrqFrp88FUxExhJ9kPqHdunQmiyn]" + System.lineSeparator() +
"label = Nuked Address" + System.lineSeparator() +
"enabled = true" + System.lineSeparator() +
"decoy = false" + System.lineSeparator() +
"noncetrialsperbyte = 320" + System.lineSeparator() +
"payloadlengthextrabytes = 14000" + System.lineSeparator() +
"privsigningkey = 5KU2gbe9u4rKJ8PHYb1rvwMnZnAJj4gtV5GLwoYckeYzygWUzB9" + System.lineSeparator() +
"privencryptionkey = 5KHd4c6cavd8xv4kzo3PwnVaYuBgEfg7voPQ5V97aZKgpYBXGck" + System.lineSeparator() +
System.lineSeparator()
importer = WifImporter(ctx, expected)
exporter.addIdentity(importer.getIdentities()[0])
assertEquals(expected, exporter.toString())
}
@Test
fun `ensure chan is added`() {
val expected = "[BM-2cW67GEKkHGonXKZLCzouLLxnLym3azS8r]" + System.lineSeparator() +
"label = general" + System.lineSeparator() +
"enabled = true" + System.lineSeparator() +
"decoy = false" + System.lineSeparator() +
"chan = true" + System.lineSeparator() +
"noncetrialsperbyte = 1000" + System.lineSeparator() +
"payloadlengthextrabytes = 1000" + System.lineSeparator() +
"privsigningkey = 5Jnbdwc4u4DG9ipJxYLznXSvemkRFueQJNHujAQamtDDoX3N1eQ" + System.lineSeparator() +
"privencryptionkey = 5JrDcFtQDv5ydcHRW6dfGUEvThoxCCLNEUaxQfy8LXXgTJzVAcq" + System.lineSeparator() +
System.lineSeparator()
val chan = ctx.joinChan("general", "BM-2cW67GEKkHGonXKZLCzouLLxnLym3azS8r")
exporter.addIdentity(chan)
assertEquals(expected, exporter.toString())
}
}

View File

@ -1,116 +0,0 @@
/*
* Copyright 2015 Christian Basler
*
* 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 ch.dissem.bitmessage.wif;
import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.ports.*;
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
public class WifImporterTest {
private AddressRepository repo = mock(AddressRepository.class);
private BitmessageContext ctx;
private WifImporter importer;
@Before
public void setUp() throws Exception {
ctx = new BitmessageContext.Builder()
.cryptography(BouncyCryptography.INSTANCE)
.networkHandler(mock(NetworkHandler.class))
.inventory(mock(Inventory.class))
.messageRepo(mock(MessageRepository.class))
.powRepo(mock(ProofOfWorkRepository.class))
.nodeRegistry(mock(NodeRegistry.class))
.addressRepo(repo)
.build();
importer = new WifImporter(ctx, getClass().getClassLoader().getResourceAsStream("nuked.dat"));
}
@Test
public void testImportSingleIdentity() throws Exception {
importer = new WifImporter(ctx, "[BM-2cWJ4UFRTCehWuWNsW8fJkAYMxU4S8jxci]\n" +
"label = Nuked Address\n" +
"enabled = true\n" +
"decoy = false\n" +
"noncetrialsperbyte = 320\n" +
"payloadlengthextrabytes = 14000\n" +
"privsigningkey = 5JU5t2JA58sP5aJwKAcrYg5EpBA9bJPrBSaFfaZ7ogmwTMDCfHL\n" +
"privencryptionkey = 5Kkx5MwjQcM4kyduKvCEPM6nVNynMdRcg88VQ5iVDWUekMz1igH");
assertEquals(1, importer.getIdentities().size());
BitmessageAddress identity = importer.getIdentities().get(0);
assertEquals("BM-2cWJ4UFRTCehWuWNsW8fJkAYMxU4S8jxci", identity.getAddress());
assertEquals("Nuked Address", identity.getAlias());
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);
assertFalse(identity.isChan());
}
@Test
public void testGetIdentities() throws Exception {
List<BitmessageAddress> identities = importer.getIdentities();
assertEquals(81, identities.size());
}
@Test
public void testImportAll() throws Exception {
importer.importAll();
verify(repo, times(81)).save(any(BitmessageAddress.class));
}
@Test
public void testImportAllFromCollection() throws Exception {
List<BitmessageAddress> identities = importer.getIdentities();
importer.importAll(identities);
for (BitmessageAddress identity : identities) {
verify(repo, times(1)).save(identity);
}
}
@Test
public void testImportIdentity() throws Exception {
List<BitmessageAddress> identities = importer.getIdentities();
importer.importIdentity(identities.get(0));
verify(repo, times(1)).save(identities.get(0));
}
@Test
public void ensureChanIsImported() throws Exception {
importer = new WifImporter(ctx, "[BM-2cW67GEKkHGonXKZLCzouLLxnLym3azS8r]\n" +
"label = [chan] general\n" +
"enabled = true\n" +
"decoy = false\n" +
"chan = true\n" +
"noncetrialsperbyte = 1000\n" +
"payloadlengthextrabytes = 1000\n" +
"privsigningkey = 5Jnbdwc4u4DG9ipJxYLznXSvemkRFueQJNHujAQamtDDoX3N1eQ\n" +
"privencryptionkey = 5JrDcFtQDv5ydcHRW6dfGUEvThoxCCLNEUaxQfy8LXXgTJzVAcq\n");
assertEquals(1, importer.getIdentities().size());
BitmessageAddress chan = importer.getIdentities().get(0);
assertTrue(chan.isChan());
}
}

View File

@ -0,0 +1,132 @@
/*
* Copyright 2017 Christian Basler
*
* 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.
*/
/*
* Copyright 2015 Christian Basler
*
* 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 ch.dissem.bitmessage.wif
import ch.dissem.bitmessage.BitmessageContext
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography
import ch.dissem.bitmessage.ports.AddressRepository
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.times
import com.nhaarman.mockito_kotlin.verify
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
class WifImporterTest {
private val repo = mock<AddressRepository>()
private lateinit var ctx: BitmessageContext
private lateinit var importer: WifImporter
@Before
fun setUp() {
ctx = BitmessageContext.Builder()
.cryptography(BouncyCryptography())
.networkHandler(mock())
.inventory(mock())
.messageRepo(mock())
.powRepo(mock())
.nodeRegistry(mock())
.addressRepo(repo)
.listener { }
.build()
importer = WifImporter(ctx, javaClass.classLoader.getResourceAsStream("nuked.dat"))
}
@Test
fun `ensure single identity is imported`() {
importer = WifImporter(ctx, "[BM-2cWJ4UFRTCehWuWNsW8fJkAYMxU4S8jxci]\n" +
"label = Nuked Address\n" +
"enabled = true\n" +
"decoy = false\n" +
"noncetrialsperbyte = 320\n" +
"payloadlengthextrabytes = 14000\n" +
"privsigningkey = 5JU5t2JA58sP5aJwKAcrYg5EpBA9bJPrBSaFfaZ7ogmwTMDCfHL\n" +
"privencryptionkey = 5Kkx5MwjQcM4kyduKvCEPM6nVNynMdRcg88VQ5iVDWUekMz1igH")
assertEquals(1, importer.getIdentities().size)
val identity = importer.getIdentities()[0]
assertEquals("BM-2cWJ4UFRTCehWuWNsW8fJkAYMxU4S8jxci", identity.address)
assertEquals("Nuked Address", identity.alias)
assertEquals(320L, identity.pubkey?.nonceTrialsPerByte)
assertEquals(14000L, identity.pubkey?.extraBytes)
assertNotNull("Private key", identity.privateKey)
assertEquals(32, identity.privateKey?.privateEncryptionKey?.size)
assertEquals(32, identity.privateKey?.privateSigningKey?.size)
assertFalse(identity.isChan)
}
@Test
fun `ensure all identities are retrieved`() {
val identities = importer.getIdentities()
assertEquals(81, identities.size)
}
@Test
fun `ensure all identities are imported`() {
importer.importAll()
verify(repo, times(81)).save(any())
}
@Test
fun `ensure all identities in collection are imported`() {
val identities = importer.getIdentities()
importer.importAll(identities)
for (identity in identities) {
verify(repo, times(1)).save(identity)
}
}
@Test
fun `ensure single identity from list is imported`() {
val identities = importer.getIdentities()
importer.importIdentity(identities[0])
verify(repo, times(1)).save(identities[0])
}
@Test
fun `ensure chan is imported`() {
importer = WifImporter(ctx, "[BM-2cW67GEKkHGonXKZLCzouLLxnLym3azS8r]\n" +
"label = [chan] general\n" +
"enabled = true\n" +
"decoy = false\n" +
"chan = true\n" +
"noncetrialsperbyte = 1000\n" +
"payloadlengthextrabytes = 1000\n" +
"privsigningkey = 5Jnbdwc4u4DG9ipJxYLznXSvemkRFueQJNHujAQamtDDoX3N1eQ\n" +
"privencryptionkey = 5JrDcFtQDv5ydcHRW6dfGUEvThoxCCLNEUaxQfy8LXXgTJzVAcq\n")
assertEquals(1, importer.getIdentities().size)
val chan = importer.getIdentities()[0]
assertTrue(chan.isChan)
}
}