diff --git a/CASA/micasad/lss/CASACrypto.cs b/CASA/micasad/lss/CASACrypto.cs index 6130fc45..58629acc 100644 --- a/CASA/micasad/lss/CASACrypto.cs +++ b/CASA/micasad/lss/CASACrypto.cs @@ -38,6 +38,7 @@ namespace sscs.crypto private const int SALTSIZE = 64; private const int ITERATION_COUNT = 1000; private const int HASH_SIZE = 32; + private const uint MAX_FILE_SIZE = 16 * 1024 * 1024; //16 MB internal static byte[] Generate16ByteKeyFromString(string sTheString, string sFilepath, bool bUseOldMethod) { @@ -179,7 +180,7 @@ namespace sscs.crypto try { //Get an decryptor. - RijndaelManaged myRijndael = new RijndaelManaged(); + RijndaelManaged myRijndael = new RijndaelManaged(); ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, baIV); csDecrypt = new CryptoStream(ms, decryptor, CryptoStreamMode.Read); @@ -206,8 +207,8 @@ namespace sscs.crypto //Get an encryptor. RijndaelManaged myRijndael = new RijndaelManaged(); - // create IV - myRijndael.GenerateIV(); + // create IV + myRijndael.GenerateIV(); baIV = myRijndael.IV; ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, baIV); @@ -286,6 +287,33 @@ namespace sscs.crypto fsEncrypt.Close(); } + internal static void ComputeHashAndWriteToFile(byte[] baPasscode, string fileName) + { + + FileStream fsHash = null; + byte[] hash = null; + + try + { + SHA256 shaM = new SHA256Managed(); + hash = shaM.ComputeHash(baPasscode); + + fsHash = new FileStream(fileName, FileMode.Create); + File.SetAttributes(fileName, FileAttributes.Hidden); + + fsHash.Write(hash, 0, hash.Length); + fsHash.Flush(); + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + CSSSLogger.DbgLog("Computing hash and storing it in the file failed."); + } + + if( fsHash != null ) + fsHash.Close(); + } + internal static byte[] ReadFileAndDecryptData(byte[] key, string fileName) { @@ -326,6 +354,14 @@ namespace sscs.crypto return null; } + if(fsDecrypt.Length > MAX_FILE_SIZE ) + { + CSSSLogger.DbgLog("Size of the secret file exceeded the maximum allowed."); + csDecrypt.Close(); + fsDecrypt.Close(); + return null; + } + ulong fileLen = (ulong)(fsDecrypt.Length - HASH_SIZE); byte[] fromEncrypt = new byte[fileLen]; @@ -710,11 +746,8 @@ namespace sscs.crypto EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, fileName); - EncryptDataAndWriteToFile( - Encoding.Default.GetBytes( - ConstStrings.MICASA_VALIDATION_STRING), - baPasscode, - validationFile); + + ComputeHashAndWriteToFile(baPasscode, validationFile + "Hash"); //Hash of MPC is written to ".miCASAValidateHash" file return baPasscode; } catch(Exception e) @@ -747,10 +780,8 @@ namespace sscs.crypto fs.Flush(); fs.Close(); - EncryptDataAndWriteToFile( - Encoding.Default.GetBytes(ConstStrings.MICASA_VALIDATION_STRING), - baPasscode, - validationFile); + ComputeHashAndWriteToFile(baPasscode, validationFile + "Hash"); //Hash of MPC is written to ".miCASASrvValidateHash" file + } catch(Exception e) { @@ -761,6 +792,52 @@ namespace sscs.crypto return baPasscode; } + public static bool CompareHashes(byte[] baPasscode, string fileName) + { + FileStream fsHash = null; + try + { +#if LINUX + UnixFileInfo fsTest = new UnixFileInfo (fileName); + if((fsTest == null) || !(fsTest.Exists) || fsTest.IsSymbolicLink) +#else + if (!File.Exists(fileName)) +#endif + { + return false; + } + + fsHash = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); + byte[] storedHash = new byte[HASH_SIZE]; + fsHash.Read(storedHash,0,storedHash.Length); + + SHA256 sha = new SHA256Managed(); + byte[] newHash = sha.ComputeHash(baPasscode); + + for( int i = 0 ; i < HASH_SIZE; i++ ) + { + if(storedHash[i] != newHash[i]) + { + CSSSLogger.DbgLog("Comparision of hashes failed."); + fsHash.Close(); + return false; + } + } + + fsHash.Close(); + return true; + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + CSSSLogger.DbgLog("Comparision of hashes failed."); + } + + if (fsHash != null) + fsHash.Close(); + return false; + } + public static bool ValidatePasscode(byte[] baPasscode, string fileName) { /* Here we decrpyt a well known string, throw exception @@ -775,19 +852,28 @@ namespace sscs.crypto try { - byte[] baString = ReadFileAndDecryptData(baPasscode, fileName); - string sString = Encoding.Default.GetString(baString); - char[] trimChars = {'\0'}; - sString = sString.TrimEnd(trimChars); - if( ConstStrings.MICASA_VALIDATION_STRING.Equals(sString)) - { - CSSSLogger.DbgLog("Passed"); - return true; - } - else - { - CSSSLogger.DbgLog("Failed"); - return false; + if(CompareHashes(baPasscode, fileName + "Hash")) + { + CSSSLogger.DbgLog("Using the hash of MPC for validating the MPC"); + return true; + } + else + { + CSSSLogger.DbgLog("Using the validation string encrypted with MPC for validating the MPC"); + byte[] baString = ReadFileAndDecryptData(baPasscode, fileName); + string sString = Encoding.Default.GetString(baString); + char[] trimChars = {'\0'}; + sString = sString.TrimEnd(trimChars); + if( ConstStrings.MICASA_VALIDATION_STRING.Equals(sString)) + { + CSSSLogger.DbgLog("Passed"); + return true; + } + else + { + CSSSLogger.DbgLog("Failed"); + return false; + } } } catch(Exception e)