00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.ext.security;
00032
00033 import java.io.ByteArrayInputStream;
00034 import java.io.ByteArrayOutputStream;
00035 import java.io.File;
00036 import java.io.IOException;
00037 import java.io.Serializable;
00038 import java.security.InvalidAlgorithmParameterException;
00039 import java.security.InvalidKeyException;
00040 import java.security.Key;
00041 import java.security.KeyFactory;
00042 import java.security.KeyPair;
00043 import java.security.KeyStore;
00044 import java.security.KeyStoreException;
00045 import java.security.NoSuchAlgorithmException;
00046 import java.security.NoSuchProviderException;
00047 import java.security.PrivateKey;
00048 import java.security.Provider;
00049 import java.security.PublicKey;
00050 import java.security.SecureRandom;
00051 import java.security.Security;
00052 import java.security.Signature;
00053 import java.security.SignatureException;
00054 import java.security.SignedObject;
00055
00056 import java.security.UnrecoverableKeyException;
00057 import java.security.cert.CertificateEncodingException;
00058 import java.security.cert.CertificateException;
00059 import java.security.cert.CertificateExpiredException;
00060 import java.security.cert.CertificateFactory;
00061 import java.security.cert.CertificateNotYetValidException;
00062 import java.security.cert.X509Certificate;
00063 import java.security.spec.X509EncodedKeySpec;
00064 import java.util.ArrayList;
00065 import java.util.Enumeration;
00066 import java.util.Hashtable;
00067 import java.util.Random;
00068
00069 import javax.crypto.BadPaddingException;
00070 import javax.crypto.Cipher;
00071 import javax.crypto.IllegalBlockSizeException;
00072 import javax.crypto.KeyGenerator;
00073 import javax.crypto.SecretKey;
00074 import javax.crypto.spec.IvParameterSpec;
00075 import javax.crypto.spec.SecretKeySpec;
00076
00077 import org.apache.log4j.Logger;
00078 import org.objectweb.proactive.core.body.UniversalBody;
00079 import org.objectweb.proactive.core.util.log.Loggers;
00080 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00081 import org.objectweb.proactive.ext.security.crypto.AuthenticationException;
00082 import org.objectweb.proactive.ext.security.crypto.AuthenticationTicket;
00083 import org.objectweb.proactive.ext.security.crypto.AuthenticationTicketProperty;
00084 import org.objectweb.proactive.ext.security.crypto.ConfidentialityTicket;
00085 import org.objectweb.proactive.ext.security.crypto.KeyExchangeException;
00086 import org.objectweb.proactive.ext.security.crypto.RandomLongGenerator;
00087 import org.objectweb.proactive.ext.security.crypto.Session;
00088 import org.objectweb.proactive.ext.security.exceptions.CommunicationForbiddenException;
00089 import org.objectweb.proactive.ext.security.exceptions.InvalidPolicyFile;
00090 import org.objectweb.proactive.ext.security.exceptions.RenegotiateSessionException;
00091 import org.objectweb.proactive.ext.security.exceptions.SecurityNotAvailableException;
00092 import org.objectweb.proactive.ext.security.securityentity.Entity;
00093 import org.objectweb.proactive.ext.security.securityentity.EntityVirtualNode;
00094
00095 import sun.rmi.server.MarshalOutputStream;
00096
00097
00102 public class ProActiveSecurityManager implements Serializable, SecurityEntity {
00103 static Logger logger = ProActiveLogger.getLogger(Loggers.SECURITY);
00104
00105
00106 protected Hashtable<Long,Session> sessions;
00107
00108
00109 protected transient RandomLongGenerator randomLongGenerator;
00110
00111
00112 protected PolicyServer policyServer;
00113
00114
00115 protected KeyStore keyStore;
00116
00117
00118 protected transient UniversalBody myBody;
00119 protected String VNName;
00120
00121
00122
00123
00124 protected SecurityEntity parent;
00125 protected byte[] encodedKeyStore;
00126
00127
00128 protected int type;
00129
00133 public ProActiveSecurityManager() {
00134 this.sessions = new Hashtable<Long,Session>();
00135 this.policyServer = null;
00136 }
00137
00138 public ProActiveSecurityManager(String file)
00139 throws java.io.IOException, InvalidPolicyFile {
00140 Provider myProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
00141 Security.addProvider(myProvider);
00142 sessions = new Hashtable<Long,Session>();
00143
00144 if ((new File(file)).exists()) {
00145 this.policyServer = ProActiveSecurityDescriptorHandler.createPolicyServer(file);
00146 keyStore = policyServer.getKeyStore();
00147 }
00148 logger.debug("psm" + file +
00149 " +-+--+-+-++-+-+-++-++-+--+-+-+-+-+-+-+-+-+-+-+-++--+-+-+-+-+-+-+-+ ");
00150 }
00151
00155 public ProActiveSecurityManager(PolicyServer server) {
00156 this();
00157
00158 this.policyServer = server;
00159 this.keyStore = server.getKeyStore();
00160 }
00161
00166 public ProActiveSecurityManager(KeyStore keyStore, PolicyServer policyServer) {
00167 this();
00168 this.policyServer = policyServer;
00169 this.keyStore = keyStore;
00170 }
00171
00172 public void setBody(UniversalBody body) {
00173 myBody = body;
00174 }
00175
00181 public SecurityContext getPolicy(SecurityContext securityContext)
00182 throws SecurityNotAvailableException {
00183
00184 if (this.parent != null) {
00185 try {
00186 securityContext = this.parent.getPolicy(securityContext);
00187 } catch (SecurityNotAvailableException e) {
00188 e.printStackTrace();
00189 } catch (IOException e) {
00190 e.printStackTrace();
00191 }
00192 }
00193
00194
00195 securityContext = this.policyServer.getPolicy(securityContext);
00196
00197 return securityContext;
00198 }
00199
00204 public Communication getPolicyTo(String type, String from, String to)
00205 throws SecurityNotAvailableException {
00206 if (policyServer == null) {
00207 throw new SecurityNotAvailableException();
00208 }
00209 return policyServer.getPolicyTo(type, from, to);
00210 }
00211
00219 public void initiateSession(int type, SecurityEntity distantSecurityEntity)
00220 throws CommunicationForbiddenException,
00221 org.objectweb.proactive.ext.security.crypto.AuthenticationException,
00222 RenegotiateSessionException, SecurityNotAvailableException {
00223
00224 Communication localPolicy = null;
00225 Communication distantBodyPolicy = null;
00226
00227 PolicyServer runtimePolicyServer = null;
00228
00229 X509Certificate distantBodyCertificate = null;
00230 try {
00231 distantBodyCertificate = ProActiveSecurity.decodeCertificate(distantSecurityEntity.getCertificateEncoded());
00232 } catch (SecurityNotAvailableException e3) {
00233 e3.printStackTrace();
00234 } catch (IOException e) {
00235 e.printStackTrace();
00236 }
00237
00238 Communication runtimePolicy;
00239 Communication VNPolicy;
00240 Communication distantPolicy;
00241 runtimePolicy = VNPolicy = distantBodyPolicy = null;
00242 ArrayList<Entity> arrayFrom = new ArrayList<Entity>();
00243 ArrayList<Entity> arrayTo = new ArrayList<Entity>();
00244
00245
00246 arrayFrom = this.getEntities();
00247
00248 try {
00249 arrayTo = distantSecurityEntity.getEntities();
00250 } catch (SecurityNotAvailableException e2) {
00251 e2.printStackTrace();
00252 } catch (IOException e2) {
00253 e2.printStackTrace();
00254 }
00255
00256
00257 SecurityContext sc = new SecurityContext(SecurityContext.COMMUNICATION_SEND_REQUEST_TO,
00258 arrayFrom, arrayTo);
00259
00260 sc = policyServer.getPolicy(sc);
00261
00262 localPolicy = sc.getSendRequest();
00263
00264 if (!localPolicy.isCommunicationAllowed()) {
00265 throw new CommunicationForbiddenException(
00266 "Sending request is denied");
00267 }
00268
00269
00270 SecurityContext scDistant = new SecurityContext(SecurityContext.COMMUNICATION_RECEIVE_REQUEST_FROM,
00271 arrayFrom, arrayTo);
00272
00273 try {
00274 scDistant = distantSecurityEntity.getPolicy(scDistant);
00275 } catch (SecurityNotAvailableException e1) {
00276 e1.printStackTrace();
00277 } catch (IOException e) {
00278 e.printStackTrace();
00279 }
00280
00281 distantPolicy = scDistant.getReceiveRequest();
00282
00283 if (!distantPolicy.isCommunicationAllowed()) {
00284 throw new CommunicationForbiddenException(
00285 "Receiving request denied ");
00286 }
00287
00288 if (distantBodyPolicy == null) {
00289 distantBodyPolicy = new Communication();
00290 }
00291
00292
00293 Communication resultPolicy = Communication.computeCommunication(localPolicy,
00294 distantBodyPolicy);
00295
00296 long sessionID = 0;
00297 Session session = null;
00298 boolean sessionAccepted = false;
00299
00300 try {
00301 while (!sessionAccepted) {
00302
00303 sessionID = distantSecurityEntity.startNewSession(resultPolicy);
00304 Long longId = new Long(sessionID);
00305
00306 if ((session = (Session) sessions.get(longId)) == null) {
00307 session = new Session(sessionID, resultPolicy);
00308 session.setDistantOACertificate(distantBodyCertificate);
00309 sessions.put(new Long(sessionID), session);
00310 sessionAccepted = true;
00311 ProActiveLogger.getLogger(Loggers.SECURITY_MANAGER).debug("adding new session " +
00312 sessionID);
00313 } else if (this.getCertificate().equals(distantBodyCertificate)) {
00314
00315
00316 session.setDistantOACertificate(distantBodyCertificate);
00317 sessionAccepted = true;
00318 ProActiveLogger.getLogger(Loggers.SECURITY_MANAGER).debug("adding new session : " +
00319 sessionID);
00320 }
00321
00322
00323 }
00324 } catch (Exception e) {
00325 logger.warn("can't start a new session");
00326 e.printStackTrace();
00327 throw new org.objectweb.proactive.ext.security.crypto.AuthenticationException();
00328 }
00329
00330 try {
00331 if (distantBodyCertificate != null) {
00332 session.setDistantOAPublicKey(distantBodyCertificate.getPublicKey());
00333 } else {
00334 ProActiveLogger.getLogger(Loggers.SECURITY_PSM).debug("WARNING remote object scertificate is null");
00335 session.setDistantOAPublicKey(distantSecurityEntity.getPublicKey());
00336 }
00337
00338 ProActiveLogger.getLogger(Loggers.SECURITY_MANAGER).debug("adding new session " +
00339 sessionID + " distant object is " +
00340 distantSecurityEntity.getCertificate().getSubjectDN() +
00341 "\n local object is " + this.getCertificate().getSubjectDN());
00342
00343 keyNegociationSenderSide(distantSecurityEntity, sessionID);
00344
00345
00346 session.setSessionValidated(true);
00347 } catch (KeyExchangeException e) {
00348 logger.warn("Key exchange exception ");
00349 e.printStackTrace();
00350 throw new CommunicationForbiddenException();
00351 } catch (Exception e) {
00352 e.printStackTrace();
00353 }
00354 }
00355
00356 public X509Certificate getCertificate() {
00357 try {
00358 if (this.keyStore == null) {
00359 return null;
00360 }
00361
00362 return (X509Certificate) this.keyStore.getCertificate(SecurityConstants.KEYSTORE_ENTITY_PATH);
00363 } catch (KeyStoreException e) {
00364 e.printStackTrace();
00365 }
00366 return null;
00367 }
00368
00369 public void terminateSession(UniversalBody body, long sessionID) {
00370 terminateSession(sessionID);
00371 }
00372
00373 public void terminateSession(long sessionID) {
00374 synchronized (sessions) {
00375 sessions.remove(new Long(sessionID));
00376 }
00377 }
00378
00383 public synchronized long startNewSession(Communication communicationPolicy) {
00384 long id = 0;
00385 PolicyRule defaultPolicy = new PolicyRule();
00386
00387
00388 try {
00389 boolean sessionAccepted = false;
00390 Long longId;
00391 do {
00392 id = new Random().nextLong() + System.currentTimeMillis();
00393 longId = new Long(id);
00394 if (sessions.get(longId) == null) {
00395
00396
00397
00398
00399 Session newSession = new Session(id, communicationPolicy);
00400 sessions.put(longId, newSession);
00401 sessionAccepted = true;
00402 }
00403 } while (!sessionAccepted);
00404 } catch (Exception e) {
00405 e.printStackTrace();
00406 }
00407
00408 ProActiveLogger.getLogger(Loggers.SECURITY).debug("starting a new session : " +
00409 id);
00410 return id;
00411 }
00412
00419 public byte[][] encrypt(long sessionID, Object object, int type)
00420 throws RenegotiateSessionException {
00421 Session session = (Session) sessions.get(new Long(sessionID));
00422
00423 if (session != null) {
00424 try {
00425 while (!session.isSessionValidated()) {
00426
00427 Thread.sleep(50);
00428 }
00429
00430 ProActiveLogger.getLogger(Loggers.SECURITY).debug("Ciphering object, session is " +
00431 sessionID);
00432 ByteArrayOutputStream bout = new ByteArrayOutputStream();
00433 MarshalOutputStream out = new MarshalOutputStream(bout);
00434 out.writeObject(object);
00435 out.flush();
00436 out.close();
00437
00438 byte[] byteArray = bout.toByteArray();
00439
00440 bout.close();
00441
00442 return session.writePDU(byteArray, type);
00443 } catch (Exception e) {
00444 throw new RenegotiateSessionException(
00445 "Something wrong when I tried to crypt the message");
00446 }
00447
00448
00449 } else {
00450 throw new RenegotiateSessionException(
00451 "Requested session was not found, need to negotiate another one");
00452 }
00453 }
00454
00461 public byte[] decrypt(long sessionID, byte[][] message, int type)
00462 throws RenegotiateSessionException {
00463 Session session = (Session) sessions.get(new Long(sessionID));
00464 if (session != null) {
00465 try {
00466 int counterLimit = SecurityConstants.MAX_SESSION_VALIDATION_WAIT;
00467 while (!session.isSessionValidated() && (counterLimit > 0)) {
00468
00469 Thread.sleep(50);
00470 counterLimit--;
00471 }
00472
00473 if (counterLimit == 0) {
00474 throw new RenegotiateSessionException(
00475 "Decrypting Request, session validation delay has expired");
00476 }
00477 return session.readPDU(message[0], message[1], type);
00478 } catch (IOException e) {
00479 throw new RenegotiateSessionException(
00480 "Decrypting the session was not found, need to renegotiate a new one");
00481 } catch (InterruptedException e) {
00482 e.printStackTrace();
00483 }
00484 } else {
00485 throw new RenegotiateSessionException(
00486 "While decrypting the session was not found, need to renegotiate a new one");
00487 }
00488
00489 return null;
00490 }
00491
00492 public boolean mutualAuthenticationSenderSide(UniversalBody distantBody,
00493 X509Certificate distantBodyCertificate) throws AuthenticationException {
00494 checkCertificate(distantBodyCertificate);
00495 unilateralAuthenticationSenderSide(distantBody);
00496
00497 return true;
00498 }
00499
00505 private boolean checkCertificate(X509Certificate distantBodyCertificate) {
00506
00507 try {
00508 distantBodyCertificate.checkValidity();
00509 } catch (CertificateExpiredException e) {
00510 logger.warn(distantBodyCertificate.getSubjectDN() +
00511 " has expired, negociation stopped");
00512
00513 return false;
00514 } catch (CertificateNotYetValidException e) {
00515 logger.warn(distantBodyCertificate.getSubjectDN() +
00516 " is not yet valid, negociation stopped");
00517
00518 return false;
00519 }
00520
00521
00522 String domainLocation = distantBodyCertificate.getIssuerDN().getName();
00523
00524 return true;
00525 }
00526
00527 public boolean unilateralAuthenticationSenderSide(UniversalBody distantBody)
00528 throws AuthenticationException {
00529 long rb = randomLongGenerator.generateLong(32);
00530 AuthenticationTicket authenticationTicket = new AuthenticationTicket();
00531 String B = this.getCertificate().getIssuerDN().getName();
00532 long ra = authenticationTicket.random;
00533 String addresse = authenticationTicket.identity;
00534
00535 if (addresse.equals(B) == false) {
00536 throw new AuthenticationException(
00537 "SessionInitializer : WRONG IDENTITY");
00538 }
00539
00540
00541 X509Certificate emitterCertificate = authenticationTicket.certificate;
00542 String A = emitterCertificate.getIssuerDN().getName();
00543
00544
00545 checkCertificate(emitterCertificate);
00546
00547 AuthenticationTicketProperty properties = new AuthenticationTicketProperty();
00548
00549 try {
00550 properties = (AuthenticationTicketProperty) ((SignedObject) authenticationTicket.signedAuthenticationTicketProperty).getObject();
00551 } catch (Exception e) {
00552 System.out.println(
00553 "SessionInitializer : Exception in AuthenticationTicketProperty extraction : " +
00554 e);
00555 }
00556
00557 if (properties.random1 != ra) {
00558 throw new AuthenticationException("SessionInitializer : wrong ra");
00559 }
00560
00561 if (properties.random2 != rb) {
00562 throw new AuthenticationException("SessionInitializer : wrong rb");
00563 }
00564
00565 if (properties.identity.equals(B) == false) {
00566 throw new AuthenticationException("SessionInitializer : wrong B");
00567 }
00568
00569
00570 return true;
00571 }
00572
00580 public boolean keyNegociationSenderSide(
00581 SecurityEntity distantSecurityEntity, long sessionID)
00582 throws KeyExchangeException {
00583 Session session = (Session) sessions.get(new Long(sessionID));
00584
00585 if (session == null) {
00586 throw new KeyExchangeException("the session is null");
00587 }
00588
00589 try {
00590
00591
00592
00593
00594
00595
00596
00597
00598 session.sec_rand.nextBytes(session.cl_rand);
00599 session.se_rand = distantSecurityEntity.randomValue(sessionID,
00600 session.cl_rand);
00601
00602
00603
00604
00605
00606
00607
00608
00609 byte[] my_pub;
00610 byte[] my_cert;
00611 byte[] sig_code;
00612
00613 Signature sig;
00614
00615
00616 sig = Signature.getInstance("MD5withRSA", "BC");
00617
00618
00619
00620
00621 sig.initSign(this.getPrivateKey(), session.sec_rand);
00622
00623
00624
00625
00626
00627 sig.update(session.cl_rand);
00628 sig.update(session.se_rand);
00629
00630
00631
00632
00633 my_pub = this.getPublicKey().getEncoded();
00634
00635
00636
00637
00638 my_cert = this.getCertificateEncoded();
00639
00640 sig.update(my_pub);
00641 sig.update(my_cert);
00642
00643 sig_code = sig.sign();
00644
00645
00646
00647
00648
00649 byte[][] tab = distantSecurityEntity.publicKeyExchange(sessionID,
00650 my_pub, my_cert, sig_code);
00651
00652
00653
00654
00655
00656
00657
00658
00659 byte[] pub_key = tab[0];
00660
00661
00662
00663
00664
00665
00666 X509EncodedKeySpec key_spec = new X509EncodedKeySpec(pub_key);
00667
00668
00669 KeyFactory key_fact = KeyFactory.getInstance("RSA", "BC");
00670
00671
00672
00673
00674 session.distantOAPublicKey = key_fact.generatePublic(key_spec);
00675
00676
00677
00678
00679
00680
00681 byte[] cert = tab[1];
00682
00683
00684
00685
00686
00687
00688 CertificateFactory cf = CertificateFactory.getInstance("X.509");
00689
00690
00691
00692
00693 session.distantOACertificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(
00694 cert));
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705 sig_code = tab[2];
00706
00707
00708
00709
00710
00711
00712
00713
00714 sig.initVerify(session.distantOACertificate);
00715 sig.update(session.cl_rand);
00716 sig.update(session.se_rand);
00717 sig.update(pub_key);
00718 sig.update(cert);
00719
00720 if (!sig.verify(sig_code)) {
00721 throw new Exception(
00722 "(CLIENT)Signature failed on Public key exchange data unit");
00723 }
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 KeyGenerator key_gen = KeyGenerator.getInstance("AES", "BC");
00736
00737 key_gen.init(192, session.sec_rand);
00738 session.cl_aes_key = key_gen.generateKey();
00739
00740 key_gen.init(160, session.sec_rand);
00741 session.cl_hmac_key = key_gen.generateKey();
00742
00743
00744
00745
00746
00747
00748 byte[] cl_iv = new byte[16];
00749 session.cl_iv = new IvParameterSpec(cl_iv);
00750
00751 byte[] aes_key;
00752 byte[] iv;
00753 byte[] mac;
00754 byte[] lock;
00755 byte[] sigtab;
00756
00757
00758
00759
00760
00761 byte[] tmp_lock = new byte[24];
00762 Cipher aes_lock = null;
00763
00764
00765
00766
00767
00768
00769 session.cl_cipher.init(Cipher.ENCRYPT_MODE, session.cl_aes_key,
00770 session.cl_iv, session.sec_rand);
00771
00772
00773
00774
00775 session.cl_mac.init(session.cl_hmac_key);
00776
00777
00778
00779
00780 session.sec_rand.nextBytes(tmp_lock);
00781
00782
00783
00784
00785 session.rsa_eng.init(Cipher.ENCRYPT_MODE,
00786 session.distantOAPublicKey, session.sec_rand);
00787
00788
00789
00790
00791 aes_lock = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
00792 aes_lock.init(Cipher.ENCRYPT_MODE, session.cl_aes_key,
00793 session.cl_iv, session.sec_rand);
00794
00795
00796
00797
00798
00799
00800
00801 sig.initSign(this.getPrivateKey());
00802 sig.update(session.cl_rand);
00803 sig.update(session.se_rand);
00804
00805 aes_key = session.rsa_eng.doFinal(session.cl_aes_key.getEncoded());
00806 sig.update(aes_key);
00807
00808 iv = session.rsa_eng.doFinal(session.cl_iv.getIV());
00809 sig.update(iv);
00810
00811 mac = session.rsa_eng.doFinal(session.cl_hmac_key.getEncoded());
00812 sig.update(mac);
00813
00814 lock = aes_lock.doFinal(tmp_lock);
00815 sig.update(tmp_lock);
00816
00817
00818 sigtab = sig.sign();
00819
00820 byte[][] tabresult = distantSecurityEntity.secretKeyExchange(sessionID,
00821 aes_key, iv, mac, lock, sigtab);
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 byte[] aes_key_enc;
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845 byte[] iv_enc;
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857 byte[] hmac_key_enc;
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 byte[] tmp_loc;
00870
00871 session.rsa_eng.init(Cipher.DECRYPT_MODE, this.getPrivateKey(),
00872 session.sec_rand);
00873
00874
00875
00876
00877 aes_key_enc = tabresult[0];
00878
00879
00880
00881
00882 iv_enc = tabresult[1];
00883
00884
00885
00886
00887 hmac_key_enc = tabresult[2];
00888
00889
00890
00891
00892 tmp_loc = tabresult[3];
00893
00894
00895
00896
00897
00898
00899
00900
00901 SecretKey sk = (SecretKey) new SecretKeySpec(session.rsa_eng.doFinal(
00902 aes_key_enc), "AES");
00903 IvParameterSpec ivspec = new IvParameterSpec(session.rsa_eng.doFinal(
00904 iv_enc));
00905 aes_lock.init(Cipher.DECRYPT_MODE, sk, ivspec);
00906 sig.initVerify(session.distantOACertificate);
00907 sig.update(session.cl_rand);
00908 sig.update(session.se_rand);
00909 sig.update(aes_key_enc);
00910 sig.update(iv_enc);
00911 sig.update(hmac_key_enc);
00912 sig.update(aes_lock.doFinal(tmp_loc));
00913
00914 if (!sig.verify(tabresult[4])) {
00915 throw new Exception(
00916 "Signature failed on Public key exchange data unit");
00917 } else {
00918
00919 }
00920
00921
00922
00923
00924
00925
00926
00927 session.se_aes_key = (SecretKey) new SecretKeySpec(session.rsa_eng.doFinal(
00928 aes_key_enc), "AES");
00929 session.se_iv = new IvParameterSpec(session.rsa_eng.doFinal(iv_enc));
00930 session.se_cipher.init(Cipher.DECRYPT_MODE, session.se_aes_key,
00931 session.se_iv);
00932
00933
00934
00935
00936
00937 session.se_hmac_key = (SecretKey) new SecretKeySpec(session.rsa_eng.doFinal(
00938 hmac_key_enc), "AES");
00939 session.se_mac.init(session.se_hmac_key);
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 } catch (Exception e) {
00950 e.printStackTrace();
00951 throw new KeyExchangeException(
00952 "something wrong with the key exchange, see the stack trace");
00953 }
00954
00955 return true;
00956 }
00957
00958 protected PrivateKey getPrivateKey() {
00959 try {
00960 return (PrivateKey) keyStore.getKey(SecurityConstants.KEYSTORE_ENTITY_PATH,
00961 null);
00962 } catch (KeyStoreException e) {
00963 e.printStackTrace();
00964 } catch (NoSuchAlgorithmException e) {
00965 e.printStackTrace();
00966 } catch (UnrecoverableKeyException e) {
00967 e.printStackTrace();
00968 }
00969
00970 return null;
00971 }
00972
00973 public AuthenticationTicket mutualAuthenticationReceiverSide(
00974 AuthenticationTicket authenticationTicket, long randomID)
00975 throws org.objectweb.proactive.ext.security.crypto.AuthenticationException {
00976 return null;
00977 }
00978
00983 private Key generateSessionKey() {
00984 try {
00985 KeyGenerator keyGen = KeyGenerator.getInstance("Rijndael", "BC");
00986 keyGen.init(128, new SecureRandom());
00987
00988 return keyGen.generateKey();
00989 } catch (java.security.NoSuchProviderException e) {
00990 e.printStackTrace();
00991 } catch (java.security.NoSuchAlgorithmException e) {
00992 e.printStackTrace();
00993 }
00994
00995 return null;
00996 }
00997
00998 public AuthenticationTicket unilateralAuthenticationReceiverSide(
00999 long randomID, long rb, String emittor) throws AuthenticationException {
01000 return null;
01001 }
01002
01003 public ConfidentialityTicket keyNegociationReceiverSide(
01004 ConfidentialityTicket confidentialityTicket, long randomID)
01005 throws KeyExchangeException {
01006 return null;
01007 }
01008
01009 public byte[] randomValue(long sessionID, byte[] clientRandomValue)
01010 throws SecurityNotAvailableException, RenegotiateSessionException {
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024 Session session = (Session) sessions.get(new Long(sessionID));
01025
01026
01027 if (session == null) {
01028 throw new RenegotiateSessionException(
01029 "Session not started,session is null");
01030 }
01031
01032 try {
01033
01034 session.cl_rand = clientRandomValue;
01035
01036
01037
01038
01039 session.sec_rand.nextBytes(session.se_rand);
01040
01041
01042 } catch (Exception e) {
01043 System.out.println("Server: Hello failed");
01044 e.printStackTrace();
01045 }
01046
01047 return session.se_rand;
01048 }
01049
01050 public byte[][] publicKeyExchange(long sessionID, byte[] pub_key,
01051 byte[] cert, byte[] signature)
01052 throws SecurityNotAvailableException, RenegotiateSessionException,
01053 KeyExchangeException {
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070 Session session = (Session) sessions.get(new Long(sessionID));
01071
01072 if (session == null) {
01073 throw new KeyExchangeException("Session not started");
01074 }
01075
01076 try {
01077
01078
01079
01080
01081
01082
01083
01084
01085 X509EncodedKeySpec key_spec = new X509EncodedKeySpec(pub_key);
01086 KeyFactory key_fact = KeyFactory.getInstance("RSA", "BC");
01087 session.distantOAPublicKey = key_fact.generatePublic(key_spec);
01088
01089 CertificateFactory cf = CertificateFactory.getInstance("X.509");
01090
01091
01092 session.distantOACertificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(
01093 cert));
01094
01095 Signature sig = null;
01096
01097 sig = Signature.getInstance("MD5withRSA", "BC");
01098 sig.initVerify(session.distantOAPublicKey);
01099 sig.update(session.cl_rand);
01100 sig.update(session.se_rand);
01101 sig.update(pub_key);
01102 sig.update(cert);
01103
01104 if (!sig.verify(signature)) {
01105 System.out.println(session);
01106 logger.warn("Signature failed on Public key exchange data unit");
01107 throw new Exception(
01108 "Signature failed on Public key exchange data unit");
01109 } else {
01110
01111 }
01112
01113
01114
01115
01116
01117
01118
01119
01120 sig.initSign(this.getPrivateKey());
01121 sig.update(session.cl_rand);
01122 sig.update(session.se_rand);
01123
01124
01125
01126
01127 byte[] my_pub = this.getPublicKey().getEncoded();
01128
01129
01130
01131
01132
01133 byte[] my_cert = this.getCertificateEncoded();
01134 sig.update(my_pub);
01135 sig.update(my_cert);
01136
01137 byte[][] result = new byte[4][];
01138 result[0] = this.getPublicKey().getEncoded();
01139 result[1] = this.getCertificateEncoded();
01140 signature = sig.sign();
01141 result[2] = signature;
01142
01143
01144 return result;
01145 } catch (Exception e) {
01146 e.printStackTrace();
01147 throw new KeyExchangeException(e.toString());
01148 }
01149 }
01150
01151 public static String displayByte(byte[] tab) {
01152 String s = "";
01153
01154 for (int i = 0; i < tab.length; i++) {
01155 s += tab[i];
01156 }
01157
01158 return s;
01159 }
01160
01171 public byte[][] secretKeyExchange(long sessionID, byte[] aesKey, byte[] iv,
01172 byte[] macKey, byte[] lockData, byte[] signatur) {
01173 byte[][] result = new byte[5][];
01174
01175 try {
01176 Session session = (Session) sessions.get(new Long(sessionID));
01177
01178 if (session == null) {
01179 return result;
01180 }
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196 byte[] clientAESKeyEncoded = aesKey;
01197
01198
01199
01200
01201 byte[] clientIVEncoded = iv;
01202
01203
01204
01205
01206 byte[] clientHMACKeyEncoded = macKey;
01207
01208
01209
01210
01211 byte[] clientLockData = lockData;
01212
01213
01214
01215
01216
01217
01218
01219 session.rsa_eng.init(Cipher.DECRYPT_MODE, this.getPrivateKey(),
01220 session.sec_rand);
01221
01222 SecretKey sk = (SecretKey) new SecretKeySpec(session.rsa_eng.doFinal(
01223 clientAESKeyEncoded), "AES");
01224
01225 IvParameterSpec ivspec = new IvParameterSpec(session.rsa_eng.doFinal(
01226 clientIVEncoded));
01227
01228 session.se_cipher.init(Cipher.DECRYPT_MODE, sk, ivspec,
01229 session.sec_rand);
01230
01231 Signature sig = Signature.getInstance("MD5withRSA", "BC");
01232
01233 sig.initVerify(session.distantOACertificate);
01234
01235 sig.update(session.cl_rand);
01236 sig.update(session.se_rand);
01237 sig.update(clientAESKeyEncoded);
01238 sig.update(clientIVEncoded);
01239 sig.update(clientHMACKeyEncoded);
01240 byte[] lock = session.se_cipher.doFinal(lockData);
01241 sig.update(lock);
01242
01243 if (!sig.verify(signatur)) {
01244 throw new KeyExchangeException(
01245 "(Server) :Signature failed on Public key exchange data unit");
01246 }
01247
01248
01249
01250
01251
01252 session.cl_aes_key = (SecretKey) new SecretKeySpec(session.rsa_eng.doFinal(
01253 clientAESKeyEncoded), "AES");
01254 session.cl_iv = new IvParameterSpec(session.rsa_eng.doFinal(
01255 clientIVEncoded));
01256 session.cl_cipher.init(Cipher.DECRYPT_MODE, session.cl_aes_key,
01257 session.cl_iv);
01258
01259
01260
01261
01262
01263 session.cl_mac_enc = session.rsa_eng.doFinal(clientHMACKeyEncoded);
01264 session.cl_hmac_key = (SecretKey) new SecretKeySpec(session.cl_mac_enc,
01265 "AES");
01266 session.cl_mac.init(session.cl_hmac_key);
01267
01268
01269
01270
01271
01272
01273
01274
01275 KeyGenerator key_gen = KeyGenerator.getInstance("AES", "BC");
01276 key_gen.init(192, session.sec_rand);
01277 session.se_aes_key = key_gen.generateKey();
01278
01279 key_gen.init(160, session.sec_rand);
01280 session.se_hmac_key = key_gen.generateKey();
01281
01282
01283 session.se_iv = new IvParameterSpec(new byte[16]);
01284
01285 session.se_cipher.init(Cipher.ENCRYPT_MODE, session.se_aes_key,
01286 session.se_iv, session.sec_rand);
01287
01288 byte[] my_iv = session.se_cipher.getIV();
01289 session.se_iv = new IvParameterSpec(my_iv);
01290
01291 session.se_mac.init(session.se_hmac_key);
01292 clientLockData = new byte[24];
01293 session.sec_rand.nextBytes(clientLockData);
01294
01295
01296
01297
01298 sig.initSign(this.getPrivateKey());
01299 sig.update(session.cl_rand);
01300 sig.update(session.se_rand);
01301 session.rsa_eng.init(Cipher.ENCRYPT_MODE,
01302 session.distantOAPublicKey, session.sec_rand);
01303
01304
01305
01306
01307 result[0] = session.rsa_eng.doFinal(session.se_aes_key.getEncoded());
01308 sig.update(result[0]);
01309
01310
01311
01312
01313 result[1] = session.rsa_eng.doFinal(my_iv);
01314 sig.update(result[1]);
01315
01316
01317
01318
01319 result[2] = session.rsa_eng.doFinal(session.se_hmac_key.getEncoded());
01320 sig.update(result[2]);
01321
01322
01323
01324
01325 session.se_cipher.init(Cipher.ENCRYPT_MODE, session.se_aes_key,
01326 new IvParameterSpec(my_iv), session.sec_rand);
01327 result[3] = session.se_cipher.doFinal(clientLockData);
01328 sig.update(clientLockData);
01329
01330 result[4] = sig.sign();
01331
01332
01333
01334
01335
01336
01337 session.setSessionValidated(true);
01338 } catch (BadPaddingException e) {
01339 e.printStackTrace();
01340 } catch (InvalidKeyException e) {
01341 e.printStackTrace();
01342 } catch (InvalidAlgorithmParameterException e) {
01343 e.printStackTrace();
01344 } catch (SignatureException e) {
01345 e.printStackTrace();
01346 } catch (IllegalBlockSizeException e) {
01347 e.printStackTrace();
01348 } catch (NoSuchAlgorithmException e) {
01349 e.printStackTrace();
01350 } catch (NoSuchProviderException e) {
01351 e.printStackTrace();
01352 } catch (KeyExchangeException e) {
01353 e.printStackTrace();
01354 }
01355
01356 return result;
01357 }
01358
01359
01360 private void writeObject(java.io.ObjectOutputStream out)
01361 throws IOException {
01362
01363 try {
01364 if (keyStore != null) {
01365 ByteArrayOutputStream bout = new ByteArrayOutputStream();
01366 keyStore.store(bout, "ha".toCharArray());
01367
01368 encodedKeyStore = bout.toByteArray();
01369 keyStore = null;
01370 bout.close();
01371 }
01372 } catch (CertificateEncodingException e) {
01373 e.printStackTrace();
01374 } catch (KeyStoreException e) {
01375 e.printStackTrace();
01376 } catch (NoSuchAlgorithmException e) {
01377 e.printStackTrace();
01378 } catch (CertificateException e) {
01379 e.printStackTrace();
01380 } catch (IOException e) {
01381 e.printStackTrace();
01382 }
01383 out.defaultWriteObject();
01384 }
01385
01386 private void readObject(java.io.ObjectInputStream in)
01387 throws IOException, ClassNotFoundException {
01388 in.defaultReadObject();
01389 logger = ProActiveLogger.getLogger(Loggers.SECURITY);
01390
01391 randomLongGenerator = new RandomLongGenerator();
01392
01393 if (encodedKeyStore != null) {
01394 try {
01395 keyStore = KeyStore.getInstance("PKCS12", "BC");
01396 keyStore.load(new ByteArrayInputStream(encodedKeyStore),
01397 "ha".toCharArray());
01398
01399 encodedKeyStore = null;
01400 } catch (KeyStoreException e) {
01401
01402 e.printStackTrace();
01403 } catch (NoSuchProviderException e) {
01404
01405 e.printStackTrace();
01406 } catch (NoSuchAlgorithmException e) {
01407
01408 e.printStackTrace();
01409 } catch (CertificateException e) {
01410
01411 e.printStackTrace();
01412 } catch (IOException e) {
01413
01414 e.printStackTrace();
01415 }
01416 }
01417 }
01418
01419 public long getSessionIDTo(X509Certificate cert) {
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438 Session session = null;
01439 if (sessions == null) {
01440 ProActiveLogger.getLogger(Loggers.SECURITY_CRYPTO).debug("sessions field is null");
01441 return (long) 0;
01442 }
01443
01444 for (Enumeration e = sessions.elements(); e.hasMoreElements();) {
01445 session = (Session) e.nextElement();
01446
01447
01448
01449
01450
01451
01452 if (session != null) {
01453
01454 if ((cert != null) && (session.distantOACertificate != null) &&
01455 cert.equals(session.distantOACertificate)) {
01456
01457
01458
01459 return session.sessionID;
01460 }
01461 }
01462 }
01463
01464
01465
01466
01467 return (long) 0;
01468 }
01469
01474 public PublicKey getPublicKey() {
01475 return getCertificate().getPublicKey();
01476 }
01477
01478
01479
01480
01481
01482
01483
01484 public Hashtable<Long,String> getOpenedConnexion() {
01485 Hashtable<Long,String> table = null;
01486 if (sessions == null) {
01487 return table;
01488 }
01489
01490 table = new Hashtable<Long,String>();
01491
01492 for (Enumeration e = sessions.keys(); e.hasMoreElements();) {
01493 Long l = (Long) e.nextElement();
01494 table.put(l, l.toString());
01495 }
01496
01497 return table;
01498 }
01499
01504 public void setVNName(String string) {
01505
01506 this.VNName = string;
01507
01508
01509 }
01510
01514 public String getVNName() {
01515 return VNName;
01516 }
01517
01521 public PolicyServer getPolicyServer() {
01522 return policyServer;
01523 }
01524
01531 public byte[] getCertificateEncoded() {
01532 try {
01533 X509Certificate cert = this.getCertificate();
01534 if (cert != null) {
01535 return cert.getEncoded();
01536 }
01537 return null;
01538 } catch (CertificateEncodingException e) {
01539 e.printStackTrace();
01540 }
01541
01542 return null;
01543 }
01544
01549 public void setPolicyServer(PolicyServer policyServer) {
01550 this.policyServer = policyServer;
01551
01552 }
01553
01557 public ArrayList<Entity> getEntities() {
01558 Entity entity = null;
01559 ArrayList<Entity> a = new ArrayList<Entity>();
01560 switch (type) {
01561 case SecurityConstants.ENTITY_TYPE_OBJECT:
01562
01563 break;
01564 case SecurityConstants.ENTITY_TYPE_NODE:
01565 entity = new EntityVirtualNode(this.getCertificate().getSubjectDN()
01566 .toString().substring(3),
01567 policyServer.getApplicationCertificate(),
01568 this.getCertificate());
01569 default:
01570 break;
01571 }
01572
01573 if (entity != null) {
01574 a.add(entity);
01575 }
01576
01577 if (parent != null) {
01578 try {
01579 ArrayList<Entity> parentEntities = parent.getEntities();
01580 if (parentEntities == null) {
01581 return null;
01582 }
01583 int parentSize = parentEntities.size();
01584 for (int i = 0; i < parentSize; i++) {
01585 a.add(parentEntities.get(i));
01586 }
01587 } catch (SecurityNotAvailableException e) {
01588
01589 return null;
01590 } catch (IOException e) {
01591 e.printStackTrace();
01592 }
01593 }
01594
01595 return a;
01596 }
01597
01598 public Session getSession(long id) {
01599 return (Session) sessions.get(new Long(id));
01600 }
01601
01602 public X509Certificate[] getMyCertificateChain() {
01603 try {
01604 return (X509Certificate[]) policyServer.getKeyStore()
01605 .getCertificateChain(SecurityConstants.KEYSTORE_ENTITY_PATH);
01606 } catch (KeyStoreException e) {
01607 return null;
01608 }
01609 }
01610
01611 public SecurityEntity getParent() {
01612 return parent;
01613 }
01614
01615 public void setParent(SecurityEntity parent) {
01616 this.parent = parent;
01617 }
01618
01619 public ProActiveSecurityManager generateSiblingCertificate(
01620 String siblingName) {
01621 ProActiveSecurityManager siblingPSM = new ProActiveSecurityManager();
01622
01623 try {
01624 siblingPSM.setPolicyServer((PolicyServer) this.policyServer.clone());
01625 siblingPSM.generateEntityCertificate(siblingName);
01626 } catch (CloneNotSupportedException e) {
01627 e.printStackTrace();
01628 }
01629
01630 return siblingPSM;
01631 }
01632
01633 protected void generateEntityCertificate(String siblingName) {
01634 siblingName = "CN=" + siblingName;
01635 try {
01636 KeyPair siblingKeyPair = KeyTools.genKeys(1024);
01637 X509Certificate cert;
01638
01639 ProActiveLogger.getLogger(Loggers.SECURITY_MANAGER).debug("generate sibling scurity manager for " +
01640 siblingName);
01641
01642 cert = CertTools.genCert(siblingName, 65 * 24 * 360L, null,
01643 siblingKeyPair.getPrivate(), siblingKeyPair.getPublic(),
01644 true,
01645 ((X509Certificate) this.policyServer.getKeyStore()
01646 .getCertificate(SecurityConstants.KEYSTORE_APPLICATION_PATH)).getSubjectDN()
01647 .toString(),
01648 (PrivateKey) this.policyServer.getKeyStore().getKey(SecurityConstants.KEYSTORE_APPLICATION_PATH,
01649 null),
01650 this.policyServer.getKeyStore()
01651 .getCertificate(SecurityConstants.KEYSTORE_APPLICATION_PATH)
01652 .getPublicKey());
01653
01654 this.keyStore = KeyTools.createP12(SecurityConstants.KEYSTORE_ENTITY_PATH,
01655 siblingKeyPair.getPrivate(), cert,
01656 this.policyServer.getKeyStore().getCertificateChain(SecurityConstants.KEYSTORE_APPLICATION_PATH));
01657 } catch (InvalidKeyException e) {
01658 e.printStackTrace();
01659 } catch (NoSuchAlgorithmException e) {
01660 e.printStackTrace();
01661 } catch (SignatureException e) {
01662 e.printStackTrace();
01663 } catch (KeyStoreException e) {
01664 e.printStackTrace();
01665
01666
01667 } catch (Exception e) {
01668 e.printStackTrace();
01669 }
01670 }
01671
01672 public ProActiveSecurityManager getProActiveSecurityManager() {
01673 return this;
01674 }
01675 }