diff --git a/CASA/micasad/cache/SecretStore.cs b/CASA/micasad/cache/SecretStore.cs index 48e6fc25..0a63446c 100644 --- a/CASA/micasad/cache/SecretStore.cs +++ b/CASA/micasad/cache/SecretStore.cs @@ -178,13 +178,15 @@ namespace sscs.cache { byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(sDesktopPassword, GetPasscodeByDesktopFilePath(), false); if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath())) - { + { + ReEncryptPasscodeUsingRandomSalt(baPasscode, sDesktopPassword, GetPasscodeByDesktopFilePath()); return true; } // try old salt baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(sDesktopPassword, GetPasscodeByDesktopFilePath(), true); if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath())) - { + { + ReEncryptPasscodeUsingRandomSalt(baPasscode, sDesktopPassword, GetPasscodeByDesktopFilePath()); return true; } } @@ -248,7 +250,7 @@ namespace sscs.cache if (CASACrypto.ValidatePasscode(baPasscode, GetServerValidationFilePath())) { slss = new LocalStorage(this, baPasscode, true); - bIsServerStorePersistent = true; + bIsServerStorePersistent = true; return true; } } @@ -337,7 +339,8 @@ namespace sscs.cache if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath())) { lss = new LocalStorage(this, baPasscode); - bIsStorePersistent = true; + bIsStorePersistent = true; + ReEncryptPasscodeUsingRandomSalt(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath()); return true; } else @@ -346,8 +349,9 @@ namespace sscs.cache baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), true); if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath())) { - // rewrite file using new encryption - CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath()); + // rewrite file using new encryption + ReEncryptPasscodeUsingRandomSalt(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath()); + //CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, desktopPasswd, GetPasscodeByDesktopFilePath()); lss = new LocalStorage(this, baPasscode); bIsStorePersistent = true; return true; @@ -409,31 +413,29 @@ namespace sscs.cache baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(desktopPasswd, GetPasscodeByDesktopFilePath(), false); if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath())) { - CASACrypto.EncryptAndStoreMasterPasscodeUsingString( - baPasscode, - mPasswd, - GetPasscodeByMasterPasswdFilePath()); + CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath()); return true; } else { // try old method baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd( - desktopPasswd, - GetPasscodeByDesktopFilePath(), - true); + desktopPasswd, + GetPasscodeByDesktopFilePath(), + true); + if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath())) { // rewrite file using new method CASACrypto.EncryptAndStoreMasterPasscodeUsingString( - baPasscode, - desktopPasswd, - GetPasscodeByDesktopFilePath()); + baPasscode, + desktopPasswd, + GetPasscodeByDesktopFilePath()); CASACrypto.EncryptAndStoreMasterPasscodeUsingString( - baPasscode, - mPasswd, - GetPasscodeByMasterPasswdFilePath()); + baPasscode, + mPasswd, + GetPasscodeByMasterPasswdFilePath()); return true; } else @@ -517,7 +519,8 @@ namespace sscs.cache { if (bIsStorePersistent == false) { - lss = new LocalStorage(this, baPasscode); + lss = new LocalStorage(this, baPasscode); + ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath()); bIsStorePersistent = true; } return true; @@ -552,7 +555,8 @@ namespace sscs.cache RewriteDesktopPasswdFile(baPasscode, desktopPasswd); if (bIsStorePersistent == false) { - lss = new LocalStorage(this, baPasscode); + lss = new LocalStorage(this, baPasscode); + ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath()); bIsStorePersistent = true; } return true; @@ -565,7 +569,8 @@ namespace sscs.cache RewriteDesktopPasswdFile(baPasscode, desktopPasswd); if (bIsStorePersistent == false) { - lss = new LocalStorage(this, baPasscode); + lss = new LocalStorage(this, baPasscode); + ReEncryptPasscodeUsingRandomSalt(baPasscode, mPasswd, GetPasscodeByMasterPasswdFilePath()); bIsStorePersistent = true; } return true; @@ -603,7 +608,8 @@ namespace sscs.cache { byte[] baPasscode = CASACrypto.GetMasterPasscodeUsingDesktopPasswd(oldDesktopPasswd, GetPasscodeByDesktopFilePath(), false); if (CASACrypto.ValidatePasscode(baPasscode, GetValidationFilePath())) - { + { + ReEncryptPasscodeUsingRandomSalt(baPasscode, oldDesktopPasswd, GetPasscodeByDesktopFilePath()); return baPasscode; } else @@ -1071,7 +1077,7 @@ namespace sscs.cache // encrypt if an encryptionstring was passed if ((sEncryptionString != null) && (sEncryptionString.Length > 0)) { - byte[] baKey = sscs.crypto.CASACrypto.Generate16ByteKeyFromString(sEncryptionString, null, false); + byte[] baKey = sscs.crypto.CASACrypto.Generate16ByteKeyFromString(sEncryptionString, null, false, false); // now encypt it. baSecrets = sscs.crypto.CASACrypto.EncryptData(baSecrets, baKey, ref baIV); @@ -1089,7 +1095,7 @@ namespace sscs.cache if (sEncryptionString != null) { // decrypt the buffer using the string passed in. - byte[] baKey = sscs.crypto.CASACrypto.Generate16ByteKeyFromString(sEncryptionString, null, false); + byte[] baKey = sscs.crypto.CASACrypto.Generate16ByteKeyFromString(sEncryptionString, null, false, false); byte[] baBuffer = sscs.crypto.CASACrypto.DecryptData(encryptedXmlSecrets, baKey, baIV); MergeXMLSecrets(baBuffer); } @@ -1101,6 +1107,14 @@ namespace sscs.cache String sXMLData = Encoding.ASCII.GetString(decryptedXmlSecrets); doc.LoadXml(sXMLData); LocalStorage.AddXMLSecretsToStore(this, doc); + } + + private void ReEncryptPasscodeUsingRandomSalt(byte[] baPasscode, string sPassword, string sFilepath) + { + if (!File.Exists(sFilepath + ".salt")) + { + CASACrypto.EncryptAndStoreMasterPasscodeUsingString(baPasscode, sPassword, sFilepath); + } } internal void CreatePolicyDirectory() diff --git a/CASA/micasad/lss/CASACrypto.cs b/CASA/micasad/lss/CASACrypto.cs index 58629acc..a9d81877 100644 --- a/CASA/micasad/lss/CASACrypto.cs +++ b/CASA/micasad/lss/CASACrypto.cs @@ -40,12 +40,12 @@ namespace sscs.crypto 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) + internal static byte[] Generate16ByteKeyFromString(string sTheString, string sFilepath, bool bUseOldMethod, bool bGenerateRandomSalt) { byte[] baKey = new byte[16]; //return value try { - Rfc2898DeriveBytes pkcs5 = new Rfc2898DeriveBytes(sTheString, SALTSIZE, ITERATION_COUNT, bUseOldMethod); + Rfc2898DeriveBytes pkcs5 = new Rfc2898DeriveBytes(sTheString, SALTSIZE, ITERATION_COUNT, bUseOldMethod, sFilepath, bGenerateRandomSalt); baKey = pkcs5.GetBytes(16); } catch(Exception e) @@ -531,7 +531,7 @@ namespace sscs.crypto { if(File.Exists(fileName)) File.Delete(fileName); - byte[] baKey = Generate16ByteKeyFromString(passwd, null, false); + byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, false, true); //Get an encryptor. RijndaelManaged myRijndael = new RijndaelManaged(); @@ -578,7 +578,7 @@ namespace sscs.crypto try { - byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, bTryOldMethod); + byte[] baKey = Generate16ByteKeyFromString(passwd, fileName, bTryOldMethod, false); /* Get a decryptor that uses the same key and * IV as the encryptor. diff --git a/CASA/micasad/lss/Rfc2898DeriveBytes.cs b/CASA/micasad/lss/Rfc2898DeriveBytes.cs index 48cd2f41..f1c4f585 100644 --- a/CASA/micasad/lss/Rfc2898DeriveBytes.cs +++ b/CASA/micasad/lss/Rfc2898DeriveBytes.cs @@ -54,6 +54,7 @@ //using System.Runtime.InteropServices; using System; using System.Text; +using System.IO; using System.Security.Cryptography; using sscs.lss; @@ -105,11 +106,11 @@ namespace sscs.crypto { } public Rfc2898DeriveBytes(string password, int saltSize, int iterations) - : this (password, saltSize, iterations, false) + : this (password, saltSize, iterations, false, null, false) { } - public Rfc2898DeriveBytes (string password, int saltSize, int iterations, bool bUseOldMethod) + public Rfc2898DeriveBytes (string password, int saltSize, int iterations, bool bUseOldMethod, string sFilepath, bool bGenerateAndSaveRandomSalt) { if (password == null) throw new ArgumentNullException ("password"); @@ -121,14 +122,70 @@ namespace sscs.crypto { Salt = GenerateOldSalt(password, saltSize); } else - { - Salt = GenerateNewSalt(password, saltSize); + { + if (bGenerateAndSaveRandomSalt) + { + Salt = GenerateAndSaveRandomSalt(saltSize, sFilepath); + } + else + { + // load saved salt if one was saved + if ((sFilepath != null) && (File.Exists(sFilepath + ".salt"))) + { + Salt = LoadSavedSalt(sFilepath); + } + else + { + Salt = GenerateNewSalt(password, saltSize); + } + } } IterationCount = iterations; _hmac = new HMACSHA1 (Encoding.UTF8.GetBytes (password)); } + private byte[] GenerateAndSaveRandomSalt(int saltSize, string sFilepath) + { + byte[] randomSalt = new byte[saltSize]; + FastRandom fr = new FastRandom(); + fr.NextBytes(randomSalt); + + // save salt + try + { + FileStream fs = new FileStream(sFilepath + ".salt", FileMode.Create); + fs.Write(randomSalt, 0, randomSalt.Length); + fs.Flush(); + fs.Close(); + File.SetAttributes(sFilepath + ".salt", FileAttributes.Hidden); + } + catch (Exception e) + { + + } + + return randomSalt; + } + + private byte[] LoadSavedSalt(string sFilePath) + { + byte[] baSalt = null; + + try + { + FileStream fs = new FileStream(sFilePath + ".salt", FileMode.Open); + baSalt = new byte[fs.Length]; + fs.Read(baSalt, 0, (int)fs.Length); + fs.Close(); + } + catch (Exception e) + { + + } + return baSalt; + } + private static byte[] GenerateOldSalt(string password, int saltSize) { byte[] buffer = new byte[saltSize];