Put DataAndSeqNrPair into P2PDataStorage

This commit is contained in:
Manfred Karrer 2016-02-11 13:21:35 +01:00
parent 04b32a35a2
commit fa2da8dbe5
4 changed files with 51 additions and 49 deletions

View File

@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.File;
import java.io.Serializable;
import java.security.KeyPair;
import java.security.PublicKey;
import java.util.*;
@ -239,7 +240,7 @@ public class P2PDataStorage implements MessageListener {
else
sequenceNumber = 0;
byte[] hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(payload, sequenceNumber));
byte[] hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNrPair(payload, sequenceNumber));
byte[] signature = Sig.sign(ownerStoragePubKey.getPrivate(), hashOfDataAndSeqNr);
return new ProtectedData(payload, payload.getTTL(), ownerStoragePubKey.getPublic(), sequenceNumber, signature);
}
@ -255,7 +256,7 @@ public class P2PDataStorage implements MessageListener {
else
sequenceNumber = 0;
byte[] hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(expirableMailboxPayload, sequenceNumber));
byte[] hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNrPair(expirableMailboxPayload, sequenceNumber));
byte[] signature = Sig.sign(storageSignaturePubKey.getPrivate(), hashOfDataAndSeqNr);
return new ProtectedMailboxData(expirableMailboxPayload, expirableMailboxPayload.getTTL(),
storageSignaturePubKey.getPublic(), sequenceNumber, signature, receiversPublicKey);
@ -300,7 +301,7 @@ public class P2PDataStorage implements MessageListener {
private boolean checkSignature(ProtectedData data) {
Log.traceCall();
byte[] hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, data.sequenceNumber));
byte[] hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNrPair(data.expirablePayload, data.sequenceNumber));
try {
boolean result = Sig.verify(data.ownerStoragePubKey, hashOfDataAndSeqNr, data.signature);
if (!result)
@ -368,4 +369,28 @@ public class P2PDataStorage implements MessageListener {
return new ByteArray(Hash.getHash(payload));
}
///////////////////////////////////////////////////////////////////////////////////////////
// Static class
///////////////////////////////////////////////////////////////////////////////////////////
public static class DataAndSeqNrPair implements Serializable {
// data are only used for getting cryptographic hash from both values
private final Serializable data;
private final int sequenceNumber;
public DataAndSeqNrPair(Serializable data, int sequenceNumber) {
this.data = data;
this.sequenceNumber = sequenceNumber;
}
@Override
public String toString() {
return "DataAndSeqNr{" +
"data=" + data +
", sequenceNumber=" + sequenceNumber +
'}';
}
}
}

View File

@ -1,22 +0,0 @@
package io.bitsquare.p2p.storage.data;
import java.io.Serializable;
public class DataAndSeqNr implements Serializable {
// data are only used for getting cryptographic hash from both values
private final Serializable data;
private final int sequenceNumber;
public DataAndSeqNr(Serializable data, int sequenceNumber) {
this.data = data;
this.sequenceNumber = sequenceNumber;
}
@Override
public String toString() {
return "DataAndSeqNr{" +
"data=" + data +
", sequenceNumber=" + sequenceNumber +
'}';
}
}

View File

@ -10,7 +10,7 @@ import io.bitsquare.p2p.mocks.MockMailboxMessage;
import io.bitsquare.p2p.network.LocalhostNetworkNode;
import io.bitsquare.p2p.peers.PeerManager;
import io.bitsquare.p2p.seed.SeedNode;
import io.bitsquare.p2p.storage.data.DataAndSeqNr;
import io.bitsquare.p2p.storage.P2PDataStorage;
import io.bitsquare.p2p.storage.data.ProtectedData;
import io.bitsquare.p2p.storage.mocks.MockData;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
@ -175,7 +175,7 @@ public class P2PServiceTest {
// try to manipulate seq nr. + pubKey + sig -> fails
int sequenceNumberManipulated = origProtectedData.sequenceNumber + 1;
byte[] hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(origProtectedData.expirablePayload, sequenceNumberManipulated));
byte[] hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(origProtectedData.expirablePayload, sequenceNumberManipulated));
byte[] signature = Sig.sign(msgSignatureKeyPairAdversary.getPrivate(), hashOfDataAndSeqNr);
protectedDataManipulated = new ProtectedData(origProtectedData.expirablePayload, origProtectedData.ttl, msgSignatureKeyPairAdversary.getPublic(), sequenceNumberManipulated, signature);
Assert.assertFalse(p2PService3.removeData(protectedDataManipulated.expirablePayload));
@ -197,7 +197,7 @@ public class P2PServiceTest {
// first he tries to use the orig. pubKey in the data -> fails as pub keys not matching
MockData manipulatedData = new MockData("mockData1_manipulated", origData.publicKey);
sequenceNumberManipulated = 0;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(manipulatedData, sequenceNumberManipulated));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(manipulatedData, sequenceNumberManipulated));
signature = Sig.sign(msgSignatureKeyPairAdversary.getPrivate(), hashOfDataAndSeqNr);
protectedDataManipulated = new ProtectedData(origProtectedData.expirablePayload, origProtectedData.ttl, msgSignatureKeyPairAdversary.getPublic(), sequenceNumberManipulated, signature);
Assert.assertFalse(p2PService3.addData(protectedDataManipulated.expirablePayload));
@ -209,7 +209,7 @@ public class P2PServiceTest {
// then he tries to use his pubKey but orig data payload -> fails as pub keys nto matching
manipulatedData = new MockData("mockData1_manipulated", msgSignatureKeyPairAdversary.getPublic());
sequenceNumberManipulated = 0;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(manipulatedData, sequenceNumberManipulated));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(manipulatedData, sequenceNumberManipulated));
signature = Sig.sign(msgSignatureKeyPairAdversary.getPrivate(), hashOfDataAndSeqNr);
protectedDataManipulated = new ProtectedData(origProtectedData.expirablePayload, origProtectedData.ttl, msgSignatureKeyPairAdversary.getPublic(), sequenceNumberManipulated, signature);
Assert.assertFalse(p2PService3.addData(protectedDataManipulated.expirablePayload));
@ -222,7 +222,7 @@ public class P2PServiceTest {
// payload data has adversary's pubKey so he could hijack the owners data
manipulatedData = new MockData("mockData1_manipulated", msgSignatureKeyPairAdversary.getPublic());
sequenceNumberManipulated = 0;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(manipulatedData, sequenceNumberManipulated));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(manipulatedData, sequenceNumberManipulated));
signature = Sig.sign(msgSignatureKeyPairAdversary.getPrivate(), hashOfDataAndSeqNr);
protectedDataManipulated = new ProtectedData(manipulatedData, origProtectedData.ttl, msgSignatureKeyPairAdversary.getPublic(), sequenceNumberManipulated, signature);
Assert.assertTrue(p2PService3.addData(protectedDataManipulated.expirablePayload));
@ -242,7 +242,7 @@ public class P2PServiceTest {
// finally he tries both previous attempts with same data - > same as before
manipulatedData = new MockData("mockData1", origData.publicKey);
sequenceNumberManipulated = 0;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(manipulatedData, sequenceNumberManipulated));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(manipulatedData, sequenceNumberManipulated));
signature = Sig.sign(msgSignatureKeyPairAdversary.getPrivate(), hashOfDataAndSeqNr);
protectedDataManipulated = new ProtectedData(origProtectedData.expirablePayload, origProtectedData.ttl, msgSignatureKeyPairAdversary.getPublic(), sequenceNumberManipulated, signature);
Assert.assertFalse(p2PService3.addData(protectedDataManipulated.expirablePayload));
@ -253,7 +253,7 @@ public class P2PServiceTest {
manipulatedData = new MockData("mockData1", msgSignatureKeyPairAdversary.getPublic());
sequenceNumberManipulated = 0;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(manipulatedData, sequenceNumberManipulated));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(manipulatedData, sequenceNumberManipulated));
signature = Sig.sign(msgSignatureKeyPairAdversary.getPrivate(), hashOfDataAndSeqNr);
protectedDataManipulated = new ProtectedData(manipulatedData, origProtectedData.ttl, msgSignatureKeyPairAdversary.getPublic(), sequenceNumberManipulated, signature);
Assert.assertTrue(p2PService3.addData(protectedDataManipulated.expirablePayload));

View File

@ -11,7 +11,6 @@ import io.bitsquare.p2p.mocks.MockMessage;
import io.bitsquare.p2p.network.NetworkNode;
import io.bitsquare.p2p.peers.Broadcaster;
import io.bitsquare.p2p.peers.PeerManager;
import io.bitsquare.p2p.storage.data.DataAndSeqNr;
import io.bitsquare.p2p.storage.data.ExpirableMailboxPayload;
import io.bitsquare.p2p.storage.data.ProtectedData;
import io.bitsquare.p2p.storage.data.ProtectedMailboxData;
@ -103,7 +102,7 @@ public class ProtectedDataStorageTest {
Assert.assertEquals(1, dataStorage1.getMap().size());
int newSequenceNumber = data.sequenceNumber + 1;
byte[] hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
byte[] hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
byte[] signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
ProtectedData dataToRemove = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertTrue(dataStorage1.remove(dataToRemove, null));
@ -135,7 +134,7 @@ public class ProtectedDataStorageTest {
// add with date in future
data = dataStorage1.getDataWithSignedSeqNr(mockData, storageSignatureKeyPair1);
int newSequenceNumber = data.sequenceNumber + 1;
byte[] hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
byte[] hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
byte[] signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
ProtectedData dataWithFutureDate = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
dataWithFutureDate.date = new Date(new Date().getTime() + 60 * 60 * sleepTime);
@ -156,63 +155,63 @@ public class ProtectedDataStorageTest {
// remove with not updated seq nr -> failure
int newSequenceNumber = 0;
byte[] hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
byte[] hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
byte[] signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
ProtectedData dataToRemove = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertFalse(dataStorage1.remove(dataToRemove, null));
// remove with too high updated seq nr -> ok
newSequenceNumber = 2;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
dataToRemove = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertTrue(dataStorage1.remove(dataToRemove, null));
// add to empty map, any seq nr. -> ok
newSequenceNumber = 2;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
ProtectedData dataToAdd = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertTrue(dataStorage1.add(dataToAdd, null));
// add with updated seq nr below previous -> failure
newSequenceNumber = 1;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
dataToAdd = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertFalse(dataStorage1.add(dataToAdd, null));
// add with updated seq nr over previous -> ok
newSequenceNumber = 3;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
dataToAdd = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertTrue(dataStorage1.add(dataToAdd, null));
// add with same seq nr -> failure
newSequenceNumber = 3;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
dataToAdd = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertFalse(dataStorage1.add(dataToAdd, null));
// add with same data but higher seq nr. -> ok, ignore
newSequenceNumber = 4;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
dataToAdd = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertTrue(dataStorage1.add(dataToAdd, null));
// remove with with same seq nr as prev. ignored -> failed
newSequenceNumber = 4;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
dataToRemove = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertFalse(dataStorage1.remove(dataToRemove, null));
// remove with with higher seq nr -> ok
newSequenceNumber = 5;
hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
signature = Sig.sign(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
dataToRemove = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertTrue(dataStorage1.remove(dataToRemove, null));
@ -237,7 +236,7 @@ public class ProtectedDataStorageTest {
// receiver (storageSignatureKeyPair2)
int newSequenceNumber = data.sequenceNumber + 1;
byte[] hashOfDataAndSeqNr = Hash.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
byte[] hashOfDataAndSeqNr = Hash.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
byte[] signature;
ProtectedMailboxData dataToRemove;
@ -283,7 +282,7 @@ public class ProtectedDataStorageTest {
// hackers key pair is storageSignatureKeyPair2
// change seq nr. and signature: fails on both own and peers dataStorage
int newSequenceNumber = data.sequenceNumber + 1;
byte[] hashOfDataAndSeqNr = cryptoService2.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
byte[] hashOfDataAndSeqNr = cryptoService2.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
byte[] signature = cryptoService2.signStorageData(storageSignatureKeyPair2.getPrivate(), hashOfDataAndSeqNr);
ProtectedData dataToAdd = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertFalse(dataStorage1.add(dataToAdd, null));
@ -291,7 +290,7 @@ public class ProtectedDataStorageTest {
// change seq nr. and signature and data pub key. fails on peers dataStorage, succeeds on own dataStorage
newSequenceNumber = data.sequenceNumber + 2;
hashOfDataAndSeqNr = cryptoService2.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
hashOfDataAndSeqNr = cryptoService2.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
signature = cryptoService2.signStorageData(storageSignatureKeyPair2.getPrivate(), hashOfDataAndSeqNr);
dataToAdd = new ProtectedData(data.expirablePayload, data.ttl, storageSignatureKeyPair2.getPublic(), newSequenceNumber, signature);
Assert.assertTrue(dataStorage2.add(dataToAdd, null));
@ -305,7 +304,7 @@ public class ProtectedDataStorageTest {
Assert.assertNotEquals(data, dataToAdd);
newSequenceNumber = data.sequenceNumber + 3;
hashOfDataAndSeqNr = cryptoService1.getHash(new DataAndSeqNr(data.expirablePayload, newSequenceNumber));
hashOfDataAndSeqNr = cryptoService1.getHash(new P2PDataStorage.DataAndSeqNrPair(data.expirablePayload, newSequenceNumber));
signature = cryptoService1.signStorageData(storageSignatureKeyPair1.getPrivate(), hashOfDataAndSeqNr);
ProtectedData dataToRemove = new ProtectedData(data.expirablePayload, data.ttl, data.ownerStoragePubKey, newSequenceNumber, signature);
Assert.assertTrue(dataStorage1.remove(dataToRemove, null));
@ -328,7 +327,7 @@ public class ProtectedDataStorageTest {
// receiver (storageSignatureKeyPair2)
int newSequenceNumber = data.sequenceNumber + 1;
byte[] hashOfDataAndSeqNr = cryptoService2.getHash(new DataAndSeqNr(expirableMailboxPayload, newSequenceNumber));
byte[] hashOfDataAndSeqNr = cryptoService2.getHash(new P2PDataStorage.DataAndSeqNrPair(expirableMailboxPayload, newSequenceNumber));
byte[] signature;
ProtectedMailboxData dataToRemove;