Add mailbox service and message encryption

This commit is contained in:
Manfred Karrer 2015-03-20 17:30:58 +01:00
parent 9dcce78d39
commit b5e47716d6
15 changed files with 297 additions and 135 deletions

View File

@ -33,5 +33,6 @@ public class CryptoModule extends BitsquareModule {
protected void configure() {
bind(SignatureService.class).in(Singleton.class);
bind(HashService.class).in(Singleton.class);
bind(EncryptionService.class).in(Singleton.class);
}
}

View File

@ -0,0 +1,88 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.crypto;
import io.bitsquare.util.Utilities;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Cipher;
public class EncryptionService {
private static final Logger log = LoggerFactory.getLogger(EncryptionService.class);
@Inject
public EncryptionService() {
}
public KeyPair getKeyPair() {
KeyPair keyPair = null;
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
keyPair = keyPairGenerator.genKeyPair();
} catch (Exception e) {
e.printStackTrace();
log.error("Exception at init " + e.getMessage());
}
return keyPair;
}
public byte[] encryptObject(PublicKey publicKey, Object object) {
return encrypt(publicKey, Utilities.objectToBytArray(object));
}
public Object decryptObject(PrivateKey privateKey, byte[] cipherMessage) {
return Utilities.byteArrayToObject(decrypt(privateKey, cipherMessage));
}
public byte[] encrypt(PublicKey publicKey, byte[] data) {
byte[] cipherData = null;
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
cipherData = cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
log.error("Exception at encrypt " + e.getMessage());
}
return cipherData;
}
public byte[] decrypt(PrivateKey privateKey, byte[] cipherText) {
byte[] data = null;
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
data = cipher.doFinal(cipherText);
} catch (Exception e) {
e.printStackTrace();
log.error("Exception at decrypt " + e.getMessage());
}
return data;
}
}

View File

@ -161,7 +161,7 @@ class MainViewModel implements ViewModel {
// Set executor for all P2PServices
BaseP2PService.setUserThread(Platform::runLater);
Observable<BootstrapState> bootstrapStateAsObservable = clientNode.bootstrap(user.getMessageKeyPair());
Observable<BootstrapState> bootstrapStateAsObservable = clientNode.bootstrap(user.getP2pSigKeyPair());
bootstrapStateAsObservable.publish();
bootstrapStateAsObservable.subscribe(
state -> Platform.runLater(() -> setBootstrapState(state)),
@ -354,7 +354,7 @@ class MainViewModel implements ViewModel {
}
private void addMockArbitrator() {
if (accountSettings.getAcceptedArbitrators().isEmpty() && user.getMessageKeyPair() != null) {
if (accountSettings.getAcceptedArbitrators().isEmpty() && user.getP2pSigKeyPair() != null) {
byte[] pubKey = new ECKey().getPubKey();
String messagePubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getMessagePubKey());
List<Locale> languages = new ArrayList<>();

View File

@ -122,7 +122,7 @@ class IrcAccountDataModel implements Activatable, DataModel {
}
private void addMockArbitrator() {
if (accountSettings.getAcceptedArbitrators().isEmpty() && user.getMessageKeyPair() != null) {
if (accountSettings.getAcceptedArbitrators().isEmpty() && user.getP2pSigKeyPair() != null) {
byte[] pubKey = new ECKey().getPubKey();
String messagePubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getMessagePubKey());
List<Locale> languages = new ArrayList<>();

View File

@ -152,7 +152,7 @@ class RestrictionsDataModel implements Activatable, DataModel {
// TODO Remove mock later
private void addMockArbitrator() {
if (accountSettings.getAcceptedArbitrators().isEmpty() && user.getMessageKeyPair() != null) {
if (accountSettings.getAcceptedArbitrators().isEmpty() && user.getP2pSigKeyPair() != null) {
byte[] pubKey = new ECKey().getPubKey();
String messagePubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getMessagePubKey());
List<Locale> languages = new ArrayList<>();

View File

@ -50,8 +50,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TomP2POfferBookService extends TomP2PDHTService implements OfferBookService {
private static final Logger log = LoggerFactory.getLogger(TomP2POfferBookService.class);
private static final int TTL = 30 * 24 * 60 * 60; // the offer is default 30 days valid
private final List<Listener> offerRepositoryListeners = new ArrayList<>();
private final LongProperty invalidationTimestamp = new SimpleLongProperty(0);
@ -67,10 +67,7 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo
Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode());
try {
final Data offerData = new Data(offer);
// the offer is default 30 days valid
int defaultOfferTTL = 30 * 24 * 60 * 60;
offerData.ttlSeconds(defaultOfferTTL);
offerData.ttlSeconds(TTL);
log.trace("Add offer to DHT requested. Added data: [locationKey: " + locationKey +
", hash: " + offerData.hash().toString() + "]");
FuturePut futurePut = addProtectedDataToMap(locationKey, offerData);

View File

@ -0,0 +1,41 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.p2p;
import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*
Stores a message in encrypted form, so it never leaves the client in plain text.
*/
public class MailboxMessage implements Message, Serializable {
private static final long serialVersionUID = -3111178895546299769L;
private static final Logger log = LoggerFactory.getLogger(MailboxMessage.class);
private byte[] cipherMessage;
public MailboxMessage(byte[] cipherMessage) {
this.cipherMessage = cipherMessage;
}
public byte[] getCipherMessage() {
return cipherMessage;
}
}

View File

@ -0,0 +1,32 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.p2p;
import io.bitsquare.common.handlers.FaultHandler;
import io.bitsquare.common.handlers.ResultHandler;
import io.bitsquare.p2p.tomp2p.TomP2PMailboxService;
import java.security.PublicKey;
public interface MailboxService {
void addMessage(PublicKey publicKey, MailboxMessage message, ResultHandler resultHandler, FaultHandler faultHandler);
void removeMessage(PublicKey publicKey, MailboxMessage message, ResultHandler resultHandler, FaultHandler faultHandler);
void getMessages(PublicKey publicKey, TomP2PMailboxService.MailboxMessagesResultHandler resultHandler);
}

View File

@ -66,7 +66,7 @@ public class TomP2PAddressService extends TomP2PDHTService implements AddressSer
public TomP2PAddressService(TomP2PNode tomP2PNode, User user) {
super(tomP2PNode, user);
locationKey = Utils.makeSHAHash(user.getMessageKeyPair().getPublic().getEncoded());
locationKey = Utils.makeSHAHash(user.getP2pSigKeyPair().getPublic().getEncoded());
}
@Override

View File

@ -49,7 +49,7 @@ public class TomP2PDHTService extends TomP2PService implements DHTService {
@Inject
public TomP2PDHTService(TomP2PNode tomP2PNode, User user) {
super(tomP2PNode);
keyPair = user.getMessageKeyPair();
keyPair = user.getP2pSigKeyPair();
pubKeyHashForMyDomain = Utils.makeSHAHash(keyPair.getPublic().getEncoded());
}

View File

@ -19,12 +19,9 @@ package io.bitsquare.p2p.tomp2p;
import io.bitsquare.common.handlers.FaultHandler;
import io.bitsquare.common.handlers.ResultHandler;
import io.bitsquare.offer.Offer;
import io.bitsquare.offer.OfferBookService;
import io.bitsquare.p2p.AddressService;
import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.Peer;
import io.bitsquare.p2p.listener.GetPeerAddressListener;
import io.bitsquare.p2p.MailboxMessage;
import io.bitsquare.p2p.MailboxService;
import io.bitsquare.user.User;
import java.io.IOException;
@ -46,21 +43,16 @@ import net.tomp2p.futures.BaseFutureListener;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.Number640;
import net.tomp2p.storage.Data;
import net.tomp2p.utils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TomP2PMailboxService extends TomP2PDHTService implements AddressService {
public class TomP2PMailboxService extends TomP2PDHTService implements MailboxService {
private static final Logger log = LoggerFactory.getLogger(TomP2PMailboxService.class);
private static final int TTL = 15 * 24 * 60 * 60; // the message is default 15 days valid, as a max trade period might be about 2 weeks.
private final List<OfferBookService.Listener> offerRepositoryListeners = new ArrayList<>();
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public TomP2PMailboxService(TomP2PNode tomP2PNode, User user) {
super(tomP2PNode, user);
@ -76,69 +68,45 @@ public class TomP2PMailboxService extends TomP2PDHTService implements AddressSer
super.shutDown();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Find peer address by publicKey
///////////////////////////////////////////////////////////////////////////////////////////
// public void findPeerAddress(PublicKey publicKey, GetPeerAddressListener listener) {
// final Number160 locationKey = Utils.makeSHAHash(publicKey.getEncoded());
public void saveMessage(PublicKey publicKey, Message message, ResultHandler resultHandler, FaultHandler faultHandler) {
final Number160 locationKey = Utils.makeSHAHash(publicKey.getEncoded());
// Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode());
@Override
public void addMessage(PublicKey publicKey, MailboxMessage message, ResultHandler resultHandler, FaultHandler faultHandler) {
try {
final Data offerData = new Data(message);
final Data data = new Data(message);
data.ttlSeconds(TTL);
log.trace("Add message to DHT requested. Added data: [locationKey: " + getLocationKey(publicKey) +
", hash: " + data.hash().toString() + "]");
// the offer is default 30 days valid
int defaultOfferTTL = 30 * 24 * 60 * 60;
offerData.ttlSeconds(defaultOfferTTL);
log.trace("Add offer to DHT requested. Added data: [locationKey: " + locationKey +
", hash: " + offerData.hash().toString() + "]");
FuturePut futurePut = addProtectedDataToMap(locationKey, offerData);
FuturePut futurePut = addDataToMapOfProtectedDomain(getLocationKey(publicKey), data, publicKey);
futurePut.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
executor.execute(() -> {
resultHandler.handleResult();
offerRepositoryListeners.stream().forEach(listener -> {
try {
Object offerDataObject = offerData.object();
if (offerDataObject instanceof Offer) {
log.info("Added offer to DHT with ID: " + offerDataObject);
listener.onOfferAdded((Offer) offerDataObject);
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
log.error("Add offer to DHT failed: " + e.getMessage());
}
});
log.trace("Add offer to DHT was successful. Added data: [locationKey: " + locationKey +
", value: " + offerData + "]");
log.trace("Add message to mailbox was successful. Added data: [locationKey: " + getLocationKey(publicKey) +
", value: " + data + "]");
});
}
}
@Override
public void exceptionCaught(Throwable ex) throws Exception {
executor.execute(() -> faultHandler.handleFault("Failed to add offer to DHT", ex));
executor.execute(() -> faultHandler.handleFault("Add message to mailbox failed.", ex));
}
});
} catch (IOException ex) {
executor.execute(() -> faultHandler.handleFault("Failed to add offer to DHT", ex));
executor.execute(() -> faultHandler.handleFault("Add message to mailbox failed.", ex));
}
}
public void removeOffer(Offer offer, ResultHandler resultHandler, FaultHandler faultHandler) {
Number160 locationKey = Number160.createHash(offer.getCurrency().getCurrencyCode());
@Override
public void removeMessage(PublicKey publicKey, MailboxMessage message, ResultHandler resultHandler, FaultHandler faultHandler) {
try {
final Data offerData = new Data(offer);
log.trace("Remove offer from DHT requested. Removed data: [locationKey: " + locationKey +
", hash: " + offerData.hash().toString() + "]");
FutureRemove futureRemove = removeProtectedDataFromMap(locationKey, offerData);
final Data data = new Data(message);
log.trace("Remove message from DHT requested. Removed data: [locationKey: " + getLocationKey(publicKey) +
", hash: " + data.hash().toString() + "]");
FutureRemove futureRemove = removeDataFromMapOfMyProtectedDomain(getLocationKey(publicKey), data);
futureRemove.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception {
@ -148,109 +116,73 @@ public class TomP2PMailboxService extends TomP2PDHTService implements AddressSer
log.trace("isRemoved? " + futureRemove.isRemoved());
executor.execute(() -> {
resultHandler.handleResult();
offerRepositoryListeners.stream().forEach(listener -> {
try {
Object offerDataObject = offerData.object();
if (offerDataObject instanceof Offer) {
log.trace("Remove offer from DHT was successful. Removed data: [key: " +
locationKey + ", " +
"offer: " + offerDataObject + "]");
listener.onOfferRemoved((Offer) offerDataObject);
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
log.error("Remove offer from DHT failed. Error: " + e.getMessage());
faultHandler.handleFault("Remove offer from DHT failed. Error: " + e.getMessage(), e);
}
});
});
}
@Override
public void exceptionCaught(Throwable t) throws Exception {
log.error("Remove offer from DHT failed. Error: " + t.getMessage());
faultHandler.handleFault("Remove offer from DHT failed. Error: " + t.getMessage(), t);
log.error("Remove message from DHT failed. Error: " + t.getMessage());
faultHandler.handleFault("Remove message from DHT failed. Error: " + t.getMessage(), t);
}
});
} catch (IOException e) {
e.printStackTrace();
log.error("Remove offer from DHT failed. Error: " + e.getMessage());
faultHandler.handleFault("Remove offer from DHT failed. Error: " + e.getMessage(), e);
log.error("Remove message from DHT failed. Error: " + e.getMessage());
faultHandler.handleFault("Remove message from DHT failed. Error: " + e.getMessage(), e);
}
}
public void getOffers(String currencyCode) {
Number160 locationKey = Number160.createHash(currencyCode);
log.trace("Get offers from DHT requested for locationKey: " + locationKey);
FutureGet futureGet = getMap(locationKey);
@Override
public void getMessages(PublicKey publicKey, MailboxMessagesResultHandler resultHandler) {
log.trace("Get messages from DHT requested for locationKey: " + getLocationKey(publicKey));
FutureGet futureGet = getDataFromMapOfMyProtectedDomain(getLocationKey(publicKey));
futureGet.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
final Map<Number640, Data> dataMap = futureGet.dataMap();
final List<Offer> offers = new ArrayList<>();
List<MailboxMessage> messages = new ArrayList<>();
if (dataMap != null) {
for (Data offerData : dataMap.values()) {
for (Data messageData : dataMap.values()) {
try {
Object offerDataObject = offerData.object();
if (offerDataObject instanceof Offer) {
offers.add((Offer) offerDataObject);
Object messageDataObject = messageData.object();
if (messageDataObject instanceof MailboxMessage) {
messages.add((MailboxMessage) messageDataObject);
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}
executor.execute(() -> offerRepositoryListeners.stream().forEach(listener ->
listener.onOffersReceived(offers)));
executor.execute(() -> resultHandler.handleResult(messages));
}
log.trace("Get offers from DHT was successful. Stored data: [key: " + locationKey
log.trace("Get messages from DHT was successful. Stored data: [key: " + getLocationKey(publicKey)
+ ", values: " + futureGet.dataMap() + "]");
}
else {
final Map<Number640, Data> dataMap = futureGet.dataMap();
if (dataMap == null || dataMap.size() == 0) {
log.trace("Get offers from DHT delivered empty dataMap.");
executor.execute(() -> offerRepositoryListeners.stream().forEach(listener ->
listener.onOffersReceived(new ArrayList<>())));
log.trace("Get messages from DHT delivered empty dataMap.");
executor.execute(() -> resultHandler.handleResult(new ArrayList<>()));
}
else {
log.error("Get offers from DHT was not successful with reason:" + future.failedReason());
log.error("Get messages from DHT was not successful with reason:" + future.failedReason());
}
}
}
});
}
@Override
public void findPeerAddress(PublicKey publicKey, GetPeerAddressListener listener) {
final Number160 locationKey = Utils.makeSHAHash(publicKey.getEncoded());
FutureGet futureGet = getDataOfProtectedDomain(locationKey, publicKey);
log.trace("findPeerAddress called");
futureGet.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override
public void operationComplete(BaseFuture baseFuture) throws Exception {
if (baseFuture.isSuccess() && futureGet.data() != null) {
final Peer peer = (Peer) futureGet.data().object();
log.trace("Peer found in DHT. Peer = " + peer);
executor.execute(() -> listener.onResult(peer));
}
else {
log.error("getPeerAddress failed. failedReason = " + baseFuture.failedReason());
executor.execute(listener::onFailed);
}
}
});
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private Number160 getLocationKey(String currencyCode) {
return Number160.createHash(currencyCode + "mailbox");
private Number160 getLocationKey(PublicKey publicKey) {
return Number160.createHash("mailbox" + publicKey.hashCode());
}
}
public interface MailboxMessagesResultHandler {
void handleResult(List<MailboxMessage> messages);
}
}

View File

@ -20,9 +20,10 @@ package io.bitsquare.p2p.tomp2p;
import io.bitsquare.p2p.AddressService;
import io.bitsquare.p2p.BootstrapNodes;
import io.bitsquare.p2p.ClientNode;
import io.bitsquare.p2p.MailboxService;
import io.bitsquare.p2p.MessageService;
import io.bitsquare.p2p.P2PModule;
import io.bitsquare.p2p.Node;
import io.bitsquare.p2p.P2PModule;
import com.google.inject.Injector;
import com.google.inject.Singleton;
@ -53,7 +54,8 @@ public class TomP2PModule extends P2PModule {
bind(AddressService.class).to(TomP2PAddressService.class).in(Singleton.class);
bind(MessageService.class).to(TomP2PMessageService.class).in(Singleton.class);
bind(MailboxService.class).to(TomP2PMailboxService.class).in(Singleton.class);
bind(int.class).annotatedWith(Names.named(Node.PORT_KEY)).toInstance(env.getProperty(Node.PORT_KEY, int.class, Node.DEFAULT_PORT));
bind(boolean.class).annotatedWith(Names.named(USE_MANUAL_PORT_FORWARDING_KEY)).toInstance(
env.getProperty(USE_MANUAL_PORT_FORWARDING_KEY, boolean.class, false));

View File

@ -17,6 +17,7 @@
package io.bitsquare.user;
import io.bitsquare.crypto.EncryptionService;
import io.bitsquare.fiat.FiatAccount;
import io.bitsquare.util.DSAKeyUtil;
@ -30,6 +31,8 @@ import java.util.List;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
@ -43,7 +46,8 @@ import javafx.collections.ObservableList;
public class User implements Serializable {
private static final long serialVersionUID = 7409078808248518638L;
private KeyPair messageKeyPair;
private KeyPair p2pSigKeyPair;
private KeyPair p2pEncryptKeyPair;
private String accountID;
// Used for serialisation (ObservableList cannot be serialized) -> serialisation will change anyway so that is
@ -53,8 +57,11 @@ public class User implements Serializable {
private final transient ObservableList<FiatAccount> fiatAccounts = FXCollections.observableArrayList();
private final transient ObjectProperty<FiatAccount> currentBankAccount = new SimpleObjectProperty<>();
transient private EncryptionService encryptionService;
public User() {
@Inject
public User(EncryptionService encryptionService) {
this.encryptionService = encryptionService;
// Used for serialisation (ObservableList cannot be serialized) -> serialisation will change anyway so that is
// only temporary
fiatAccounts.addListener((ListChangeListener<FiatAccount>) change -> _fiatAccounts = new ArrayList<>(fiatAccounts));
@ -62,6 +69,9 @@ public class User implements Serializable {
currentBankAccount.addListener((ov) -> _currentFiatAccount = currentBankAccount.get());
}
// for unit tests
public User() {
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public Methods
@ -71,13 +81,14 @@ public class User implements Serializable {
if (persistedUser != null) {
fiatAccounts.setAll(persistedUser.getSerializedBankAccounts());
setCurrentBankAccount(persistedUser.getSerializedCurrentBankAccount());
messageKeyPair = persistedUser.getMessageKeyPair();
p2pSigKeyPair = persistedUser.getP2pSigKeyPair();
p2pEncryptKeyPair = persistedUser.getP2pEncryptKeyPair();
accountID = persistedUser.getAccountId();
}
else {
// First time
// TODO use separate thread. DSAKeyUtil.getKeyPair() runs in same thread now
messageKeyPair = DSAKeyUtil.generateKeyPair();
p2pSigKeyPair = DSAKeyUtil.generateKeyPair();
p2pEncryptKeyPair = encryptionService.getKeyPair();
}
}
@ -160,12 +171,12 @@ public class User implements Serializable {
return null;
}
public KeyPair getMessageKeyPair() {
return messageKeyPair;
public KeyPair getP2pSigKeyPair() {
return p2pSigKeyPair;
}
public PublicKey getMessagePubKey() {
return messageKeyPair.getPublic();
return p2pSigKeyPair.getPublic();
}
public ObjectProperty<FiatAccount> currentBankAccountProperty() {
@ -181,4 +192,7 @@ public class User implements Serializable {
return _currentFiatAccount;
}
public KeyPair getP2pEncryptKeyPair() {
return p2pEncryptKeyPair;
}
}

View File

@ -27,7 +27,9 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
@ -145,6 +147,59 @@ public class Utilities {
return result;
}
public static Object byteArrayToObject(byte[] data) {
ByteArrayInputStream bis = new ByteArrayInputStream(data);
ObjectInput in = null;
Object result = null;
try {
in = new ObjectInputStream(bis);
result = in.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bis.close();
} catch (IOException ex) {
// ignore close exception
}
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
// ignore close exception
}
}
return result;
}
public static byte[] objectToBytArray(Object object) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = null;
byte[] result = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(object);
result = bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException ex) {
// ignore close exception
}
try {
bos.close();
} catch (IOException ex) {
// ignore close exception
}
}
return result;
}
private static void printElapsedTime(String msg) {
if (!msg.isEmpty()) {
msg += " / ";

View File

@ -98,7 +98,7 @@ public class PlaceOfferProtocolTest {
tomP2PNode = new TomP2PNode(bootstrappedPeerBuilder);
messageService = new TomP2PMessageService(tomP2PNode);
Observable<BootstrapState> messageObservable = tomP2PNode.bootstrap(user.getMessageKeyPair());
Observable<BootstrapState> messageObservable = tomP2PNode.bootstrap(user.getP2pSigKeyPair());
messageObservable.publish();
messageObservable.subscribe(
state -> log.trace("state changed: " + state),