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 }