001: /*
002: * Created on 04-Jul-2004
003: *
004: * To change the template for this generated file go to
005: * Window - Preferences - Java - Code Generation - Code and Comments
006: */
007: package org.jgroups.protocols;
008:
009: import junit.framework.TestCase;
010: import org.jgroups.*;
011: import org.jgroups.protocols.ENCRYPT.EncryptHeader;
012: import org.jgroups.stack.Protocol;
013: import org.jgroups.stack.ProtocolObserver;
014:
015: import javax.crypto.Cipher;
016: import java.io.*;
017: import java.security.MessageDigest;
018: import java.security.Security;
019: import java.util.HashMap;
020: import java.util.Map;
021: import java.util.Properties;
022: import java.util.Vector;
023:
024: /**
025: * @author xenephon
026: *
027: * To change the template for this generated type comment go to
028: * Window - Preferences - Java - Code Generation - Code and Comments
029: */
030: public class ENCRYPTAsymmetricTest extends TestCase {
031:
032: {
033: Security
034: .addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
035:
036: }
037:
038: public void testInitNoProperties() {
039:
040: ENCRYPT encrypt = new ENCRYPT();
041: try {
042: encrypt.init();
043: } catch (Exception e) {
044: fail(e.getMessage());
045: }
046:
047: // test the default asymetric key
048: assertEquals("RSA", encrypt.getAsymAlgorithm());
049: assertEquals(512, encrypt.getAsymInit());
050: assertEquals("RSA", encrypt.getKpair().getPublic()
051: .getAlgorithm());
052: assertEquals("X.509", encrypt.getKpair().getPublic()
053: .getFormat());
054:
055: assertNotNull(encrypt.getKpair().getPublic().getEncoded());
056:
057: // test the default symetric key
058: assertEquals("Blowfish", encrypt.getSymAlgorithm());
059: assertEquals(56, encrypt.getSymInit());
060: assertEquals("Blowfish", encrypt.getDesKey().getAlgorithm());
061: assertEquals("RAW", encrypt.getDesKey().getFormat());
062: assertNotNull(encrypt.getDesKey().getEncoded());
063:
064: //test the resulting ciphers
065: System.out.println("Provider:"
066: + encrypt.getAsymCipher().getProvider());
067: assertNotNull(encrypt.getAsymCipher());
068: assertNotNull(encrypt.getSymDecodingCipher());
069: assertNotNull(encrypt.getSymEncodingCipher());
070: }
071:
072: public void testInitBCAsymProperties() {
073:
074: Properties props = new Properties();
075: props.put("asym_provider", "BC");
076: props.put("asym_algorithm", "RSA");
077: //javax.
078: ENCRYPT encrypt = new ENCRYPT();
079: encrypt.setProperties(props);
080: try {
081: encrypt.init();
082: } catch (Exception e) {
083: fail(e.getMessage());
084: }
085:
086: // test the default asymetric key
087: assertEquals("RSA", encrypt.getAsymAlgorithm());
088: assertEquals(512, encrypt.getAsymInit());
089: assertEquals("RSA", encrypt.getKpair().getPublic()
090: .getAlgorithm());
091: //Strangely this returns differently from the default provider for RSA which is also BC!
092: assertEquals("X.509", encrypt.getKpair().getPublic()
093: .getFormat());
094: assertNotNull(encrypt.getKpair().getPublic().getEncoded());
095:
096: //test the resulting ciphers
097: assertNotNull(encrypt.getAsymCipher());
098:
099: }
100:
101: public void XtestInitRSABlockAsymProperties() {
102:
103: Properties props = new Properties();
104: props.put("asym_algorithm", "RSA/ECB/OAEPPadding");
105: //javax.
106: ENCRYPT encrypt = new ENCRYPT();
107: encrypt.setProperties(props);
108: try {
109: encrypt.init();
110: } catch (Exception e) {
111: fail(e.getMessage());
112: }
113:
114: // test the default asymetric key
115: assertEquals("RSA/ECB/OAEPPadding", encrypt.getAsymAlgorithm());
116: assertEquals(512, encrypt.getAsymInit());
117: assertEquals("RSA", encrypt.getKpair().getPublic()
118: .getAlgorithm());
119: //Strangely this returns differently from the default provider for RSA which is also BC!
120: assertEquals("X509", encrypt.getKpair().getPublic().getFormat());
121: assertNotNull(encrypt.getKpair().getPublic().getEncoded());
122:
123: //test the resulting ciphers
124: assertNotNull(encrypt.getAsymCipher());
125:
126: }
127:
128: public void testInitIDEAProperties() {
129: Properties props = new Properties();
130: props.put("sym_algorithm", "IDEA");
131: props.put("sym_init", "128");
132:
133: ENCRYPT encrypt = new ENCRYPT();
134: encrypt.setProperties(props);
135: try {
136: encrypt.init();
137: } catch (Exception e) {
138: fail(e.getMessage());
139: }
140:
141: // test the default symetric key
142: assertEquals("IDEA", encrypt.getSymAlgorithm());
143: assertEquals(128, encrypt.getSymInit());
144: assertEquals("IDEA", encrypt.getDesKey().getAlgorithm());
145: assertEquals("RAW", encrypt.getDesKey().getFormat());
146: assertNotNull(encrypt.getDesKey().getEncoded());
147:
148: //test the resulting ciphers
149:
150: assertNotNull(encrypt.getSymDecodingCipher());
151: assertNotNull(encrypt.getSymEncodingCipher());
152: }
153:
154: public void testInitAESProperties() {
155: Properties props = new Properties();
156: props.put("sym_algorithm", "AES");
157: props.put("sym_init", "128");
158: ENCRYPT encrypt = new ENCRYPT();
159: encrypt.setProperties(props);
160: try {
161: encrypt.init();
162: } catch (Exception e) {
163: fail(e.getMessage());
164: }
165:
166: // test the default symetric key
167: assertEquals("AES", encrypt.getSymAlgorithm());
168: assertEquals(128, encrypt.getSymInit());
169: assertEquals("AES", encrypt.getDesKey().getAlgorithm());
170: assertEquals("RAW", encrypt.getDesKey().getFormat());
171: assertNotNull(encrypt.getDesKey().getEncoded());
172:
173: //test the resulting ciphers
174:
175: assertNotNull(encrypt.getSymDecodingCipher());
176: assertNotNull(encrypt.getSymEncodingCipher());
177: }
178:
179: public void testViewChangeBecomeKeyserver() throws Exception {
180: // set up the peer
181: ENCRYPT encrypt = new ENCRYPT();
182: try {
183: encrypt.init();
184: } catch (Exception e) {
185: fail(e.getMessage());
186: }
187:
188: // set in the observer
189: MockAddress tempAddress = new MockAddress("encrypt");
190: encrypt.setLocal_addr(tempAddress);
191: MockObserver observer = new MockObserver();
192: encrypt.setObserver(observer);
193:
194: // produce encrypted message
195: Cipher cipher = encrypt.getSymEncodingCipher();
196:
197: MessageDigest digest = MessageDigest.getInstance("MD5");
198: digest.reset();
199: digest.update(encrypt.getDesKey().getEncoded());
200:
201: String symVersion = new String(digest.digest(), "UTF-8");
202:
203: encrypt.keyServer = false;
204: Message msg = new Message();
205: msg.setBuffer(cipher.doFinal("hello".getBytes()));
206: msg.putHeader(EncryptHeader.KEY, new EncryptHeader(
207: EncryptHeader.ENCRYPT, symVersion));
208:
209: Event evt = new Event(Event.MSG, msg);
210:
211: //pass in event to encrypt layer
212:
213: encrypt.up(evt);
214:
215: // assert that message is queued as we have no key
216: assertTrue(observer.getUpMessages().isEmpty());
217:
218: // send a view change to trigger the become key server
219: // we use the fact that our address is now the controller one
220: Vector tempVector = new Vector();
221: tempVector.add(tempAddress);
222: View tempView = new View(new ViewId(tempAddress, 1), tempVector);
223: Event event = new Event(Event.VIEW_CHANGE, tempView);
224: // this should have changed us to the key server
225: encrypt.up(event);
226:
227: // send another encrypted message
228: Message msg2 = new Message();
229: msg2.setBuffer(cipher.doFinal("hello2".getBytes()));
230: msg2.putHeader(EncryptHeader.KEY, new EncryptHeader(
231: EncryptHeader.ENCRYPT, symVersion));
232:
233: // we should have three messages now in our observer
234: // that are decrypted
235:
236: Event evt2 = new Event(Event.MSG, msg2);
237:
238: encrypt.up(evt2);
239: assertEquals(3, observer.getUpMessages().size());
240:
241: Event sent = (Event) observer.getUpMessages().get("message1");
242:
243: assertEquals(new String(((Message) sent.getArg()).getBuffer()),
244: "hello");
245:
246: sent = (Event) observer.getUpMessages().get("message2");
247:
248: assertEquals(new String(((Message) sent.getArg()).getBuffer()),
249: "hello2");
250:
251: }
252:
253: public void testViewChangeNewKeyServer() throws Exception {
254: // create peer and server
255: ENCRYPT peer = new ENCRYPT();
256: try {
257: peer.init();
258: } catch (Exception e) {
259: fail(e.getMessage());
260: }
261:
262: ENCRYPT server = new ENCRYPT();
263: try {
264: server.init();
265: } catch (Exception e) {
266: fail(e.getMessage());
267: }
268:
269: // set up server
270: server.keyServer = true;
271: MockObserver serverObserver = new MockObserver();
272: server.setObserver(serverObserver);
273: Address serverAddress = new MockAddress("server");
274:
275: server.setLocal_addr(serverAddress);
276: //set the server up as keyserver
277: Vector serverVector = new Vector();
278: serverVector.add(serverAddress);
279: View tempView = new View(new ViewId(serverAddress, 1),
280: serverVector);
281: Event serverEvent = new Event(Event.VIEW_CHANGE, tempView);
282: server.up(serverEvent);
283:
284: // set up peer
285: Address peerAddress = new MockAddress("peer");
286: peer.setLocal_addr(peerAddress);
287: MockObserver peerObserver = new MockObserver();
288: peer.setObserver(peerObserver);
289: peer.keyServer = false;
290:
291: MessageDigest digest = MessageDigest.getInstance("MD5");
292: digest.reset();
293: digest.update(server.getDesKey().getEncoded());
294:
295: String symVersion = new String(digest.digest(), "UTF-8");
296:
297: // encrypt and send an initial message to peer
298: Cipher cipher = server.getSymEncodingCipher();
299: Message msg = new Message();
300: msg.setBuffer(cipher.doFinal("hello".getBytes()));
301: msg.putHeader(EncryptHeader.KEY, new EncryptHeader(
302: EncryptHeader.ENCRYPT, symVersion));
303:
304: Event evt = new Event(Event.MSG, msg);
305:
306: peer.up(evt);
307: //assert that message is queued as we have no key from server
308: assertTrue(peerObserver.getUpMessages().isEmpty());
309:
310: // send a view change where we are not the controller
311:
312: // send to peer - which should have peer2 as its key server
313: peer.up(serverEvent);
314: // assert that peer\ keyserver address is now set
315: assertTrue(serverAddress == peer.getKeyServerAddr());
316:
317: // get the resulting message from the peer - should be a key request
318:
319: Event sent = (Event) peerObserver.getDownMessages().get(
320: "message0");
321:
322: assertTrue(((EncryptHeader) ((Message) sent.getArg())
323: .getHeader(ENCRYPT.EncryptHeader.KEY)).getType() == ENCRYPT.EncryptHeader.KEY_REQUEST);
324: assertEquals(new String(((Message) sent.getArg()).getBuffer()),
325: new String(peer.getKpair().getPublic().getEncoded()));
326:
327: // send this event to server
328: server.up(sent);
329:
330: Event reply = (Event) serverObserver.getDownMessages().get(
331: "message1");
332:
333: //assert that reply is the session key encrypted with peer's public key
334: assertTrue(((EncryptHeader) ((Message) reply.getArg())
335: .getHeader(ENCRYPT.EncryptHeader.KEY)).getType() == ENCRYPT.EncryptHeader.SECRETKEY);
336:
337: assertNotSame(peer.getDesKey(), server.getDesKey());
338: // now send back to peer
339: peer.up(reply);
340:
341: // assert that both now have same key
342: assertEquals(peer.getDesKey(), server.getDesKey());
343:
344: // send another encrypted message to peer to test queue
345: Message msg2 = new Message();
346: msg2.setBuffer(cipher.doFinal("hello2".getBytes()));
347: msg2.putHeader(EncryptHeader.KEY, new EncryptHeader(
348: EncryptHeader.ENCRYPT, symVersion));
349:
350: Event evt2 = new Event(Event.MSG, msg2);
351:
352: peer.up(evt2);
353:
354: // make sure we have the events now in the up layers
355: assertEquals(3, peerObserver.getUpMessages().size());
356:
357: Event tempEvt = (Event) peerObserver.getUpMessages().get(
358: "message2");
359:
360: assertEquals(new String(((Message) tempEvt.getArg())
361: .getBuffer()), "hello");
362:
363: tempEvt = (Event) peerObserver.getUpMessages().get("message3");
364:
365: assertEquals(new String(((Message) tempEvt.getArg())
366: .getBuffer()), "hello2");
367:
368: }
369:
370: public void testViewChangeNewKeyServerNewKey() throws Exception {
371: // create peer and server
372: ENCRYPT peer = new ENCRYPT();
373: try {
374: peer.init();
375: } catch (Exception e) {
376: fail(e.getMessage());
377: }
378:
379: ENCRYPT server = new ENCRYPT();
380: try {
381: server.init();
382: } catch (Exception e) {
383: fail(e.getMessage());
384: }
385:
386: ENCRYPT peer2 = new ENCRYPT();
387: try {
388: peer2.init();
389: } catch (Exception e) {
390: fail(e.getMessage());
391: }
392:
393: // set up server
394: server.keyServer = true;
395: MockObserver serverObserver = new MockObserver();
396: server.setObserver(serverObserver);
397:
398: //set the local address and view change to simulate a started instance
399: Address serverAddress = new MockAddress("server");
400: server.setLocal_addr(serverAddress);
401:
402: // set the server up as keyserver
403: Vector serverVector = new Vector();
404: serverVector.add(serverAddress);
405: View tempView = new View(new ViewId(serverAddress, 1),
406: serverVector);
407: Event serverEvent = new Event(Event.VIEW_CHANGE, tempView);
408: server.up(serverEvent);
409:
410: // set up peer as if it has started but not recieved view change
411: Address peerAddress = new MockAddress("peer");
412: peer.setLocal_addr(peerAddress);
413: MockObserver peerObserver = new MockObserver();
414: peer.setObserver(peerObserver);
415: peer.keyServer = false;
416:
417: // set up peer2 with server as key server
418: Address peer2Address = new MockAddress("peer2");
419: peer2.setLocal_addr(peer2Address);
420: MockObserver peer2Observer = new MockObserver();
421: peer2.setObserver(peer2Observer);
422: peer2.keyServer = false;
423: peer2.setKeyServerAddr(serverAddress);
424:
425: // send an encrypted message from the server
426: Message msg = new Message();
427: msg.setBuffer("hello".getBytes());
428:
429: Event evt = new Event(Event.MSG, msg);
430:
431: server.down(evt);
432:
433: // message0 is in response to view change
434: Event encEvt = (Event) serverObserver.getDownMessages().get(
435: "message1");
436:
437: // sent to peer encrypted - should be queued in encyption layer as we do not have a keyserver set
438: peer.up(encEvt);
439:
440: //assert that message is queued as we have no key from server
441: assertTrue(peerObserver.getUpMessages().isEmpty());
442:
443: // send a view change to peer where peer2 is controller
444: Vector peerVector = new Vector();
445: peerVector.add(peer2Address);
446: View tempPeerView = new View(new ViewId(peer2Address, 1),
447: peerVector);
448: Event event = new Event(Event.VIEW_CHANGE, tempPeerView);
449:
450: // send to peer - should set peer2 as keyserver
451: peer.up(event);
452:
453: // assert that peer\ keyserver address is now set
454: assertTrue(peer2Address == peer.getKeyServerAddr());
455:
456: // get the resulting message from the peer - should be a key request to peer2
457: Event sent = (Event) peerObserver.getDownMessages().get(
458: "message0");
459:
460: // ensure type and that request contains peers pub key
461: assertTrue(((EncryptHeader) ((Message) sent.getArg())
462: .getHeader(ENCRYPT.EncryptHeader.KEY)).getType() == ENCRYPT.EncryptHeader.KEY_REQUEST);
463: assertEquals(new String(((Message) sent.getArg()).getBuffer()),
464: new String(peer.getKpair().getPublic().getEncoded()));
465:
466: //assume that server is no longer available and peer2 is new server
467: // but did not get the key from server before assuming role
468: // send this event to peer2
469: // send a view change to trigger the become key server
470: // we use the fact that our address is now the controller one
471: // send a view change where we are not the controller
472: Vector peer2Vector = new Vector();
473: peer2Vector.add(peer2Address);
474: View tempPeer2View = new View(new ViewId(peer2Address, 1),
475: peer2Vector);
476: Event event2 = new Event(Event.VIEW_CHANGE, tempPeer2View);
477: // this should have changed us to the key server
478: peer2.up(event2);
479:
480: peer2.up(sent);
481:
482: Event reply = (Event) peer2Observer.getDownMessages().get(
483: "message1");
484:
485: //assert that reply is the session key encrypted with peer's public key
486: assertTrue(((EncryptHeader) ((Message) reply.getArg())
487: .getHeader(ENCRYPT.EncryptHeader.KEY)).getType() == ENCRYPT.EncryptHeader.SECRETKEY);
488:
489: assertNotSame(peer.getDesKey(), peer2.getDesKey());
490: assertNotSame(server.getDesKey(), peer2.getDesKey());
491:
492: // now send back to peer
493: peer.up(reply);
494:
495: // assert that both now have same key
496: assertEquals(peer.getDesKey(), peer2.getDesKey());
497: assertNotSame(server.getDesKey(), peer.getDesKey());
498:
499: // send another encrypted message to peer to test queue
500: Message msg2 = new Message();
501: msg2.setBuffer("hello2".getBytes());
502:
503: Event evt2 = new Event(Event.MSG, msg2);
504:
505: peer2.down(evt2);
506:
507: Event Evt2 = (Event) peer2Observer.getDownMessages().get(
508: "message2");
509:
510: peer.up(Evt2);
511: // make sure we have the events now in the up layers
512: assertEquals(2, peerObserver.getUpMessages().size());
513:
514: Event tempEvt = (Event) peerObserver.getUpMessages().get(
515: "message2");
516:
517: assertEquals(new String(((Message) tempEvt.getArg())
518: .getBuffer()), "hello2");
519:
520: }
521:
522: class MockObserver implements ProtocolObserver {
523:
524: private Map upMessages = new HashMap();
525: private Map downMessages = new HashMap();
526: private int counter = 0;
527:
528: /* (non-Javadoc)
529: * @see org.jgroups.UpHandler#up(org.jgroups.Event)
530: */
531:
532: private void storeUp(Event evt) {
533: upMessages.put("message" + counter++, evt);
534: }
535:
536: private void storeDown(Event evt) {
537: downMessages.put("message" + counter++, evt);
538: }
539:
540: public void up(Event evt) {
541: storeUp(evt);
542: System.out.println("Up:" + evt.toString());
543:
544: }
545:
546: /* (non-Javadoc)
547: * @see org.jgroups.stack.ProtocolObserver#setProtocol(org.jgroups.stack.Protocol)
548: */
549: public void setProtocol(Protocol prot) {
550: }
551:
552: /* (non-Javadoc)
553: * @see org.jgroups.stack.ProtocolObserver#up(org.jgroups.Event, int)
554: */
555: public boolean up(Event evt, int num_evts) {
556: System.out.println("Up:" + evt.toString());
557:
558: return false;
559: }
560:
561: /* (non-Javadoc)
562: * @see org.jgroups.stack.ProtocolObserver#passUp(org.jgroups.Event)
563: */
564: public boolean passUp(Event evt) {
565: storeUp(evt);
566: System.out.println("PassUp:" + evt.toString());
567:
568: return false;
569: }
570:
571: /* (non-Javadoc)
572: * @see org.jgroups.stack.ProtocolObserver#down(org.jgroups.Event, int)
573: */
574: public boolean down(Event evt, int num_evts) {
575: System.out.println("down:" + evt.toString());
576:
577: return false;
578: }
579:
580: /* (non-Javadoc)
581: * @see org.jgroups.stack.ProtocolObserver#passDown(org.jgroups.Event)
582: */
583: public boolean passDown(Event evt) {
584: storeDown(evt);
585: System.out.println("passdown:" + evt.toString());
586:
587: return false;
588: }
589:
590: /**
591: * @return Returns the upMessages.
592: */
593: protected Map getUpMessages() {
594: return upMessages;
595: }
596:
597: /**
598: * @param upMessages The upMessages to set.
599: */
600: protected void setUpMessages(Map upMessages) {
601: this .upMessages = upMessages;
602: }
603:
604: /**
605: * @return Returns the downMessages.
606: */
607: protected Map getDownMessages() {
608: return downMessages;
609: }
610:
611: /**
612: * @param downMessages The downMessages to set.
613: */
614: protected void setDownMessages(Map downMessages) {
615: this .downMessages = downMessages;
616: }
617: }
618:
619: class MockAddress implements Address {
620:
621: /* (non-Javadoc)
622: * @see org.jgroups.Address#isMulticastAddress()
623: */
624: String name;
625:
626: public MockAddress(String name) {
627: this .name = name;
628: }
629:
630: public MockAddress() {
631: }
632:
633: public boolean isMulticastAddress() {
634: return false;
635: }
636:
637: public int size() {
638: return 0;
639: }
640:
641: /* (non-Javadoc)
642: * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
643: */
644: public void readExternal(ObjectInput in) throws IOException,
645: ClassNotFoundException {
646: }
647:
648: /* (non-Javadoc)
649: * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
650: */
651: public void writeExternal(ObjectOutput out) throws IOException {
652: }
653:
654: /* (non-Javadoc)
655: * @see java.lang.Comparable#compareTo(java.lang.Object)
656: */
657: public int compareTo(Object o) {
658: return -1;
659: }
660:
661: public boolean equals(Object obj) {
662: MockAddress address = (MockAddress) obj;
663: if (address.name.equals(this .name)) {
664: return true;
665: }
666: return false;
667: }
668:
669: public void writeTo(DataOutputStream out) throws IOException {
670: }
671:
672: public void readFrom(DataInputStream in) throws IOException,
673: IllegalAccessException, InstantiationException {
674: }
675: }
676:
677: }
|