Package org.jgroups.protocols

Source Code of org.jgroups.protocols.ENCRYPTAsymmetricTest$MockProtocol

/*
* Created on 04-Jul-2004
*
* To change the template for this generated file go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
package org.jgroups.protocols;


import org.jgroups.*;
import org.jgroups.conf.ClassConfigurator;
import org.jgroups.protocols.ENCRYPT.EncryptHeader;
import org.jgroups.stack.Protocol;
import org.jgroups.util.MessageBatch;
import org.jgroups.util.Util;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import java.security.MessageDigest;
import java.security.Security;
import java.util.TreeMap;

/**
* @author xenephon
* @author Bela Ban
*/
@Test(groups=Global.FUNCTIONAL, sequential=false)
public class ENCRYPTAsymmetricTest {

    protected static final short ENCRYPT_ID=ClassConfigurator.getProtocolId(ENCRYPT.class);
    protected static final Address encrypt_addr=Util.createRandomAddress("encrypt");
    protected static final Address server_addr=Util.createRandomAddress("server");
    protected static final Address peer_addr=Util.createRandomAddress("peer");
    protected static final Address peer2_addr=Util.createRandomAddress("peer2");


    @BeforeClass
    static void initProvider() {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    }

    public static void testInitNoProperties() throws Exception {
        ENCRYPT encrypt=new ENCRYPT();
        encrypt.init();

        // test the default asymetric key
        assert "RSA".equals(encrypt.getAsymAlgorithm());
        assert encrypt.getAsymInit() == 512;
        assert "RSA".equals(encrypt.getKpair().getPublic().getAlgorithm());
        assert "X.509".equals(encrypt.getKpair().getPublic().getFormat());

        assert encrypt.getKpair().getPublic().getEncoded() != null;

        // test the default symetric key
        assert "AES".equals(encrypt.getSymAlgorithm());
        assert encrypt.getSymInit() == 128;
        assert "AES".equals(encrypt.getDesKey().getAlgorithm());
        assert "RAW".equals(encrypt.getDesKey().getFormat());
        assert encrypt.getDesKey().getEncoded() != null;

        //test the resulting ciphers
        System.out.println("Provider:" + encrypt.getAsymCipher().getProvider());
        assert encrypt.getAsymCipher() != null;
        assert encrypt.getSymDecodingCipher() != null;
        assert encrypt.getSymEncodingCipher() != null;
    }

    public static void testInitBCAsymProperties() throws Exception {
        ENCRYPT encrypt=new ENCRYPT();
        encrypt.asymAlgorithm = "RSA";
        encrypt.init();

        // test the default asymetric key
        assert "RSA".equals(encrypt.getAsymAlgorithm());
        assert encrypt.getAsymInit() == 512;
        assert "RSA".equals(encrypt.getKpair().getPublic().getAlgorithm());
        //Strangely this returns differently from the default provider for RSA which is also BC!
        assert "X.509".equals(encrypt.getKpair().getPublic().getFormat());
        assert encrypt.getKpair().getPublic().getEncoded() != null;

        //test the resulting ciphers
        assert encrypt.getAsymCipher() != null;

    }



    @Test(expectedExceptions=Exception.class)
    public static void testInitIDEAProperties() throws Exception {   
        ENCRYPT encrypt=new ENCRYPT();
        encrypt.symAlgorithm =  "IDEA";
        encrypt.symInit = 128;
        encrypt.init();       
    }


    public static void testInitAESProperties() throws Exception {      
        ENCRYPT encrypt=new ENCRYPT();
        encrypt.symAlgorithm = "AES";
        encrypt.symInit = 128;    
        encrypt.init();

        // test the default symetric key
        assert "AES".equals(encrypt.getSymAlgorithm()) : "expected AES but was " + encrypt.getSymAlgorithm();
        Util.assertEquals(128, encrypt.getSymInit());
        Util.assertEquals("AES", encrypt.getDesKey().getAlgorithm());
        Util.assertEquals("RAW", encrypt.getDesKey().getFormat());
        Util.assertNotNull(encrypt.getDesKey().getEncoded());

        //test the resulting ciphers

        Util.assertNotNull(encrypt.getSymDecodingCipher());
        Util.assertNotNull(encrypt.getSymEncodingCipher());
    }

    public static void testViewChangeBecomeKeyserver() throws Exception {
        // set up the peer
        ENCRYPT encrypt=new ENCRYPT();
        encrypt.init();

        // set in the observer
        encrypt.setLocalAddress(encrypt_addr);
        MockProtocol observer=new MockProtocol();
        encrypt.setUpProtocol(observer);

        // produce encrypted message
        Cipher cipher=encrypt.getSymEncodingCipher();

        MessageDigest digest=MessageDigest.getInstance("MD5");
        digest.reset();
        digest.update(encrypt.getDesKey().getEncoded());

        byte[] symVersion=digest.digest();
        encrypt.keyServer=false;
        Message msg=new Message().setBuffer(cipher.doFinal("hello".getBytes()))
          .putHeader(ENCRYPT_ID, new EncryptHeader(EncryptHeader.ENCRYPT, symVersion));

        encrypt.up(new Event(Event.MSG, msg));

        // assert that message is queued as we have no key
        Util.assertTrue(observer.upMessages.isEmpty());

        // send a view change to trigger the become key server
        // we use the fact that our address is now the controller one
        View tempView=View.create(encrypt_addr,1,encrypt_addr);
        Event event=new Event(Event.VIEW_CHANGE, tempView);
        // this should have changed us to the key server
        encrypt.up(event);

        // send another encrypted message
        Message msg2=new Message().setBuffer(cipher.doFinal("hello2".getBytes()))
          .putHeader(ENCRYPT_ID,new EncryptHeader(EncryptHeader.ENCRYPT,symVersion));

        // we should have three messages now in our observer that are decrypted
        encrypt.up(new Event(Event.MSG, msg2));
        Util.assertEquals(3, observer.upMessages.size());

        Event sent=observer.upMessages.get("message1");
        Util.assertEquals("hello", new String(((Message)sent.getArg()).getBuffer()));

        sent=observer.upMessages.get("message2");
        Util.assertEquals("hello2", new String(((Message)sent.getArg()).getBuffer()));
    }


    public static void testViewChangeNewKeyServer() throws Exception {
        ENCRYPT peer=new ENCRYPT();
        peer.init();

        ENCRYPT server=new ENCRYPT();
        server.init();

        // set up server
        server.keyServer=true;
        MockProtocol serverObserver=new MockProtocol();
        server.setUpProtocol(serverObserver);
        server.setDownProtocol(serverObserver);

        server.setLocalAddress(server_addr);
        Event viewChange = new Event(Event.VIEW_CHANGE, View.create(server_addr, 1, server_addr));
        server.up(viewChange);

        // set up peer
        peer.setLocalAddress(peer_addr);
        MockProtocol peerObserver=new MockProtocol();
        peer.setUpProtocol(peerObserver);
        peer.setDownProtocol(peerObserver);
        peer.keyServer=false;


        MessageDigest digest=MessageDigest.getInstance("MD5");
        digest.reset();
        digest.update(server.getDesKey().getEncoded());

        // encrypt and send an initial message to peer
        Cipher cipher=server.getSymEncodingCipher();
        byte[] symVersion=digest.digest();
        Message msg=new Message().setBuffer(cipher.doFinal("hello".getBytes()))
          .putHeader(ENCRYPT_ID, new EncryptHeader(EncryptHeader.ENCRYPT, symVersion));

        peer.up(new Event(Event.MSG, msg));
        //assert that message is queued as we have no key from server
        Util.assertTrue(peerObserver.upMessages.isEmpty());

        // send a view change where we are not the controller

        // send to peer - which should have peer2 as its key server
        peer.up(viewChange);
        // assert that peer\ keyserver address is now set
        Util.assertEquals(server_addr, peer.getKeyServerAddr());

        // get the resulting message from the peer - should be a key request

        Event sent=peerObserver.downMessages.get("message0");

        Util.assertEquals(((EncryptHeader)((Message)sent.getArg()).getHeader(ENCRYPT_ID)).getType(), EncryptHeader.KEY_REQUEST);
        Util.assertEquals(new String(((Message)sent.getArg()).getBuffer()), new String(peer.getKpair().getPublic().getEncoded()));

        // send this event to server
        server.up(sent);

        Event reply=serverObserver.downMessages.get("message1");

        //assert that reply is the session key encrypted with peer's public key
        Util.assertEquals(((EncryptHeader)((Message)reply.getArg()).getHeader(ENCRYPT_ID)).getType(), EncryptHeader.SECRETKEY);


        assert !peer.getDesKey().equals(server.getDesKey());
        // now send back to peer
        peer.up(reply);

        // assert that both now have same key
        Util.assertEquals(peer.getDesKey(), server.getDesKey());

        // send another encrypted message to peer to test queue
        Message msg2=new Message().setBuffer(cipher.doFinal("hello2".getBytes()))
          .putHeader(ENCRYPT_ID,new EncryptHeader(EncryptHeader.ENCRYPT,symVersion));
        peer.up(new Event(Event.MSG, msg2));

        // make sure we have the events now in the up layers
        Util.assertEquals(3,peerObserver.upMessages.size());

        Event tempEvt=peerObserver.upMessages.get("message2");
        Util.assertEquals("hello", new String(((Message)tempEvt.getArg()).getBuffer()));

        tempEvt=peerObserver.upMessages.get("message3");
        Util.assertEquals("hello2", new String(((Message)tempEvt.getArg()).getBuffer()));
    }


    public static void testViewChangeNewKeyServerNewKey() throws Exception {
        // create peer and server
        ENCRYPT peer=new ENCRYPT();
        peer.init();

        ENCRYPT server=new ENCRYPT();
        server.init();

        ENCRYPT peer2=new ENCRYPT();
        peer2.init();

        // set up server
        server.keyServer=true;
        MockProtocol serverObserver=new MockProtocol();
        server.setUpProtocol(serverObserver);
        server.setDownProtocol(serverObserver);

        //set the local address and view change to simulate a started instance
        server.setLocalAddress(server_addr);

        Event serverEvent = new Event(Event.VIEW_CHANGE, View.create(server_addr, 1, server_addr));
        server.up(serverEvent);

        // set up peer as if it has started but not recieved view change
        peer.setLocalAddress(peer_addr);
        MockProtocol peerObserver=new MockProtocol();
        peer.setUpProtocol(peerObserver);
        peer.setDownProtocol(peerObserver);
        peer.keyServer=false;

        // set up peer2 with server as key server
        peer2.setLocalAddress(peer2_addr);
        MockProtocol peer2Observer=new MockProtocol();
        peer2.setUpProtocol(peer2Observer);
        peer2.setDownProtocol(peer2Observer);
        peer2.keyServer=false;
        peer2.setKeyServerAddr(server_addr);

        // send an encrypted message from the server
        Message msg=new Message().setBuffer("hello".getBytes());
        server.down(new Event(Event.MSG, msg));

        // message0 is in response to view change
        Event encEvt=serverObserver.downMessages.get("message1");

        // sent to peer encrypted - should be queued in encyption layer as we do not have a keyserver set
        peer.up(encEvt);

        //assert that message is queued as we have no key from server
        Util.assertTrue(peerObserver.upMessages.isEmpty());
        updateViewFor(peer, server, serverObserver, serverEvent, peerObserver);
        Util.assertFalse(peerObserver.upMessages.isEmpty());
       
        Event event = new Event(Event.VIEW_CHANGE, View.create(peer2_addr, 2, peer2_addr));

        // send to peer - should set peer2 as keyserver
        peer.up(event);

        // assert that peer\ keyserver address is now set
        Util.assertEquals(peer2_addr, peer.getKeyServerAddr());

        // get the resulting message from the peer - should be a key request to peer2
        Event sent=peerObserver.downMessages.get("message0");

        // ensure type and that request contains peers pub key
        Util.assertEquals(((EncryptHeader)((Message)sent.getArg()).getHeader(ENCRYPT_ID)).getType(), EncryptHeader.KEY_REQUEST);
        Util.assertEquals(new String(((Message)sent.getArg()).getBuffer()), new String(peer.getKpair().getPublic().getEncoded()));

       
        // this should have changed us to the key server
        peer2.up(event);

        peer2.up(sent);

        Event reply=peer2Observer.downMessages.get("message1");

        //assert that reply is the session key encrypted with peer's public key
        Util.assertEquals(((EncryptHeader)((Message)reply.getArg()).getHeader(ENCRYPT_ID)).getType(), EncryptHeader.SECRETKEY);


        assert !peer.getDesKey().equals(peer2.getDesKey());
        assert !server.getDesKey().equals(peer2.getDesKey());

        // now send back to peer
        peer.up(reply);

        // assert that both now have same key
        Util.assertEquals(peer.getDesKey(), peer2.getDesKey());
        assert !server.getDesKey().equals(peer.getDesKey());

        // send another encrypted message to peer to test queue
        Message msg2=new Message();
        msg2.setBuffer("hello2".getBytes());


        Event evt2=new Event(Event.MSG, msg2);

        peer2.down(evt2);

        Event evt3=peer2Observer.downMessages.get("message2");

        peer.up(evt3);
        // make sure we have the events now in the up layers
        Util.assertEquals(4, peerObserver.upMessages.size());

        Event tempEvt=peerObserver.getLatestUpMessage();
        Util.assertEquals("hello2", new String(((Message)tempEvt.getArg()).getBuffer()));
    }

    public static void testKeyChangesDuringKeyServerChange() throws Exception {
        // create peers and server
        ENCRYPT peer=new ENCRYPT();
        peer.init();

        ENCRYPT server=new ENCRYPT();
        server.init();

        ENCRYPT peer2=new ENCRYPT();
        peer2.init();

        // set up server
        server.keyServer=true;
        MockProtocol serverObserver=new MockProtocol();
        server.setUpProtocol(serverObserver);
        server.setDownProtocol(serverObserver);

        //set the local address and view change to simulate a started instance
        server.setLocalAddress(server_addr);

        //  set the server up as keyserver
        Event serverEvent = new Event(Event.VIEW_CHANGE, View.create(server_addr, 1, server_addr));
        server.up(new Event(Event.TMP_VIEW, serverEvent.getArg()));
        server.up(serverEvent);

        peer.setLocalAddress(peer_addr);
        MockProtocol peerObserver=new MockProtocol();
        peer.setUpProtocol(peerObserver);
        peer.setDownProtocol(peerObserver);
        peer.keyServer=false;
       
        updateViewFor(peer, server, serverObserver, serverEvent, peerObserver);

        // set up peer2 with server as key server
        peer2.setLocalAddress(peer2_addr);
        MockProtocol peer2Observer=new MockProtocol();
        peer2.setUpProtocol(peer2Observer);
        peer2.setDownProtocol(peer2Observer);
        peer2.keyServer=false;
        updateViewFor(peer2, server, serverObserver, serverEvent, peer2Observer);

        Assert.assertEquals(server.getDesKey(), peer.getDesKey());
        Assert.assertEquals(server.getDesKey(), peer2.getDesKey());

        Event viewChange2 = new Event(Event.VIEW_CHANGE, View.create(peer2_addr, 2, peer2_addr));
        peer2.up(new Event(Event.TMP_VIEW, viewChange2.getArg()));
        peer2.up(viewChange2);

        updateViewFor(peer, peer2, peer2Observer, viewChange2, peerObserver);

        Assert.assertFalse(server.getDesKey().equals(peer.getDesKey()));
        Assert.assertEquals(peer.getDesKey(), peer2.getDesKey());

    }

    public static void testSymmetricKeyIsChangedOnViewChange() throws Exception{
        ENCRYPT server=new ENCRYPT();
        server.changeKeysOnViewChange=true;
        MockProtocol serverObserver=new MockProtocol();
        server.setDownProtocol(serverObserver);
        server.setUpProtocol(serverObserver);
        server.setLocalAddress(server_addr);
        server.init();

        //  set the server up as key server
        Event initalView = new Event(Event.VIEW_CHANGE, View.create(server_addr, 1, server_addr));
        server.up(new Event(Event.TMP_VIEW, initalView.getArg()));
        server.up(initalView);
       
        SecretKey key = server.getDesKey();
       
        //  Update the view with new member
        Event updatedView = new Event(Event.VIEW_CHANGE, View.create(server_addr, 2, peer_addr));
        server.up(new Event(Event.TMP_VIEW, updatedView.getArg()));
        server.up(updatedView);
       
        SecretKey keyAfterViewChange = server.getDesKey();
        Util.assertFalse(key.equals(keyAfterViewChange));
    }
   
  private static void updateViewFor(ENCRYPT peer, ENCRYPT keyServer, MockProtocol serverObserver, Event serverEvent,
                                      MockProtocol peerObserver) {
    peer.up(serverEvent);
        Event peerKeyRequest=peerObserver.getLatestDownMessage();
        keyServer.up(peerKeyRequest);
        Event serverKeyToPeer=serverObserver.getLatestDownMessage();
        peer.up(serverKeyToPeer);
  }


   
    static class MockProtocol extends Protocol {
        private final TreeMap<String, Event> upMessages=new TreeMap<String, Event>();
        private final TreeMap<String, Event> downMessages=new TreeMap<String, Event>();
        private int counter;


        public Object down(Event evt) {
            downMessages.put("message" + counter++, evt);
            return null;
        }

        public Object up(Event evt) {
            upMessages.put("message" + counter++, evt);
            return null;
        }

        public void up(MessageBatch batch) {
            throw new UnsupportedOperationException();
        }

        protected Event getLatestUpMessage() {
            return upMessages.isEmpty()? null : upMessages.lastEntry().getValue();
        }

        protected Event getLatestDownMessage() {
            return downMessages.isEmpty()? null : downMessages.lastEntry().getValue();
        }
    }



}
TOP

Related Classes of org.jgroups.protocols.ENCRYPTAsymmetricTest$MockProtocol

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.