Package net.tomp2p.dht

Source Code of net.tomp2p.dht.TestSecurity

package net.tomp2p.dht;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.SignatureException;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.crypto.Cipher;

import net.tomp2p.connection.*;
import net.tomp2p.connection.ChannelServerConfiguration;
import net.tomp2p.dht.StorageLayer.ProtectionEnable;
import net.tomp2p.dht.StorageLayer.ProtectionMode;
import net.tomp2p.message.RSASignatureCodec;
import net.tomp2p.message.SignatureCodec;
import net.tomp2p.p2p.PeerBuilder;
import net.tomp2p.p2p.RequestP2PConfiguration;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.Number640;
import net.tomp2p.storage.Data;
import net.tomp2p.utils.Utils;

import org.junit.Assert;
import org.junit.Test;

public class TestSecurity {
    final private static Random rnd = new Random(42L);
    private static final DSASignatureFactory factory = new DSASignatureFactory();

    @Test
    public void testPublicKeyReceived() throws Exception {
        final Random rnd = new Random(43L);
        PeerDHT master = null;
        PeerDHT slave1 = null;
        KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
        KeyPair pair1 = gen.generateKeyPair();
        KeyPair pair2 = gen.generateKeyPair();
        // make master
        try {
          final AtomicBoolean gotPK = new AtomicBoolean(false);
            // set storage to test PK
          StorageLayer sl = new StorageLayer(new StorageMemory()) {
              @Override
              public Enum<?> put(Number640 key, Data newData, PublicKey publicKey, boolean putIfAbsent,
                  boolean domainProtection) {
                System.err.println("P is " + publicKey);
                    gotPK.set(publicKey != null);
                    System.err.println("PK is " + gotPK);
                return super.put(key, newData, publicKey, putIfAbsent, domainProtection);
              }
            };
         
            master = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair1).ports(4001).start()).start();
            // make slave
            slave1 = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair2).masterPeer(master.peer()).start()).storageLayer(sl).start();
           
            // perfect routing
            boolean peerInMap1 = master.peerBean().peerMap().peerFound(slave1.peerAddress(), null, null);
            boolean peerInMap2 = slave1.peerBean().peerMap().peerFound(master.peerAddress(), null, null);
            Assert.assertEquals(true, peerInMap1);
            Assert.assertEquals(true, peerInMap2);
            //
            Number160 locationKey = new Number160(50);

            RequestP2PConfiguration rc = new RequestP2PConfiguration(1, 1, 0);
            master.put(locationKey).data(new Data(new byte[100000])).requestP2PConfiguration(rc).sign()
                    .start().awaitUninterruptibly();
            // master.put(locationKey, new Data("test"),
            // cs1).awaitUninterruptibly();
            Assert.assertEquals(true, gotPK.get());
            // without PK, this test should fail.
            master.put(locationKey).data(new Data("test1")).requestP2PConfiguration(rc).start()
                    .awaitUninterruptibly();
            Assert.assertEquals(false, gotPK.get());
        } finally {
            master.shutdown();
            slave1.shutdown();
        }
    }

    @Test
    public void testPublicKeyReceivedDomain() throws Exception {
        final Random rnd = new Random(43L);
        PeerDHT master = null;
        try {
            KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
            KeyPair pair1 = gen.generateKeyPair();
           
            final AtomicBoolean gotPK = new AtomicBoolean(false);
            // set storage to test PK
            StorageLayer sl =new StorageLayer(new StorageMemory()) {
              @Override
              public Enum<?> put(Number640 key, Data newData, PublicKey publicKey, boolean putIfAbsent,
                  boolean domainProtection) {
                    gotPK.set(publicKey != null);
                    System.err.println("PK is " + gotPK);
                    return super.put(key, newData, publicKey, putIfAbsent, domainProtection);
                }
            };
           
            // make master
            master = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair1).ports(4001).start()).storageLayer(sl).start();
           
            //
            Number160 locationKey = new Number160(50);
            RequestP2PConfiguration rc = new RequestP2PConfiguration(1, 1, 0);
            master.put(locationKey).data(Number160.ONE, new Data(new byte[2000])).requestP2PConfiguration(rc)
                    .domainKey(Number160.ONE).sign().start().awaitUninterruptibly();
            Assert.assertEquals(true, gotPK.get());
            // without PK
            master.put(locationKey).data(Number160.ONE, new Data("test1")).requestP2PConfiguration(rc)
                    .domainKey(Number160.ONE).start().awaitUninterruptibly();
            Assert.assertEquals(false, gotPK.get());
        } catch (Throwable t) {
          Assert.fail(t.getMessage());
          t.printStackTrace();
        } finally {
            master.shutdown();
        }
    }

    @Test
    public void testProtection() throws Exception {
        final Random rnd = new Random(43L);
        PeerDHT master = null;
        PeerDHT slave1 = null;
        PeerDHT slave2 = null;
        KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
        KeyPair pair1 = gen.generateKeyPair();
        KeyPair pair2 = gen.generateKeyPair();
        KeyPair pair3 = gen.generateKeyPair();
        System.err.println("PPK1 " + pair1.getPublic());
        System.err.println("PPK2 " + pair2.getPublic());
        System.err.println("PPK3 " + pair3.getPublic());
        try {
            master = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair1).ports(4001).start()).start();
            master
                    .storageLayer()
                    .protection(ProtectionEnable.ALL, ProtectionMode.MASTER_PUBLIC_KEY, ProtectionEnable.ALL,
                            ProtectionMode.MASTER_PUBLIC_KEY);
            slave1 = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair2).masterPeer(master.peer()).start()).start();
            slave1.storageLayer()
                    .protection(ProtectionEnable.ALL, ProtectionMode.MASTER_PUBLIC_KEY, ProtectionEnable.ALL,
                            ProtectionMode.MASTER_PUBLIC_KEY);
            slave2 = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair3).masterPeer(master.peer()).start()).start();
            slave2.storageLayer()
                    .protection(ProtectionEnable.ALL, ProtectionMode.MASTER_PUBLIC_KEY, ProtectionEnable.ALL,
                            ProtectionMode.MASTER_PUBLIC_KEY);
            // perfect routing
            master.peerBean().peerMap().peerFound(slave1.peerAddress(), null, null);
            master.peerBean().peerMap().peerFound(slave2.peerAddress(), null, null);
            //
            slave1.peerBean().peerMap().peerFound(master.peerAddress(), null, null);
            slave1.peerBean().peerMap().peerFound(slave2.peerAddress(), null, null);
            //
            slave2.peerBean().peerMap().peerFound(master.peerAddress(), null, null);
            slave2.peerBean().peerMap().peerFound(slave1.peerAddress(), null, null);
            Number160 locationKey = new Number160(50);
            FuturePut fdht1 = master.put(locationKey).data(new Number160(10), new Data("test1"))
                    .domainKey(Utils.makeSHAHash(pair3.getPublic().getEncoded())).protectDomain().start();
            fdht1.awaitUninterruptibly();
            Assert.assertEquals(true, fdht1.isSuccess());
            // try to insert in same domain from different peer
            FuturePut fdht2 = slave1.put(locationKey).data(new Number160(11), new Data("tes2"))
                    .domainKey(Utils.makeSHAHash(pair3.getPublic().getEncoded())).protectDomain().start();
            fdht2.awaitUninterruptibly();
            Assert.assertEquals(false, fdht2.isSuccess());
            // insert from same peer but with public key protection
            FuturePut fdht3 = slave2.put(locationKey).data(new Number160(12), new Data("tes2"))
                    .domainKey(Utils.makeSHAHash(pair3.getPublic().getEncoded())).protectDomain().start();
            fdht3.awaitUninterruptibly();
            Assert.assertEquals(true, fdht3.isSuccess());
            //
            // get at least 3 results, because we want to test the domain
            // removel feature
            RequestP2PConfiguration rc = new RequestP2PConfiguration(3, 3, 3);
            FutureGet fdht4 = slave1.get(locationKey).all().requestP2PConfiguration(rc)
                    .domainKey(Utils.makeSHAHash(pair3.getPublic().getEncoded())).start();
            fdht4.awaitUninterruptibly();
            Assert.assertEquals(true, fdht4.isSuccess());
            Assert.assertEquals(2, fdht4.dataMap().size());
        } finally {
            master.shutdown();
            slave1.shutdown();
            slave2.shutdown();
        }
    }

    @Test
    public void testProtectionWithRemove() throws Exception {
        final Random rnd = new Random(42L);
        PeerDHT master = null;
        PeerDHT slave1 = null;
        PeerDHT slave2 = null;
        KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
        KeyPair pair1 = gen.generateKeyPair();
        KeyPair pair2 = gen.generateKeyPair();
        KeyPair pair3 = gen.generateKeyPair();
        System.err.println("PPK1 " + pair1.getPublic());
        System.err.println("PPK2 " + pair2.getPublic());
        System.err.println("PPK3 " + pair3.getPublic());
        try {
            master = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair1).ports(4001).start()).start();
            master.storageLayer()
                    .protection(ProtectionEnable.ALL, ProtectionMode.MASTER_PUBLIC_KEY, ProtectionEnable.ALL,
                            ProtectionMode.MASTER_PUBLIC_KEY);
            slave1 = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair2).masterPeer(master.peer()).start()).start();
            slave1.storageLayer()
                    .protection(ProtectionEnable.ALL, ProtectionMode.MASTER_PUBLIC_KEY, ProtectionEnable.ALL,
                            ProtectionMode.MASTER_PUBLIC_KEY);
            slave2 = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair3).masterPeer(master.peer()).start()).start();
            slave2.storageLayer()
                    .protection(ProtectionEnable.ALL, ProtectionMode.MASTER_PUBLIC_KEY, ProtectionEnable.ALL,
                            ProtectionMode.MASTER_PUBLIC_KEY);
            // perfect routing
            master.peerBean().peerMap().peerFound(slave1.peerAddress(), null, null);
            master.peerBean().peerMap().peerFound(slave2.peerAddress(), null, null);
            //
            slave1.peerBean().peerMap().peerFound(master.peerAddress(), null, null);
            slave1.peerBean().peerMap().peerFound(slave2.peerAddress(), null, null);
            //
            slave2.peerBean().peerMap().peerFound(master.peerAddress(), null, null);
            slave2.peerBean().peerMap().peerFound(slave1.peerAddress(), null, null);
            Number160 locationKey = new Number160(50);
            FuturePut fdht1 = master.put(locationKey).data(new Data("test1"))
                    .domainKey(Utils.makeSHAHash(pair1.getPublic().getEncoded())).protectDomain().start();
            fdht1.awaitUninterruptibly();
            // remove from different peer, should fail
            FutureRemove fdht2 = slave1.remove(locationKey)
                    .domainKey(Utils.makeSHAHash(pair1.getPublic().getEncoded())).sign().start();
            fdht2.awaitUninterruptibly();
            Assert.assertFalse(fdht2.isSuccess());
            // this should work
            FutureRemove fdht3 = master.remove(locationKey)
                    .domainKey(Utils.makeSHAHash(pair1.getPublic().getEncoded())).sign().start();
            fdht3.awaitUninterruptibly();
            Assert.assertTrue(fdht3.isSuccess());
        } finally {
            master.shutdown();
            slave1.shutdown();
            slave2.shutdown();
        }
    }

    @Test
    public void testProtectionDomain() throws Exception {
        final Random rnd = new Random(43L);
        PeerDHT master = null;
        PeerDHT slave1 = null;
        KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
        KeyPair pair1 = gen.generateKeyPair();
        KeyPair pair2 = gen.generateKeyPair();
        // make master
        try {
         
          StorageLayer slm =new StorageLayer(new StorageMemory()) {
              @Override
              public Enum<?> put(Number640 key, Data newData, PublicKey publicKey, boolean putIfAbsent,
                  boolean domainProtection) {
                    // System.out.println("store1");
                return super.put(key, newData, publicKey, putIfAbsent, domainProtection);
                }
            };
            StorageLayer sls =new StorageLayer(new StorageMemory()) {
              @Override
              public Enum<?> put(Number640 key, Data newData, PublicKey publicKey, boolean putIfAbsent,
                  boolean domainProtection) {
                    // System.out.println("store2");
                return super.put(key, newData, publicKey, putIfAbsent, domainProtection);
                }
            };
         
            master = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair1).ports(4001).start()).storageLayer(slm).start();
            // make slave
            slave1 = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair2).masterPeer(master.peer()).start()).storageLayer(sls).start();
           
            // perfect routing
            boolean peerInMap1 = master.peerBean().peerMap().peerFound(slave1.peerAddress(), null, null);
            boolean peerInMap2 = slave1.peerBean().peerMap().peerFound(master.peerAddress(), null, null);
            Assert.assertEquals(true, peerInMap1);
            Assert.assertEquals(true, peerInMap2);

            // since we have to peers, we store on both, otherwise this test may
            // sometimes work, sometimes not.
            RequestP2PConfiguration rc = new RequestP2PConfiguration(1, 1, 1);
            Number160 locationKey = Number160.createHash("loctaion");
            FuturePut futureDHT = master.put(locationKey).data(Number160.createHash("content1"), new Data("test1"))
                    .domainKey(Number160.createHash("domain1")).protectDomain().requestP2PConfiguration(rc)
                    .start();
            futureDHT.awaitUninterruptibly();
            Assert.assertEquals(true, futureDHT.isSuccess());
            // now the slave stores with different in the same domain. This
            // should not work
            futureDHT = slave1.put(locationKey).data(Number160.createHash("content2"), new Data("test2"))
                    .domainKey(Number160.createHash("domain1")).protectDomain().requestP2PConfiguration(rc)
                    .start();
            futureDHT.awaitUninterruptibly();
            System.err.println(futureDHT.failedReason());
            Assert.assertEquals(false, futureDHT.isSuccess());
        } finally {
            master.shutdown();
            slave1.shutdown();
        }
    }

    @Test
    public void testSecurePutGet1() throws Exception {
        PeerDHT master = null;
        PeerDHT slave1 = null;
        PeerDHT slave2 = null;
        KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
        KeyPair pair1 = gen.generateKeyPair();
        KeyPair pair2 = gen.generateKeyPair();
        KeyPair pair3 = gen.generateKeyPair();
        System.err.println("PPK1 " + pair1.getPublic());
        System.err.println("PPK2 " + pair2.getPublic());
        System.err.println("PPK3 " + pair3.getPublic());
        try {

            // make slave
            master = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair1).ports(4001).start()).start();
            master.storageLayer()
                    .protection(ProtectionEnable.ALL, ProtectionMode.MASTER_PUBLIC_KEY, ProtectionEnable.ALL,
                            ProtectionMode.MASTER_PUBLIC_KEY);
            slave1 = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair2).masterPeer(master.peer()).start()).start();
            slave1.storageLayer()
                    .protection(ProtectionEnable.ALL, ProtectionMode.MASTER_PUBLIC_KEY, ProtectionEnable.ALL,
                            ProtectionMode.MASTER_PUBLIC_KEY);
            slave2 = new PeerBuilderDHT(new PeerBuilder(new Number160(rnd)).keyPair(pair3).masterPeer(master.peer()).start()).start();
            slave2.storageLayer()
                    .protection(ProtectionEnable.ALL, ProtectionMode.MASTER_PUBLIC_KEY, ProtectionEnable.ALL,
                            ProtectionMode.MASTER_PUBLIC_KEY);
            // perfect routing
            master.peerBean().peerMap().peerFound(slave1.peerAddress(), null, null);
            master.peerBean().peerMap().peerFound(slave2.peerAddress(), null, null);
            //
            slave1.peerBean().peerMap().peerFound(master.peerAddress(), null, null);
            slave1.peerBean().peerMap().peerFound(slave2.peerAddress(), null, null);
            //
            slave2.peerBean().peerMap().peerFound(master.peerAddress(), null, null);
            slave2.peerBean().peerMap().peerFound(slave1.peerAddress(), null, null);
            Number160 locationKey = new Number160(50);

            Data data1 = new Data("test1");
            data1.protectEntry(pair1);
            FuturePut fdht1 = master.put(locationKey).data(data1).sign().start();
            fdht1.awaitUninterruptibly();
            fdht1.futureRequests().awaitUninterruptibly();
            Assert.assertEquals(true, fdht1.isSuccess());
            // store again
            Data data2 = new Data("test1");
            data2.protectEntry(pair2);
            FuturePut fdht2 = slave1.put(locationKey).data(data2).sign().start();
            fdht2.awaitUninterruptibly();
            fdht2.futureRequests().awaitUninterruptibly();
            Assert.assertEquals(0, fdht2.result().size());
            Assert.assertEquals(false, fdht2.isSuccess());
            // Utils.sleep(1000000);
            // try to remove it, will fail since we do not sign
            FutureRemove fdht3 = slave2.remove(locationKey).start();
            fdht3.awaitUninterruptibly();
            // false, since we have domain protection yet
            Assert.assertEquals(false, fdht3.isSuccess());
            // try to put another thing
            Data data3 = new Data("test2");
            data3.protectEntry(pair1);
            FuturePut fdht4 = master.put(locationKey).sign().data(new Number160(33), data3).start();
            fdht4.awaitUninterruptibly();
            fdht4.futureRequests().awaitUninterruptibly();
            Assert.assertEquals(true, fdht4.isSuccess());
            // get it
            FutureGet fdht7 = slave2.get(locationKey).all().start();
            fdht7.awaitUninterruptibly();
            Assert.assertEquals(2, fdht7.dataMap().size());
            Assert.assertEquals(true, fdht7.isSuccess());
            // if(true)
            // System.exit(0);
            // try to remove for real, all
            FutureRemove fdht5 = master.remove(locationKey).sign().all().sign().start();
            fdht5.awaitUninterruptibly();
            System.err.println(fdht5.failedReason());
            Assert.assertEquals(true, fdht5.isSuccess());
            // get all, they should be removed now
            FutureGet fdht6 = slave2.get(locationKey).all().start();
            fdht6.awaitUninterruptibly();
            Assert.assertEquals(0, fdht6.dataMap().size());
            Assert.assertEquals(false, fdht6.isSuccess());
            // put there the data again...
            FuturePut fdht8 = slave1.put(locationKey)
                    .data(Utils.makeSHAHash(pair1.getPublic().getEncoded()), new Data("test1")).sign().start();
            fdht8.awaitUninterruptibly();
            fdht8.futureRequests().awaitUninterruptibly();
            Assert.assertEquals(true, fdht8.isSuccess());
            // overwrite
            Data data4 = new Data("test1");
            data4.protectEntry(pair1);
            FuturePut fdht9 = master.put(locationKey).data(Utils.makeSHAHash(pair1.getPublic().getEncoded()), data4).sign()
                    .start();
            fdht9.awaitUninterruptibly();
            fdht9.futureRequests().awaitUninterruptibly();
            System.err.println("reason " + fdht9.failedReason());
            Assert.assertEquals(true, fdht9.isSuccess());
        } finally {
            // Utils.sleep(1000000);
            master.shutdown();
            slave1.shutdown();
            slave2.shutdown();
        }
    }
   
    @Test
    public void testContentProtectoin() throws IOException, ClassNotFoundException, NoSuchAlgorithmException, InterruptedException, InvalidKeyException, SignatureException {
        KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");

        KeyPair keyPairPeer1 = gen.generateKeyPair();
        PeerDHT p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4838)
                .keyPair(keyPairPeer1).start()).start();
        KeyPair keyPairPeer2 = gen.generateKeyPair();
        PeerDHT p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).masterPeer(p1.peer())
                .keyPair(keyPairPeer2).start()).start();

        p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
        p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();
        KeyPair keyPair = gen.generateKeyPair();

        String locationKey = "location";
        Number160 lKey = Number160.createHash(locationKey);
        String contentKey = "content";
        Number160 cKey = Number160.createHash(contentKey);

        String testData1 = "data1";
        Data data = new Data(testData1).protectEntry(keyPair);
        // put trough peer 1 with key pair -------------------------------------------------------
        FuturePut futurePut1 = p1.put(lKey).data(cKey, data).keyPair(keyPair).start();
        futurePut1.awaitUninterruptibly();
        Assert.assertTrue(futurePut1.isSuccess());

        FutureGet futureGet1a = p1.get(lKey).contentKey(cKey).start();
        futureGet1a.awaitUninterruptibly();

        Assert.assertTrue(futureGet1a.isSuccess());
        Assert.assertEquals(testData1, (String) futureGet1a.data().object());
        FutureGet futureGet1b = p2.get(lKey).contentKey(cKey).start();
        futureGet1b.awaitUninterruptibly();

        Assert.assertTrue(futureGet1b.isSuccess());
        Assert.assertEquals(testData1, (String) futureGet1b.data().object());
        // put trough peer 2 without key pair ----------------------------------------------------
        String testData2 = "data2";
        Data data2 = new Data(testData2);
        FuturePut futurePut2 = p2.put(lKey).data(cKey, data2).start();
        futurePut2.awaitUninterruptibly();
        //PutStatus.FAILED_SECURITY
        Assert.assertFalse(futurePut2.isSuccess());
       
        FutureGet futureGet2 = p2.get(lKey).contentKey(cKey).start();
        futureGet2.awaitUninterruptibly();
        Assert.assertTrue(futureGet2.isSuccess());
        // should have been not modified
        Assert.assertEquals(testData1, (String) futureGet2.data().object());
        // put trough peer 1 without key pair ----------------------------------------------------
        String testData3 = "data3";
        Data data3 = new Data(testData3);
        FuturePut futurePut3 = p2.put(lKey).data(cKey, data3).start();
        futurePut3.awaitUninterruptibly();

        // FAILED_SECURITY?
        Assert.assertFalse(futurePut3.isSuccess());
       
        FutureGet futureGet3 = p2.get(lKey).contentKey(cKey).start();
        futureGet3.awaitUninterruptibly();
        Assert.assertTrue(futureGet3.isSuccess());
        // should have been not modified ---> why it has been modified without giving a key pair?
        Assert.assertEquals(testData1, (String) futureGet3.data().object());
        Assert.assertEquals(keyPair.getPublic(), futureGet3.data().publicKey());
       
        //now we store a signed data object and we will get back the public key as well
        data = new Data("Juhuu").protectEntryNow(keyPair, factory);
        FuturePut futurePut4 = p1.put(lKey).data(cKey, data).keyPair(keyPair).start();
        futurePut4.awaitUninterruptibly();
        Assert.assertTrue(futurePut4.isSuccess());
        FutureGet futureGet4 = p2.get(lKey).contentKey(cKey).start();
        futureGet4.awaitUninterruptibly();
        Assert.assertTrue(futureGet4.isSuccess());
        // should have been not modified ---> why it has been modified without giving a key pair?
        Assert.assertEquals("Juhuu", (String) futureGet4.data().object());
        Assert.assertEquals(keyPair.getPublic(), futureGet4.data().publicKey());
       

        p1.shutdown().awaitUninterruptibly();
        p2.shutdown().awaitUninterruptibly();
    }
   
    @Test
    public void testContentProtectoinGeneric() throws IOException, ClassNotFoundException, NoSuchAlgorithmException, InterruptedException, InvalidKeyException, SignatureException {
        KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");

        KeyPair keyPair = gen.generateKeyPair();
        PeerDHT p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4838)
                .keyPair(keyPair).start()).start();
       
        String locationKey = "location";
        Number160 lKey = Number160.createHash(locationKey);
        String contentKey = "content";
        Number160 cKey = Number160.createHash(contentKey);
       
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<1000;i++) {
          sb.append(i);
        }
       
        Data data = new Data(sb.toString()).protectEntryNow(keyPair, factory);
        FuturePut futurePut4 = p1.put(lKey).data(cKey, data).keyPair(keyPair).start();
        futurePut4.awaitUninterruptibly();
        System.err.println(futurePut4.failedReason());
        Assert.assertTrue(futurePut4.isSuccess());
        FutureGet futureGet4 = p1.get(lKey).contentKey(cKey).start();
        futureGet4.awaitUninterruptibly();
        Assert.assertTrue(futureGet4.isSuccess());
        // should have been not modified ---> why it has been modified without giving a key pair?
        Assert.assertEquals(sb.toString(), (String) futureGet4.data().object());
        Assert.assertEquals(keyPair.getPublic(), futureGet4.data().publicKey());
       
       
        p1.shutdown().awaitUninterruptibly();
    }
   
    @Test
    public void testVersionContentProtectoinGeneric() throws IOException, ClassNotFoundException, NoSuchAlgorithmException, InterruptedException, InvalidKeyException, SignatureException {
        KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");

        KeyPair keyPair1 = gen.generateKeyPair();
        KeyPair keyPair2 = gen.generateKeyPair();
        PeerDHT p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4838)
                .keyPair(keyPair1).start()).start();
        PeerDHT p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).ports(4839)
                .keyPair(keyPair2).start()).start();
       
        p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
        p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();
       
        String locationKey = "location";
        Number160 lKey = Number160.createHash(locationKey);
        String contentKey = "content";
        Number160 cKey = Number160.createHash(contentKey);
       
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<1000;i++) {
          sb.append(i);
        }
       
        Data data1 = new Data(sb.toString()).protectEntryNow(keyPair1, factory);
       
        FuturePut futurePut4 = p1.put(lKey).data(cKey, data1).keyPair(keyPair1).versionKey(Number160.ZERO).start();
        futurePut4.awaitUninterruptibly();
        Assert.assertTrue(futurePut4.isSuccess());
       
        Data data2 = new Data(sb.toString()).protectEntryNow(keyPair2, factory);
       
        FuturePut futurePut5 = p2.put(lKey).data(cKey, data2).keyPair(keyPair2).versionKey(Number160.ONE).start();
        futurePut5.awaitUninterruptibly();
        Assert.assertTrue(!futurePut5.isSuccess());
       
        Data data3 = new Data(sb.toString()).protectEntryNow(keyPair2, factory);
        FuturePut futurePut6 = p1.put(lKey).data(cKey, data3).keyPair(keyPair1).versionKey(Number160.MAX_VALUE).start();
        futurePut6.awaitUninterruptibly();
        Assert.assertTrue(futurePut6.isSuccess());
       
        FuturePut futurePut7 = p2.put(lKey).data(cKey, data2).keyPair(keyPair2).versionKey(Number160.ONE).start();
        futurePut7.awaitUninterruptibly();
        Assert.assertTrue(futurePut7.isSuccess());
       
       
        p1.shutdown().awaitUninterruptibly();
        p2.shutdown().awaitUninterruptibly();
    }
   
    @Test
    public void testChangeDomainProtectionKey() throws IOException, ClassNotFoundException, NoSuchAlgorithmException, InterruptedException, InvalidKeyException, SignatureException {
        KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");

        KeyPair keyPair1 = gen.generateKeyPair();
        KeyPair keyPair2 = gen.generateKeyPair();
        PeerDHT p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4838)
                .keyPair(keyPair1).start()).start();
        PeerDHT p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).ports(4839)
                .keyPair(keyPair2).start()).start();
       
        p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
        p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();
       
        Data data = new Data("test");
        FuturePut fp1 = p1.put(Number160.createHash("key1")).protectDomain().data(data).start().awaitUninterruptibly();
        Assert.assertTrue(fp1.isSuccess());
        FuturePut fp2 = p2.put(Number160.createHash("key1")).protectDomain().data(data).start().awaitUninterruptibly();
        Assert.assertTrue(!fp2.isSuccess());
       
        FuturePut fp3 = p1.put(Number160.createHash("key1")).changePublicKey(keyPair2.getPublic()).start().awaitUninterruptibly();
        Assert.assertTrue(fp3.isSuccess());
        FuturePut fp4 = p2.put(Number160.createHash("key1")).protectDomain().data(data).start().awaitUninterruptibly();
        Assert.assertTrue(fp4.isSuccess());
       
        p1.shutdown().awaitUninterruptibly();
        p2.shutdown().awaitUninterruptibly();
    }
   
    @Test
    public void testChangeEntryProtectionKey() throws IOException, ClassNotFoundException, NoSuchAlgorithmException, InterruptedException, InvalidKeyException, SignatureException {
        KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");

        KeyPair keyPair1 = gen.generateKeyPair();
        KeyPair keyPair2 = gen.generateKeyPair();
        PeerDHT p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4838)
                .keyPair(keyPair1).start()).start();
        PeerDHT p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).ports(4839)
                .keyPair(keyPair2).start()).start();
       
        p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
        p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();
       
        Data data = new Data("test").protectEntry(keyPair1);
        FuturePut fp1 = p1.put(Number160.createHash("key1")).sign().data(data).start().awaitUninterruptibly();
        Assert.assertTrue(fp1.isSuccess());
        FuturePut fp2 = p2.put(Number160.createHash("key1")).data(data).start().awaitUninterruptibly();
        Assert.assertTrue(!fp2.isSuccess());
       
        Data data2 = new Data().protectEntry(keyPair2);
        data2.publicKey(keyPair2.getPublic());
        FuturePut fp3 = p1.put(Number160.createHash("key1")).sign().putMeta().data(data2).start().awaitUninterruptibly();
        Assert.assertTrue(fp3.isSuccess());
       
        FuturePut fp4 = p2.put(Number160.createHash("key1")).sign().data(data).start().awaitUninterruptibly();
        Assert.assertTrue(fp4.isSuccess());  
       
        p1.shutdown().awaitUninterruptibly();
        p2.shutdown().awaitUninterruptibly();
    }
   
    @Test
    public void testChangeEntryProtectionKeySignature() throws IOException, ClassNotFoundException, NoSuchAlgorithmException, InterruptedException, InvalidKeyException, SignatureException {
        KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");

        KeyPair keyPair1 = gen.generateKeyPair();
        KeyPair keyPair2 = gen.generateKeyPair();
        PeerDHT p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4838)
                .keyPair(keyPair1).start()).start();
        PeerDHT p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).ports(4839)
                .keyPair(keyPair2).start()).start();
       
        p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
        p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();
       
        Data data = new Data("test1").protectEntryNow(keyPair1, factory);
        FuturePut fp1 = p1.put(Number160.createHash("key1")).sign().data(data).start().awaitUninterruptibly();
        Assert.assertTrue(fp1.isSuccess());
        FuturePut fp2 = p2.put(Number160.createHash("key1")).data(data).start().awaitUninterruptibly();
        Assert.assertTrue(!fp2.isSuccess());
       
        Data data2 = new Data("test1").protectEntryNow(keyPair2, factory).duplicateMeta();
        FuturePut fp3 = p1.put(Number160.createHash("key1")).sign().putMeta().data(data2).start().awaitUninterruptibly();
        Assert.assertTrue(fp3.isSuccess());
       
        Data retData = p2.get(Number160.createHash("key1")).start().awaitUninterruptibly().data();
        Assert.assertTrue(retData.verify(keyPair2.getPublic(), factory));
       
        p1.shutdown().awaitUninterruptibly();
        p2.shutdown().awaitUninterruptibly();
    }
   
  @Test
  public void testTTLUpdate() throws IOException, ClassNotFoundException, NoSuchAlgorithmException,
          InterruptedException, InvalidKeyException, SignatureException {

    PeerDHT p1 = null;
    PeerDHT p2 = null;

    try {
      StorageMemory sm1 = new StorageMemory(1);
      StorageMemory sm2 = new StorageMemory(1);
      p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1))
              .ports(4838).start()).storage(sm1).start();
      p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2))
              .ports(4839).start()).storage(sm2).start();

      p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
      p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();

      Data data = new Data("test1");
      data.ttlSeconds(1);
      FuturePut fp1 = p1.put(Number160.createHash("key1")).data(data).start().awaitUninterruptibly();
      Assert.assertTrue(fp1.isSuccess());

      Thread.sleep(2000);
      Data retData = p2.get(Number160.createHash("key1")).start().awaitUninterruptibly().data();
      Assert.assertNull(retData);

      FuturePut fp2 = p1.put(Number160.createHash("key1")).data(data).start().awaitUninterruptibly();
      Assert.assertTrue(fp2.isSuccess());

      Data update = data.duplicateMeta();
      update.ttlSeconds(10);

      FuturePut fp3 = p1.put(Number160.createHash("key1")).putMeta().data(update).start()
              .awaitUninterruptibly();
      System.err.println(fp3.failedReason());
      Assert.assertTrue(fp3.isSuccess());

      Thread.sleep(1000);
      retData = p2.get(Number160.createHash("key1")).start().awaitUninterruptibly().data();
      Assert.assertEquals("test1", retData.object());
    } finally {
      p1.shutdown().awaitUninterruptibly();
      p2.shutdown().awaitUninterruptibly();
    }
  }
   
   
  @Test
  public void testRemoveFromTo2() throws NoSuchAlgorithmException, IOException, InvalidKeyException,
          SignatureException, ClassNotFoundException {
    KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");

    KeyPair keyPairPeer1 = gen.generateKeyPair();
    PeerDHT p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4838).keyPair(keyPairPeer1)
            .start()).start();
    KeyPair keyPairPeer2 = gen.generateKeyPair();
    PeerDHT p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).masterPeer(p1.peer()).keyPair(keyPairPeer2)
            .start()).start();

    p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
    p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();

    KeyPair key1 = gen.generateKeyPair();

    String locationKey = "location";
    Number160 lKey = Number160.createHash(locationKey);
    String domainKey = "domain";
    Number160 dKey = Number160.createHash(domainKey);
    String contentKey = "content";
    Number160 cKey = Number160.createHash(contentKey);

    String testData1 = "data1";
    Data data = new Data(testData1).protectEntryNow(key1, factory);

    // put trough peer 1 with key pair
    // -------------------------------------------------------

    FuturePut futurePut1 = p1.put(lKey).domainKey(dKey).data(cKey, data).keyPair(key1).start();
    futurePut1.awaitUninterruptibly();
    Assert.assertTrue(futurePut1.isSuccess());

    FutureGet futureGet1a = p1.get(lKey).domainKey(dKey).contentKey(cKey).start();
    futureGet1a.awaitUninterruptibly();
    Assert.assertTrue(futureGet1a.isSuccess());
    Assert.assertEquals(testData1, (String) futureGet1a.data().object());

    FutureGet futureGet1b = p2.get(lKey).domainKey(dKey).contentKey(cKey).start();
    futureGet1b.awaitUninterruptibly();
    Assert.assertTrue(futureGet1b.isSuccess());
    Assert.assertEquals(testData1, (String) futureGet1b.data().object());

    // remove with correct key pair
    // -----------------------------------------------------------

    FutureRemove futureRemove4 = p1.remove(lKey).from(new Number640(lKey, dKey, cKey, Number160.ZERO))
            .to(new Number640(lKey, dKey, cKey, Number160.MAX_VALUE)).keyPair(key1).start();
    futureRemove4.awaitUninterruptibly();
    Assert.assertTrue(futureRemove4.isSuccess());

    FutureGet futureGet4a = p2.get(lKey).domainKey(dKey).contentKey(cKey).start();
    futureGet4a.awaitUninterruptibly();
    // we did not find the data
    Assert.assertTrue(futureGet4a.isFailed());
    // should have been removed
    Assert.assertNull(futureGet4a.data());

    FutureGet futureGet4b = p2.get(lKey).contentKey(cKey).start();
    futureGet4b.awaitUninterruptibly();
    // we did not find the data
    Assert.assertTrue(futureGet4b.isFailed());
    // should have been removed
    Assert.assertNull(futureGet4b.data());

    p1.shutdown().awaitUninterruptibly();
    p2.shutdown().awaitUninterruptibly();
  }
 
  @Test
  public void testRemoveFutureResponse() throws NoSuchAlgorithmException, IOException, InvalidKeyException,
          SignatureException, ClassNotFoundException {
    KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");

    KeyPair keyPairPeer1 = gen.generateKeyPair();
    PeerDHT p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4838).keyPair(keyPairPeer1)
            .start()).start();
    KeyPair keyPairPeer2 = gen.generateKeyPair();
    PeerDHT p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).masterPeer(p1.peer()).keyPair(keyPairPeer2)
            .start()).start();

    p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
    p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();

    KeyPair key1 = gen.generateKeyPair();

    String locationKey = "location";
    Number160 lKey = Number160.createHash(locationKey);
    //String domainKey = "domain";
    //Number160 dKey = Number160.createHash(domainKey);
    String contentKey = "content";
    Number160 cKey = Number160.createHash(contentKey);

    String testData1 = "data1";
    Data data = new Data(testData1).protectEntryNow(key1, factory);
    // put trough peer 1 with key pair
    // -------------------------------------------------------

    FuturePut futurePut1 = p1.put(lKey).data(cKey, data).keyPair(key1).start();
    futurePut1.awaitUninterruptibly();
    Assert.assertTrue(futurePut1.isSuccess());

    FutureGet futureGet1a = p1.get(lKey).contentKey(cKey).start();
    futureGet1a.awaitUninterruptibly();
    Assert.assertTrue(futureGet1a.isSuccess());
    Assert.assertEquals(testData1, (String) futureGet1a.data().object());

    FutureGet futureGet1b = p2.get(lKey).contentKey(cKey).start();
    futureGet1b.awaitUninterruptibly();
    Assert.assertTrue(futureGet1b.isSuccess());
    Assert.assertEquals(testData1, (String) futureGet1b.data().object());

    // try to remove without key pair using the direct remove
    // -------------------------------
    // should fail

    FutureRemove futureRemoveDirect = p1.remove(lKey).contentKey(cKey).start();
    futureRemoveDirect.awaitUninterruptibly();
    // try to remove without key pair using the from/to
    // -------------------------------------
    // should fail
    FutureRemove futureRemoveFromTo = p1.remove(lKey).from(new Number640(lKey, Number160.ZERO, cKey, Number160.ZERO))
            .to(new Number640(lKey, Number160.ZERO, cKey, Number160.MAX_VALUE)).start();
    futureRemoveFromTo.awaitUninterruptibly();

    Assert.assertEquals(futureRemoveDirect.isSuccess(), futureRemoveFromTo.isSuccess());
    Assert.assertFalse(futureRemoveDirect.isSuccess());
    Assert.assertFalse(futureRemoveFromTo.isSuccess());

    p1.shutdown().awaitUninterruptibly();
    p2.shutdown().awaitUninterruptibly();
  }
 
 
  @Test
  public void testChangeProtectionKey() throws NoSuchAlgorithmException, IOException, InvalidKeyException,
          SignatureException, ClassNotFoundException {
    KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
    KeyPair keyPairPeer1 = gen.generateKeyPair();
    PeerDHT p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4834).keyPair(keyPairPeer1)
            .start()).start();
    KeyPair keyPairPeer2 = gen.generateKeyPair();
    PeerDHT p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).masterPeer(p1.peer()).keyPair(keyPairPeer2)
            .start()).start();
    p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
    p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();
    KeyPair keyPair1 = gen.generateKeyPair();
    KeyPair keyPair2 = gen.generateKeyPair();
    Number160 lKey = Number160.createHash("location");
    Number160 dKey = Number160.createHash("domain");
    Number160 cKey = Number160.createHash("content");
    // initial put
    String testData = "data";
    Data data = new Data(testData).protectEntryNow(keyPair1, factory);
    FuturePut futurePut1 = p1.put(lKey).domainKey(dKey).sign().data(cKey, data).keyPair(keyPair1).start();
    futurePut1.awaitUninterruptibly();
    Assert.assertTrue(futurePut1.isSuccess());
    Data retData = p1.get(lKey).domainKey(dKey).contentKey(cKey).start().awaitUninterruptibly().data();
    Assert.assertEquals(testData, (String) retData.object());
    Assert.assertTrue(retData.verify(keyPair1.getPublic(), factory));
    retData = p2.get(lKey).domainKey(dKey).contentKey(cKey).start().awaitUninterruptibly().data();
    Assert.assertEquals(testData, (String) retData.object());
    Assert.assertTrue(retData.verify(keyPair1.getPublic(), factory));
    // change the key pair to the new one using an empty data object
    data = new Data(testData).protectEntryNow(keyPair2, factory).duplicateMeta();
    // use the old protection key to sign the message
    FuturePut futurePut2 = p1.put(lKey).domainKey(dKey).sign().putMeta().data(cKey, data)
            .keyPair(keyPair1).start();
    futurePut2.awaitUninterruptibly();
    Assert.assertTrue(futurePut2.isSuccess());
    retData = p1.get(lKey).domainKey(dKey).contentKey(cKey).start().awaitUninterruptibly().data();
    Assert.assertEquals(testData, (String) retData.object());
    Assert.assertTrue(retData.verify(keyPair2.getPublic(), factory));
    retData = p2.get(lKey).domainKey(dKey).contentKey(cKey).start().awaitUninterruptibly().data();
    Assert.assertEquals(testData, (String) retData.object());
    Assert.assertTrue(retData.verify(keyPair2.getPublic(), factory));
    // should be not possible to modify
    data = new Data().protectEntryNow(keyPair1, factory);
    FuturePut futurePut3 = p1.put(lKey).domainKey(dKey).sign().data(cKey, data).keyPair(keyPair1).start();
    futurePut3.awaitUninterruptibly();
    Assert.assertFalse(futurePut3.isSuccess());
    retData = p1.get(lKey).domainKey(dKey).contentKey(cKey).start().awaitUninterruptibly().data();
    Assert.assertEquals(testData, (String) retData.object());
    Assert.assertTrue(retData.verify(keyPair2.getPublic(), factory));
    retData = p2.get(lKey).domainKey(dKey).contentKey(cKey).start().awaitUninterruptibly().data();
    Assert.assertEquals(testData, (String) retData.object());
    Assert.assertTrue(retData.verify(keyPair2.getPublic(), factory));
    // modify with new protection key
    String newTestData = "new data";
    data = new Data(newTestData).protectEntryNow(keyPair2, factory);
    FuturePut futurePut4 = p1.put(lKey).domainKey(dKey).sign().data(cKey, data).keyPair(keyPair2).start();
    futurePut4.awaitUninterruptibly();
    Assert.assertTrue(futurePut4.isSuccess());
    retData = p1.get(lKey).domainKey(dKey).contentKey(cKey).start().awaitUninterruptibly().data();
    Assert.assertEquals(newTestData, (String) retData.object());
    Assert.assertTrue(retData.verify(keyPair2.getPublic(), factory));
    retData = p2.get(lKey).domainKey(dKey).contentKey(cKey).start().awaitUninterruptibly().data();
    Assert.assertEquals(newTestData, (String) retData.object());
    Assert.assertTrue(retData.verify(keyPair2.getPublic(), factory));
    p1.shutdown().awaitUninterruptibly();
    p2.shutdown().awaitUninterruptibly();
  }

  @Test
  public void testChangeProtectionKeyWithVersions() throws NoSuchAlgorithmException, IOException,
          ClassNotFoundException, InvalidKeyException, SignatureException {
    PeerDHT p1 = null;
    PeerDHT p2 = null;
    try {
    KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
    KeyPair keyPairPeer1 = gen.generateKeyPair();
    p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4834).keyPair(keyPairPeer1)
            .start()).start();
    KeyPair keyPairPeer2 = gen.generateKeyPair();
    p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).masterPeer(p1.peer()).keyPair(keyPairPeer2)
            .start()).start();
    p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
    p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();
    KeyPair keyPair1 = gen.generateKeyPair();
    KeyPair keyPair2 = gen.generateKeyPair();
    Number160 lKey = Number160.createHash("location");
    Number160 dKey = Number160.createHash("domain");
    Number160 cKey = Number160.createHash("content");
    // put the first version of the content with key pair 1
    Number160 vKey1 = Number160.createHash("version1");
    Data data = new Data("data1v1").protectEntryNow(keyPair1, factory);
    data.addBasedOn(Number160.ZERO);
    FuturePut futurePut1 = p1.put(lKey).domainKey(dKey).sign().data(cKey, data).keyPair(keyPair1)
            .versionKey(vKey1).start();
    futurePut1.awaitUninterruptibly();
    Assert.assertTrue(futurePut1.isSuccess());
    // add another version with the correct key pair 1
    Number160 vKey2 = Number160.createHash("version2");
    data = new Data("data1v2").protectEntryNow(keyPair1, factory);
    data.addBasedOn(vKey1);
    FuturePut futurePut2 = p1.put(lKey).domainKey(dKey).sign().data(cKey, data).keyPair(keyPair1)
            .versionKey(vKey2).start();
    futurePut2.awaitUninterruptibly();
    Assert.assertTrue(futurePut2.isSuccess());
    // put new version with other key pair 2 (expected to fail)
    Number160 vKey3 = Number160.createHash("version3");
    data = new Data("data1v3").protectEntryNow(keyPair2, factory);
    data.addBasedOn(vKey2);
    FuturePut futurePut3 = p1.put(lKey).domainKey(dKey).data(cKey, data).keyPair(keyPair2)
            .versionKey(vKey3).start();
    futurePut3.awaitUninterruptibly();
    Assert.assertFalse(futurePut3.isSuccess());
    // change the key pair to the new one using an empty data object
    data = new Data().protectEntryNow(keyPair2, factory).duplicateMeta();
    // use the old protection key to sign the message
    FuturePut futurePut4 = p1.put(lKey).domainKey(dKey).sign().putMeta().data(cKey, data)
            .keyPair(keyPair1).start();
    futurePut4.awaitUninterruptibly();
    Assert.assertFalse(futurePut4.isSuccess());
    // verify if the two versions have the new protection key
    Data retData = p1.get(lKey).domainKey(dKey).contentKey(cKey).versionKey(vKey1).start()
            .awaitUninterruptibly().data();
    Assert.assertEquals("data1v1", (String) retData.object());
    Assert.assertFalse(retData.verify(keyPair2.getPublic(), factory));
    retData = p1.get(lKey).domainKey(dKey).contentKey(cKey).versionKey(vKey2).start()
            .awaitUninterruptibly().data();
    //Assert.assertEquals("data1v2", (String) retData.object());
    Assert.assertFalse(retData.verify(keyPair2.getPublic(), factory));
    // add another version with the new protection key
    Number160 vKey4 = Number160.createHash("version4");
    data = new Data("data1v4").protectEntryNow(keyPair2, factory);
    data.addBasedOn(vKey2);
    FuturePut futurePut5 = p1.put(lKey).domainKey(dKey).sign().data(cKey, data).keyPair(keyPair2)
            .versionKey(vKey4).start();
    futurePut5.awaitUninterruptibly();
    Assert.assertTrue(futurePut5.isSuccess());
    } finally {
      p1.shutdown().awaitUninterruptibly();
      p2.shutdown().awaitUninterruptibly();
    }
  }
 
  @Test
  public void testGetMeta() throws NoSuchAlgorithmException, IOException, ClassNotFoundException,
          InvalidKeyException, SignatureException {
    PeerDHT p1 = null;
    PeerDHT p2 = null;
    try {
      KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
      KeyPair keyPairPeer1 = gen.generateKeyPair();
      p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4834).keyPair(keyPairPeer1)
              .start()).start();
      KeyPair keyPairPeer2 = gen.generateKeyPair();
      p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).masterPeer(p1.peer()).keyPair(keyPairPeer2)
              .start()).start();
      p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
      p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();

      KeyPair keyPair1 = gen.generateKeyPair();

      Number160 lKey = Number160.createHash("location");
      Data data = new Data("data1v11").protectEntryNow(keyPair1, factory);

      FuturePut futurePut = p1.put(lKey).sign().data(data).keyPair(keyPair1).start();
      futurePut.awaitUninterruptibly();
      Assert.assertTrue(futurePut.isSuccess());

      FutureDigest futureDigest = p1.digest(lKey).returnMetaValues().start();
      futureDigest.awaitUninterruptibly();
      Assert.assertTrue(futureDigest.isSuccess());
      Data dataMeta = futureDigest.digest().dataMap().values().iterator().next();

      Assert.assertEquals(keyPair1.getPublic(), dataMeta.publicKey());
      Assert.assertEquals(data.signature(), dataMeta.signature());
      Assert.assertEquals(0, dataMeta.length());
    } finally {
      p1.shutdown().awaitUninterruptibly();
      p2.shutdown().awaitUninterruptibly();
    }
  }
 
  @Test
  public void testSignature() throws InvalidKeyException, SignatureException, IOException, NoSuchAlgorithmException {
    SignatureFactory signatureFactory = new RSASignatureFactory();

    // generate some test data
    Data testData = new Data("test");
    // create a content protection key
   
    KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
    KeyPair protectionKey = gen.generateKeyPair();

    SignatureCodec signature = signatureFactory.sign(protectionKey.getPrivate(), testData.buffer());

    boolean isVerified = signatureFactory.verify(protectionKey.getPublic(), testData.buffer(), signature);

    Assert.assertTrue(isVerified);
  }
 
  @Test
  public void testTTLDecrement() throws IOException, ClassNotFoundException, NoSuchAlgorithmException,
          InvalidKeyException, SignatureException, InterruptedException {
    PeerDHT p1 = null;
    PeerDHT p2 = null;
    try {
    KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");

    KeyPair keyPairPeer1 = gen.generateKeyPair();
   
    StorageMemory sm1 = new StorageMemory(1);
    StorageMemory sm2 = new StorageMemory(1);
   
    p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4834).keyPair(keyPairPeer1)
            .start()).storage(sm1).start();
    KeyPair keyPairPeer2 = gen.generateKeyPair();
    p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).masterPeer(p1.peer()).keyPair(keyPairPeer2)
            .start()).storage(sm2).start();

    p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
    p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();

    KeyPair keyPair1 = gen.generateKeyPair();

    Number160 lKey = Number160.createHash("location");
    Number160 dKey = Number160.createHash("domain");
    Number160 cKey = Number160.createHash("content");
    Number160 vKey = Number160.createHash("version");
    Number160 bKey = Number160.ZERO;

    int ttl = 4;

    String testData = "data";
    Data data = new Data(testData).protectEntry(keyPair1);
    data.ttlSeconds(ttl).addBasedOn(bKey);

    // initial put
    FuturePut futurePut = p1.put(lKey).domainKey(dKey).data(cKey, data).versionKey(vKey).keyPair(keyPair1)
            .start();
    futurePut.awaitUninterruptibly();
    Assert.assertTrue(futurePut.isSuccess());

    // wait a moment, so that the ttl decrements
    Thread.sleep(2000);

    // check decrement of ttl through a normal get
    FutureGet futureGet = p1.get(lKey).domainKey(dKey).contentKey(cKey).versionKey(vKey).start();
    futureGet.awaitUninterruptibly();
    Assert.assertTrue(futureGet.isSuccess());
    System.err.println(futureGet.data().ttlSeconds());
    Assert.assertTrue(ttl > futureGet.data().ttlSeconds());

    // check decrement of ttl through a get meta
    FutureDigest futureDigest = p1.digest(lKey).domainKey(dKey).contentKey(cKey).versionKey(vKey)
            .returnMetaValues().start();
    futureDigest.awaitUninterruptibly();
    Assert.assertTrue(futureDigest.isSuccess());
    Data dataMeta = futureDigest.digest().dataMap().values().iterator().next();
    Assert.assertTrue(ttl > dataMeta.ttlSeconds());

    // wait again a moment, till data gets expired
    Thread.sleep(2000);

    // check if data has been removed
    Data retData = p2.get(lKey).domainKey(dKey).contentKey(cKey).versionKey(vKey).start()
            .awaitUninterruptibly().data();
    Assert.assertNull(retData);

    } finally {
      p1.shutdown().awaitUninterruptibly();
      p2.shutdown().awaitUninterruptibly();
    }
  }
 
  @Test
  public void testChangeProtectionKeyWithReusedSignature() throws Exception {
    PeerDHT p1 = null;
    PeerDHT p2 = null;
    try {
    KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");

    // create custom RSA factories
    SignatureFactory factory = new RSASignatureFactory();
    SignatureCodec codec = new RSASignatureCodec();

    // replace default signature factories
    ChannelClientConfiguration clientConfig = PeerBuilder.createDefaultChannelClientConfiguration();
    clientConfig.signatureFactory(factory);
    ChannelServerConfiguration serverConfig = PeerBuilder.createDefaultChannelServerConfiguration();
    serverConfig.signatureFactory(factory);

    KeyPair keyPairPeer1 = gen.generateKeyPair();
    p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4834).keyPair(keyPairPeer1)
            .channelClientConfiguration(clientConfig)
            .channelServerConfiguration(serverConfig).start()).start();
    KeyPair keyPairPeer2 = gen.generateKeyPair();
    p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).masterPeer(p1.peer()).keyPair(keyPairPeer2)
            .channelClientConfiguration(clientConfig)
            .channelServerConfiguration(serverConfig).start()).start();

    p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
    p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();

    KeyPair keyPairOld = gen.generateKeyPair();
    KeyPair keyPairNew = gen.generateKeyPair();

    Number160 lKey = Number160.createHash("location");
    Number160 dKey = Number160.createHash("domain");
    Number160 cKey = Number160.createHash("content");
    Number160 vKey = Number160.createHash("version");
    Number160 bKey = Number160.ZERO;

    int ttl = 10;

    String testData = "data";
    Data data = new Data(testData).protectEntryNow(keyPairOld, factory);
    data.ttlSeconds(ttl).addBasedOn(bKey);

    // initial put of some test data
    FuturePut futurePut = p1.put(lKey).domainKey(dKey).data(cKey, data).versionKey(vKey)
            .keyPair(keyPairOld).start();
    futurePut.awaitUninterruptibly();
    Assert.assertTrue(futurePut.isSuccess());

    // create signature with old key pair having the data object
    byte[] signature1 = factory.sign(keyPairOld.getPrivate(), data.buffer()).encode();

    // decrypt signature to get hash of the object
    Cipher rsa = Cipher.getInstance("RSA");
    rsa.init(Cipher.DECRYPT_MODE, keyPairOld.getPublic());
    byte[] hash = rsa.doFinal(signature1);

    // encrypt hash with new key pair to get the new signature (without
    // having the data object)
    rsa = Cipher.getInstance("RSA");
    rsa.init(Cipher.ENCRYPT_MODE, keyPairNew.getPrivate());
    byte[] signatureNew = rsa.doFinal(hash);

    // verify old content protection keys
    Data retData = p1.get(lKey).domainKey(dKey).contentKey(cKey).versionKey(vKey).start()
            .awaitUninterruptibly().data();
    Assert.assertTrue(retData.verify(keyPairOld.getPublic(), factory));

    // create a dummy data object for changing the content protection key
    // through a put meta
    Data dummyData = new Data();
    dummyData.addBasedOn(bKey).ttlSeconds(ttl);
    // assign the reused hash from signature (don't forget to set the
    // signedflag)
    dummyData.signature(codec.decode(signatureNew)).signed(true).duplicateMeta();
    // change content protection key through a put meta
    FuturePut futurePutMeta = p1.put(lKey).domainKey(dKey).putMeta().data(cKey, dummyData)
            .versionKey(vKey).keyPair(keyPairOld).start();
    futurePutMeta.awaitUninterruptibly();
    Assert.assertTrue(futurePutMeta.isSuccess());

    // verify new content protection keys
    retData = p1.get(lKey).domainKey(dKey).contentKey(cKey).versionKey(vKey).start()
            .awaitUninterruptibly().data();
    Assert.assertTrue(retData.verify(keyPairNew.getPublic(), factory));

    } finally {
      p1.shutdown().awaitUninterruptibly();
      p2.shutdown().awaitUninterruptibly();
    }
  }
}
TOP

Related Classes of net.tomp2p.dht.TestSecurity

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.