1 3 6 7 9 package org.jgroups.protocols; 10 11 import org.jgroups.Address; 12 import org.jgroups.Event; 13 import org.jgroups.Message; 14 import org.jgroups.View; 15 import org.jgroups.stack.Protocol; 16 17 import javax.crypto.Cipher; 18 import javax.crypto.KeyGenerator; 19 import javax.crypto.SecretKey; 20 import javax.crypto.SecretKeyFactory; 21 import javax.crypto.spec.SecretKeySpec; 22 import java.io.IOException ; 23 import java.security.*; 24 import java.security.spec.X509EncodedKeySpec ; 25 import java.util.Properties ; 26 import java.util.Vector ; 27 28 31 public class ENCRYPT1_4 extends Protocol { 32 33 public static class EncryptHeader extends org.jgroups.Header { 34 int type; 35 static final int ENCRYPT=0; 36 static final int KEY_REQUEST=1; 37 static final int SERVER_PUBKEY=2; 38 static final int SECRETKEY=3; 39 static final int SECRETKEY_READY=4; 40 41 static final String KEY="encrypt"; 43 44 public EncryptHeader(){} 45 46 public EncryptHeader(int type) { 47 this.type=type; 48 } 49 50 public void writeExternal(java.io.ObjectOutput out) throws IOException { 51 out.writeInt(type); 52 } 53 54 public void readExternal(java.io.ObjectInput in) throws IOException , ClassNotFoundException { 55 type=in.readInt(); 56 } 57 58 public String toString() { 59 return "[ENCTYPT: <variables> ]"; 60 } 61 } 62 63 64 Address local_addr=null; 65 Address keyServerAddr=null; 66 boolean keyServer=false; 67 String asymAlgorithm="RSA"; 68 String symAlgorithm="DES/ECB/PKCS5Padding"; 69 int asymInit=512; int symInit=56; KeyPair Kpair; SecretKey desKey=null; 74 final PublicKey pubKey=null; PublicKey serverPubKey=null; Cipher cipher; 77 Cipher rsa; 78 final Vector members=new Vector (); 79 final Vector notReady=new Vector (); 80 81 public ENCRYPT1_4() { 82 } 85 86 87 public String getName() { 88 return "ENCRYPT1_4"; 89 } 90 91 92 95 private String getAlgorithm(String s) { 96 int index=s.indexOf("/"); 97 if(index == -1) 98 return s; 99 100 return s.substring(0, index); 101 } 102 103 104 public boolean setProperties(Properties props) { 105 String str; 106 107 super.setProperties(props); 108 str=props.getProperty("asymInit"); 110 if(str != null) { 111 asymInit=Integer.parseInt(str); 112 props.remove("asymInit"); 113 114 if(log.isInfoEnabled()) log.info("Asym algo bits used is " + asymInit); 115 } 116 117 str=props.getProperty("symInit"); 119 if(str != null) { 120 symInit=Integer.parseInt(str); 121 props.remove("symInit"); 122 123 if(log.isInfoEnabled()) log.info("Sym algo bits used is " + symInit); 124 } 125 126 str=props.getProperty("asymAlgorithm"); 128 if(str != null) { 129 asymAlgorithm=str; 130 props.remove("asymAlgorithm"); 131 132 if(log.isInfoEnabled()) log.info("Asym algo used is " + asymAlgorithm); 133 } 134 135 str=props.getProperty("symAlgorithm"); 137 if(str != null) { 138 symAlgorithm=str; 139 props.remove("symAlgorithm"); 140 141 if(log.isInfoEnabled()) log.info("Sym algo used is " + symAlgorithm); 142 } 143 if(props.size() > 0) { 144 145 if(log.isErrorEnabled()) log.error("these properties are not recognized:"+ props); 146 return false; 147 } 148 149 150 return true; 151 } 152 153 public void init() throws Exception { 154 KeyPairGenerator KpairGen=KeyPairGenerator.getInstance(getAlgorithm(asymAlgorithm)); 157 KpairGen.initialize(asymInit, new SecureRandom()); 158 Kpair=KpairGen.generateKeyPair(); 159 160 KeyGenerator keyGen=KeyGenerator.getInstance(getAlgorithm(symAlgorithm)); 162 keyGen.init(symInit); 163 desKey=keyGen.generateKey(); 164 165 rsa=Cipher.getInstance(asymAlgorithm); 167 cipher=Cipher.getInstance(symAlgorithm); 168 169 170 if(log.isInfoEnabled()) log.info(" Both asym and sym algo initialized with the single shared key"); 171 } 172 173 174 public void reset() { 175 } 176 177 public void up(Event evt) { 178 Message msg; 179 Message newMsg; 180 EncryptHeader hdr; 181 182 183 if(log.isInfoEnabled()) log.info("Event going up is " + evt); 184 185 switch(evt.getType()) { 186 case Event.SET_LOCAL_ADDRESS: 187 188 if(log.isInfoEnabled()) log.info("Set address call"); 189 local_addr=(Address)evt.getArg(); 190 break; 191 case Event.FIND_INITIAL_MBRS_OK: 192 Vector member=(Vector )evt.getArg(); 193 194 if(log.isInfoEnabled()) log.info("FIND_INIT members call, left members are " + member.size()); 195 196 197 if (!keyServer) 199 keyServer=member.size() > 0 ? false : true; 200 201 if(member != null && member.size() > 0) 202 keyServerAddr=((PingRsp) member.firstElement()).coord_addr; 203 else 204 keyServerAddr=local_addr; 205 206 if(!keyServer) 207 { 208 209 desKey=null; 210 211 if(log.isDebugEnabled()) log.debug("This is not keyserver, deskey set to null"); 212 newMsg=new Message(keyServerAddr, local_addr, Kpair.getPublic().getEncoded()); 214 newMsg.putHeader(EncryptHeader.KEY, new EncryptHeader(EncryptHeader.KEY_REQUEST)); 216 passDown(new Event(Event.MSG, newMsg)); 217 } 218 219 if(log.isInfoEnabled()) log.info("Done parsing for encrypt headers, sending upwards" + evt); 220 passUp(evt); 221 return; 222 223 case Event.MSG: 224 msg=(Message) evt.getArg(); 225 226 if(log.isInfoEnabled()) log.info("This is a message from peer, not control header" + msg); 227 228 if(msg == null) { 230 231 if(log.isDebugEnabled()) log.debug("Null message"); 232 passUp(evt); 233 return; 234 } 235 236 Object obj=msg.removeHeader(EncryptHeader.KEY); 239 240 if(log.isInfoEnabled()) log.info("Stripping the required protocol header"); 241 242 if(obj == null || !(obj instanceof EncryptHeader)) { 244 245 if(log.isInfoEnabled()) log.info("Dropping package as ENCRYPT1_4 protocol is not been recognized, msg will not be passed up"); 246 247 return; 250 } 251 252 hdr=(EncryptHeader) obj; 255 256 if(log.isInfoEnabled()) log.info("Header received " + hdr + ':' + hdr.type); 257 switch(hdr.type) { 258 case EncryptHeader.KEY_REQUEST: 260 try { 261 262 if(log.isDebugEnabled()) log.debug("Request for key"); 263 notReady.addElement(msg.getSrc()); 265 PublicKey pubKey=generatePubKey(msg.getBuffer()); 267 268 if(log.isDebugEnabled()) log.debug("Generated requestors public key"); 269 270 newMsg=new Message(msg.getSrc(), local_addr, Kpair.getPublic().getEncoded()); 272 newMsg.putHeader(EncryptHeader.KEY, new EncryptHeader(EncryptHeader.SERVER_PUBKEY)); 274 275 if(log.isDebugEnabled()) log.debug("Encoded servers public key using clients public key, only client can debug it using its private key and sending it back"); 276 passDown(new Event(Event.MSG, newMsg)); 277 278 rsa.init(Cipher.ENCRYPT_MODE, pubKey); 280 byte[] encryptedKey = rsa.doFinal(desKey.getEncoded()); 281 282 if(log.isDebugEnabled()) log.debug(" Generated encoded key which only client can decode"); 283 284 296 newMsg=new Message(msg.getSrc(), local_addr, encryptedKey); 298 newMsg.putHeader(EncryptHeader.KEY, new EncryptHeader(EncryptHeader.SECRETKEY)); 300 301 if(log.isDebugEnabled()) log.debug(" Sending encoded key to client"); 302 passDown(new Event(Event.MSG, newMsg)); 303 } 304 catch(Exception e) { 305 e.printStackTrace(); 306 System.out.println(e + "0"); 307 } 308 return; 309 case EncryptHeader.SECRETKEY_READY: 310 notReady.removeElement(msg.getSrc()); 312 313 if(log.isDebugEnabled()) log.debug("Removed client " + msg.getSrc() + "from notready list"); 314 return; 315 case EncryptHeader.SERVER_PUBKEY: 316 serverPubKey=generatePubKey(msg.getBuffer()); 317 318 if(log.isDebugEnabled()) log.debug(" Obtained the servers public key"); 319 return; 320 321 case EncryptHeader.SECRETKEY: 322 try { 323 rsa.init(Cipher.DECRYPT_MODE, Kpair.getPrivate()); 325 byte[] encodedKey = rsa.doFinal(msg.getBuffer()); 327 328 329 if(log.isDebugEnabled()) log.debug("generating encoded key obtained from server-admin"); 330 331 337 338 desKey=decodedKey(encodedKey); 340 if(desKey == null) 341 log.error("ohh oh !! DES key is null"); 342 343 344 newMsg=new Message(msg.getSrc(), local_addr, null); 346 newMsg.putHeader(EncryptHeader.KEY, new EncryptHeader(EncryptHeader.SECRETKEY_READY)); 348 passDown(new Event(Event.MSG, newMsg)); 349 350 if(log.isDebugEnabled()) log.debug("Got the deskey, sending down sec_Ready header"); 351 } 352 catch(Exception e) { 353 e.printStackTrace(); 354 System.out.println(e + "5"); 355 } 356 return; 357 358 default: 359 break; 360 } 361 362 if (hdr.type != 0) 363 log.error("Error , header is not 0"); 364 365 if(desKey == null) return; 368 369 370 if(log.isInfoEnabled()) log.info(" Starting to decypher messages"); 371 372 if(msg.getBuffer() != null) { 375 try { 376 cipher.init(Cipher.DECRYPT_MODE, desKey); 377 msg.setBuffer(cipher.doFinal(msg.getBuffer())); 378 } 379 catch(Exception e) { 380 e.printStackTrace(); 381 } 382 } 383 break; 384 } 385 386 if(log.isInfoEnabled()) log.info("Passing up event"); 387 passUp(evt); } 389 390 public void down(Event evt) { 391 Message msg; 392 Message newMsg; 393 boolean leave=false; 394 395 396 if(log.isInfoEnabled()) log.info("down:evt is " + evt + ':' + evt.getType()); 397 398 switch(evt.getType()) { 399 400 case Event.VIEW_CHANGE: 401 402 if(log.isInfoEnabled()) log.info("View change call, new member coming in"); 403 Vector new_members=((View)evt.getArg()).getMembers(); 404 405 if(members.size() > new_members.size()) leave=true; 407 408 synchronized(members) { 410 members.removeAllElements(); 411 if(new_members != null && new_members.size() > 0) 412 for(int i=0; i < new_members.size(); i++) 413 members.addElement(new_members.elementAt(i)); 414 } 416 if(leave) { 418 Object obj=members.firstElement(); 420 421 if(obj.equals(local_addr)) { 423 keyServer=true; 425 keyServerAddr=local_addr; 426 427 desKey=null; 429 430 if(log.isInfoEnabled()) log.info(" leave caused deskey to be null "); 431 432 try { 433 KeyGenerator keyGen=KeyGenerator.getInstance(getAlgorithm(symAlgorithm)); 435 keyGen.init(symInit); 436 desKey=keyGen.generateKey(); 437 } 438 catch(Exception e) { 439 e.printStackTrace(); 440 } 441 } else { 444 keyServer=false; 445 keyServerAddr=(Address)obj; 446 447 desKey=null; 449 450 newMsg=new Message(keyServerAddr, local_addr, Kpair.getPublic().getEncoded()); 452 newMsg.putHeader(EncryptHeader.KEY, new EncryptHeader(EncryptHeader.KEY_REQUEST)); 454 passDown(new Event(Event.MSG, newMsg)); 455 456 if(log.isDebugEnabled()) log.debug("Requesting new key to be part of group"); 457 } } 459 break; 460 461 case Event.MSG: 462 msg= (Message) evt.getArg(); 463 464 if(log.isDebugEnabled()) log.debug("Its a message call " + msg); 465 int i; 466 467 if(!notReady.isEmpty()) 470 { 471 System.out.println("not Ready list :" + notReady.toString()); 472 if(msg.getDest() == null) { 473 for(i=0; i < notReady.size(); i++) { 474 newMsg=new Message((Address)notReady.elementAt(i), local_addr, msg.getBuffer()); 476 passDown(new Event(Event.MSG, newMsg)); 477 } 478 break; 479 } 480 else 481 { 482 for(i=0; i < notReady.size(); i++) { 483 if(msg.getDest() == notReady.elementAt(i)) { 484 passDown(evt); 485 return; 486 } } } } 490 491 if(desKey != null) 493 { 494 495 496 if(log.isInfoEnabled()) log.info("DESkey is not null, I know it "); 497 try 498 { 499 if(msg.getBuffer() != null) 501 { 502 cipher.init(Cipher.ENCRYPT_MODE, desKey); 503 msg.setBuffer(cipher.doFinal(msg.getBuffer())); 504 msg.putHeader(EncryptHeader.KEY, new EncryptHeader(0)); 505 506 if(log.isInfoEnabled()) log.info(" have DES key , package sent"); 507 } 508 else 509 { 510 msg.setBuffer(null); 511 msg.putHeader(EncryptHeader.KEY, new EncryptHeader(0)); 512 513 if(log.isInfoEnabled()) log.info(" buffer null, added header"); 514 } 515 }catch(Exception e) 516 { 517 e.printStackTrace(); 518 } 519 } 520 break; 521 } 523 if(log.isInfoEnabled()) log.info("Pass Down: " + evt.toString()); 524 passDown(evt); } 526 527 private SecretKey decodedKey(byte[] encodedKey) { 528 SecretKey key=null; 529 try { 530 SecretKeyFactory KeyFac=SecretKeyFactory.getInstance(getAlgorithm(symAlgorithm)); 532 SecretKeySpec desKeySpec=new SecretKeySpec(encodedKey, getAlgorithm(symAlgorithm)); 533 key=KeyFac.generateSecret(desKeySpec); 534 } 535 catch(Exception e) { 536 e.printStackTrace(); 537 } 538 return key; 539 } 540 541 private PublicKey generatePubKey(byte[] encodedKey) { 542 PublicKey pubKey=null; 543 try { 544 KeyFactory KeyFac=KeyFactory.getInstance(getAlgorithm(asymAlgorithm)); 545 X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec (encodedKey); 546 pubKey=KeyFac.generatePublic(x509KeySpec); 547 } 548 catch(Exception e) { 549 e.printStackTrace(); 550 } 551 return pubKey; 552 } 553 } 554 | Popular Tags |