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.crypto;
00032
00033 import java.io.IOException;
00034 import java.io.Serializable;
00035 import java.security.AlgorithmParameters;
00036 import java.security.PublicKey;
00037 import java.security.SecureRandom;
00038 import java.security.cert.CertificateEncodingException;
00039 import java.security.cert.X509Certificate;
00040
00041 import javax.crypto.Cipher;
00042 import javax.crypto.Mac;
00043 import javax.crypto.SecretKey;
00044 import javax.crypto.spec.IvParameterSpec;
00045
00046 import org.objectweb.proactive.core.util.log.Loggers;
00047 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00048 import org.objectweb.proactive.ext.security.Communication;
00049 import org.objectweb.proactive.ext.security.PolicyRule;
00050 import org.objectweb.proactive.ext.security.ProActiveSecurity;
00051 import org.objectweb.proactive.ext.security.SecurityContext;
00052
00053
00054 public class Session implements Serializable {
00055
00056 public long sessionID;
00057 protected static Object synchronizationObject = new Object();
00058
00059
00060 public X509Certificate distantOACertificate;
00061
00062
00063 public PublicKey distantOAPublicKey;
00064
00065
00066 public transient Cipher cl_cipher;
00067
00068
00069 public transient Cipher se_cipher;
00070
00071
00072 private Communication communication;
00073
00074
00075 public transient Cipher rsa_eng;
00076
00077
00078 public transient Mac cl_mac;
00079
00080
00081 public transient Mac se_mac;
00082 public byte[] cl_sec_key;
00083 public byte[] se_sec_key;
00084 public byte[] cl_mac_enc;
00085 public byte[] se_mac_enc;
00086 public transient IvParameterSpec se_iv;
00087 public transient IvParameterSpec cl_iv;
00088
00089
00090
00091
00092 protected boolean isSessionValidated;
00093 public AlgorithmParameters seCipherAlgParams;
00094 public AlgorithmParameters clCipherAlgParams;
00095 public AlgorithmParameters seMacAlgParams;
00096 public AlgorithmParameters clMacAlgParams;
00097 public byte[] encodedSeCipherAlgParams;
00098 public byte[] encodedClCipherAlgParams;
00099 public byte[] encodedSeMacAlgParams;
00100 public byte[] encodedClMacAlgParams;
00101
00102
00103 public byte[] se_rand;
00104
00105
00106 public byte[] cl_rand;
00107 public SecretKey se_hmac_key;
00108 public SecretKey se_aes_key;
00109 public SecretKey cl_hmac_key;
00110 public SecretKey cl_aes_key;
00111
00112
00113
00114 public transient SecureRandom sec_rand;
00115
00116
00117 public SecurityContext securityContext;
00118 public static int ACT_AS_CLIENT = 1;
00119 public static int ACT_AS_SERVER = 2;
00120
00121 public Session() {
00122 }
00123
00124 public Session(long sessionID, Communication policy)
00125 throws Exception {
00126 this.communication = policy;
00127 isSessionValidated = false;
00128
00129 se_rand = new byte[32];
00130 cl_rand = new byte[32];
00131 sec_rand = new SecureRandom();
00132 cl_cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
00133 se_cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
00134 rsa_eng = Cipher.getInstance("RSA/None/OAEPPadding", "BC");
00135 cl_mac = Mac.getInstance("HMACSHA1", "BC");
00136 se_mac = Mac.getInstance("HMACSHA1", "BC");
00137
00138 this.sessionID = sessionID;
00139 distantOACertificate = null;
00140 distantOAPublicKey = null;
00141 }
00142
00143 public boolean isID(long ID) {
00144 if (ID == this.sessionID) {
00145 return true;
00146 }
00147
00148 return false;
00149 }
00150
00151 public X509Certificate get_otherPublicCertificate(long id) {
00152 if (this.sessionID == id) {
00153 return distantOACertificate;
00154 }
00155
00156 return null;
00157 }
00158
00159 public long getSessionID() {
00160 return sessionID;
00161 }
00162
00163 public void setDistantOACertificate(X509Certificate distantBodyCertificate) {
00164 distantOACertificate = distantBodyCertificate;
00165 }
00166
00167 public X509Certificate getDistantOACertificate() {
00168 return distantOACertificate;
00169 }
00170
00171 public PublicKey getDistantOAPublicKey() {
00172 return distantOAPublicKey;
00173 }
00174
00175 public void setDistantOAPublicKey(PublicKey distantOAPublicKey) {
00176 this.distantOAPublicKey = distantOAPublicKey;
00177 }
00178
00179 public synchronized byte[][] writePDU(byte[] in, int type)
00180 throws Exception {
00181 byte[] mac = null;
00182 switch (type) {
00183 case 1:
00184
00185 if (communication.isIntegrityEnabled()) {
00186 cl_mac.update(in);
00187 }
00188 if (communication.isConfidentialityEnabled()) {
00189 try {
00190 cl_cipher.init(Cipher.ENCRYPT_MODE, cl_aes_key, cl_iv,
00191 sec_rand);
00192
00193
00194
00195 in = cl_cipher.doFinal(in);
00196 } catch (Exception bex) {
00197 bex.printStackTrace();
00198 throw (new IOException("PDU failed to encrypt " +
00199 bex.getMessage()));
00200 }
00201 }
00202
00203 if (communication.isIntegrityEnabled()) {
00204 ProActiveLogger.getLogger(Loggers.SECURITY_SESSION).debug("writePDU as client cl_mac :" +
00205 displayByte(cl_hmac_key.getEncoded()));
00206 mac = cl_mac.doFinal();
00207 }
00208 break;
00209 case 2:
00210
00211 if (communication.isIntegrityEnabled()) {
00212 se_mac.update(in);
00213 }
00214 if (communication.isConfidentialityEnabled()) {
00215 try {
00216 in = se_cipher.doFinal(in);
00217 } catch (Exception bex) {
00218 bex.printStackTrace();
00219 throw (new IOException("PDU failed to encrypt " +
00220 bex.getMessage()));
00221 }
00222 }
00223
00224 if (communication.isIntegrityEnabled()) {
00225 mac = se_mac.doFinal();
00226 }
00227 break;
00228 default:
00229 break;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239 return new byte[][] { in, mac };
00240 }
00241
00242 public static boolean isEqual(byte[] a, byte[] b) {
00243 if ((a == null) || (b == null)) {
00244 return (false);
00245 }
00246
00247 if (a.length != b.length) {
00248 return (false);
00249 }
00250
00251 for (int t = 0; t < a.length; t++) {
00252 if (a[t] != b[t]) {
00253 return (false);
00254 }
00255 }
00256
00257 return (true);
00258 }
00259
00260 public synchronized byte[] readPDU(byte[] in, byte[] mac, int type)
00261 throws IOException {
00262
00263
00264 switch (type) {
00265 case 1:
00266
00267 if (communication.isConfidentialityEnabled()) {
00268 try {
00269 in = se_cipher.doFinal(in);
00270 } catch (Exception ex) {
00271 ProActiveLogger.getLogger(Loggers.SECURITY_SESSION).debug("PDU Cipher code decryption failed, session " +
00272 sessionID);
00273 throw new IOException("PDU failed to decrypt " +
00274 ex.getMessage());
00275 }
00276 }
00277 if (communication.isIntegrityEnabled()) {
00278 se_mac.update(in);
00279
00280 byte[] m = null;
00281 m = se_mac.doFinal();
00282
00283 if (!isEqual(m, mac)) {
00284 ProActiveLogger.getLogger(Loggers.SECURITY_SESSION).debug("PDU Mac code failed , session " +
00285 sessionID);
00286 throw new IOException("PDU Mac code failed ");
00287 }
00288 }
00289 break;
00290 case 2:
00291
00292 if (communication.isConfidentialityEnabled()) {
00293 try {
00294 in = cl_cipher.doFinal(in);
00295 } catch (Exception ex) {
00296 ProActiveLogger.getLogger(Loggers.SECURITY_SESSION).debug("PDU Cipher code decryption failed, session " +
00297 sessionID);
00298 throw new IOException("PDU failed to decrypt " +
00299 ex.getMessage());
00300 }
00301 }
00302 if (communication.isIntegrityEnabled()) {
00303 cl_mac.update(in);
00304
00305 byte[] m = null;
00306 m = cl_mac.doFinal();
00307
00308 ProActiveLogger.getLogger(Loggers.SECURITY_SESSION).debug("readPDU as server cl_mac :" +
00309 displayByte(cl_hmac_key.getEncoded()));
00310 if (!isEqual(m, mac)) {
00311 throw new IOException("PDU Mac code failed, session " +
00312 sessionID);
00313 }
00314 }
00315 break;
00316 default:
00317 break;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327 return (in);
00328 }
00329
00330
00331 private void writeObject(java.io.ObjectOutputStream out)
00332 throws IOException {
00333 out.defaultWriteObject();
00334 if (se_iv != null) {
00335 out.write(se_iv.getIV());
00336 } else {
00337 out.write(new byte[16]);
00338 }
00339 if (cl_iv != null) {
00340 out.write(cl_iv.getIV());
00341 } else {
00342 out.write(new byte[16]);
00343 }
00344
00345 byte[] cert = new byte[0];
00346 try {
00347 if (distantOACertificate != null) {
00348 cert = distantOACertificate.getEncoded();
00349 }
00350 } catch (CertificateEncodingException e) {
00351 e.printStackTrace();
00352 }
00353 out.writeInt(cert.length);
00354 out.write(cert);
00355 }
00356
00357 private void readObject(java.io.ObjectInputStream in)
00358 throws IOException, ClassNotFoundException {
00359 in.defaultReadObject();
00360
00361
00362 byte[] temp = new byte[16];
00363 in.read(temp);
00364
00365 se_iv = new IvParameterSpec(temp);
00366
00367 in.read(temp);
00368 cl_iv = new IvParameterSpec(temp);
00369 sec_rand = new SecureRandom();
00370
00371 ProActiveSecurity.loadProvider();
00372
00373 int i = in.readInt();
00374 byte[] certEncoded = new byte[i];
00375 in.read(certEncoded);
00376
00377 distantOACertificate = ProActiveSecurity.decodeCertificate(certEncoded);
00378
00379 try {
00380 cl_cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
00381 se_cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
00382 rsa_eng = Cipher.getInstance("RSA/None/OAEPPadding", "BC");
00383 sec_rand = new SecureRandom();
00384 cl_mac = Mac.getInstance("HMACSHA1", "BC");
00385 se_mac = Mac.getInstance("HMACSHA1", "BC");
00386
00387 if ((se_iv != null) && (se_aes_key != null)) {
00388 se_cipher.init(Cipher.DECRYPT_MODE, (SecretKey) se_aes_key,
00389 se_iv);
00390 }
00391
00392 if ((cl_iv != null) && (cl_aes_key != null)) {
00393 cl_cipher.init(Cipher.ENCRYPT_MODE, cl_aes_key, cl_iv, sec_rand);
00394 }
00395
00396 if ((se_mac != null) && (se_hmac_key != null)) {
00397 se_mac.init(se_hmac_key);
00398 }
00399 if ((cl_mac != null) && (cl_hmac_key != null)) {
00400 System.out.println("readObject session cl_mac : " +
00401 displayByte(cl_hmac_key.getEncoded()));
00402 cl_mac.init(cl_hmac_key);
00403 }
00404 } catch (Exception e) {
00405 e.printStackTrace();
00406 }
00407
00408
00409 }
00410
00411 public static String displayByte(byte[] in) {
00412 byte ch = 0x00;
00413
00414 int i = 0;
00415
00416 if ((in == null) || (in.length <= 0)) {
00417 return null;
00418 }
00419
00420 String[] pseudo = {
00421 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C",
00422 "D", "E", "F"
00423 };
00424
00425 StringBuffer out = new StringBuffer(in.length * 2);
00426
00427 while (i < in.length) {
00428 ch = (byte) (in[i] & 0xF0);
00429
00430 ch = (byte) (ch >>> 4);
00431
00432 ch = (byte) (ch & 0x0F);
00433
00434 out.append(pseudo[(int) ch]);
00435
00436 ch = (byte) (in[i] & 0x0F);
00437
00438 out.append(pseudo[(int) ch]);
00439
00440 i++;
00441 }
00442
00443 String rslt = new String(out);
00444
00445 return rslt;
00446 }
00447
00448 public String toString() {
00449 return "ID : " + sessionID + "\n" + "cl_rand : " +
00450 displayByte(cl_rand) + "\n" + "se_rand : " + displayByte(se_rand);
00451 }
00452
00457 public void setPolicy(PolicyRule resultPolicy) {
00458 }
00459
00460 public Communication getCommunication() {
00461 return communication;
00462 }
00463
00467 public SecurityContext getSecurityContext() {
00468 return securityContext;
00469 }
00470
00474 public void setSecurityContext(SecurityContext securityContext) {
00475 this.securityContext = securityContext;
00476 }
00477
00478 public boolean isSessionValidated() {
00479 return isSessionValidated;
00480 }
00481
00482 public void setSessionValidated(boolean isSessionValidated) {
00483 this.isSessionValidated = isSessionValidated;
00484
00485 }
00486 }