From a9e5a67876d2807b485909088056096f7d8e5c5b Mon Sep 17 00:00:00 2001 From: "Cameron (Kamran) Mashayekhi" Date: Tue, 25 Oct 2005 16:06:04 +0000 Subject: [PATCH] Modifications of Poorna to fix SetMasterPassword() defect. --- c_micasad/lss/CASACrypto.cs | 1029 ++++++++++++++++++----------------- 1 file changed, 534 insertions(+), 495 deletions(-) diff --git a/c_micasad/lss/CASACrypto.cs b/c_micasad/lss/CASACrypto.cs index cc666875..d283ea24 100644 --- a/c_micasad/lss/CASACrypto.cs +++ b/c_micasad/lss/CASACrypto.cs @@ -7,502 +7,541 @@ using sscs.constants; namespace sscs.crypto { - public class CASACrypto - { + public class CASACrypto + { - private const int SALTSIZE = 64; - private const int ITERATION_COUNT = 1000; + private const int SALTSIZE = 64; + private const int ITERATION_COUNT = 1000; - internal static byte[] Generate16ByteKeyFromString(string sTheString) - { - byte[] baKey = new byte[16]; //return value - try - { - Rfc2898DeriveBytes pkcs5 = new Rfc2898DeriveBytes(sTheString, SALTSIZE, ITERATION_COUNT); - baKey = pkcs5.GetBytes(16); - } - catch(Exception e) - { - CSSSLogger.ExpLog(e.ToString()); - CSSSLogger.DbgLog("Key generation failed"); - baKey = null; - } - return baKey; - } - - internal static bool StoreKeySetUsingMasterPasscode(byte[] key, - byte[] IV, byte[] baMasterPasscode, string fileName) - { - bool bRet = false; - try - { - - //Get an encryptor. - RijndaelManaged myRijndael = new RijndaelManaged(); - ICryptoTransform encryptor; - encryptor = myRijndael.CreateEncryptor(baMasterPasscode, baMasterPasscode); - - //Encrypt the data to a file - FileStream fsEncrypt = new FileStream(fileName, FileMode.Create); -#if LINUX - Mono.Unix.Syscall.chmod(fileName,Mono.Unix.FilePermissions.S_IRUSR | Mono.Unix.FilePermissions.S_IWUSR); -#endif - - SHA256 sha = new SHA256Managed(); - byte[] hash = sha.ComputeHash(key); - - fsEncrypt.Write(hash,0,hash.Length); - fsEncrypt.Flush(); - - CryptoStream csEncrypt = new CryptoStream(fsEncrypt, encryptor, CryptoStreamMode.Write); - - //Write all data to the crypto stream and flush it. - csEncrypt.Write(key, 0, key.Length); - csEncrypt.FlushFinalBlock(); - fsEncrypt.Close(); - bRet = true; - } - catch(Exception e) - { - CSSSLogger.ExpLog(e.ToString()); - CSSSLogger.DbgLog("Unable to store the generated key"); - bRet = false; - } - return bRet; - } - - internal static byte[] GetKeySetFromFile(byte[] baMasterPasscode, - string fileName ) - { - byte[] baSavedKey = null; - try - { - if(!File.Exists(fileName)) - { - return null; - } - - /* Get a decryptor that uses the same key and IV - * as the encryptor. - */ - - RijndaelManaged myRijndael = new RijndaelManaged(); - ICryptoTransform decryptor = myRijndael.CreateDecryptor(baMasterPasscode, baMasterPasscode); - //Now decrypt - FileStream fsDecrypt = new FileStream(fileName, FileMode.Open); - - byte[] storedHash = new byte[32]; - fsDecrypt.Read(storedHash,0,storedHash.Length); - - CryptoStream csDecrypt = new CryptoStream(fsDecrypt, decryptor, CryptoStreamMode.Read); - baSavedKey = new byte[32]; - - //Read the data out of the crypto stream. - csDecrypt.Read(baSavedKey, 0, baSavedKey.Length); - fsDecrypt.Close(); - - SHA256 sha = new SHA256Managed(); - byte[] newHash = sha.ComputeHash(baSavedKey); - for( int i = 0 ; i < 32; i++ ) - { - if(storedHash[i] != newHash[i]) - { - CSSSLogger.DbgLog("Hash doesnot match"); - return null; - } - } - - return baSavedKey; - } - catch(Exception e) - { - CSSSLogger.ExpLog(e.ToString()); - CSSSLogger.DbgLog("Unable to get the stored key"); - baSavedKey = null; - } - return baSavedKey; - } - - internal static void EncryptDataAndWriteToFile(byte[] xmlData, - byte[] key, string fileName) - { - try - { - byte[] IV = new byte[16]; - for(int z = 0 ; z < 16; z++ ) - IV[z] = key[z]; - - //Get an encryptor. - RijndaelManaged myRijndael = new RijndaelManaged(); - ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, IV); - - //Encrypt the data to a file - FileStream fsEncrypt = new FileStream(fileName, FileMode.Create); -#if LINUX - Mono.Unix.Syscall.chmod(fileName,Mono.Unix.FilePermissions.S_IRUSR | Mono.Unix.FilePermissions.S_IWUSR); -#endif - SHA256 sha = new SHA256Managed(); - - byte[] hash = sha.ComputeHash(xmlData); - - fsEncrypt.Write(hash,0,hash.Length); - fsEncrypt.Flush(); - - CryptoStream csEncrypt = new CryptoStream(fsEncrypt, encryptor, CryptoStreamMode.Write); - - //Write all data to the crypto stream and flush it. - csEncrypt.Write(xmlData, 0, xmlData.Length); - csEncrypt.FlushFinalBlock(); - fsEncrypt.Close(); - } - catch(Exception e) - { - CSSSLogger.ExpLog(e.ToString()); - CSSSLogger.DbgLog("Encrypting and storing to file failed."); - } - } - - internal static byte[] ReadFileAndDecryptData(byte[] key, - string fileName) - { - FileStream fsDecrypt = null; - try - { - byte[] IV = new byte[16]; - for(int z = 0 ; z < 16; z++ ) - IV[z] = key[z]; - - //Get a decryptor that uses the same key and IV as the encryptor. - RijndaelManaged myRijndael = new RijndaelManaged(); - ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, IV); - - if(!File.Exists(fileName)) - { - return null; - } - - //Now decrypt - fsDecrypt = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); - byte[] storedHash = new byte[32]; - fsDecrypt.Read(storedHash,0,storedHash.Length); - - CryptoStream csDecrypt = new CryptoStream(fsDecrypt, decryptor, CryptoStreamMode.Read); - long fileLen = fsDecrypt.Length - 32; - byte[] fromEncrypt = new byte[fileLen]; - - //Read the data out of the crypto stream. - int bytesRead = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length); - byte[] tmpEncrypt = new byte[bytesRead]; - for(int i = 0 ; i < bytesRead; i++ ) - tmpEncrypt[i] = fromEncrypt[i]; - - SHA256 sha = new SHA256Managed(); - byte[] newHash = sha.ComputeHash(tmpEncrypt); - - for( int i = 0 ; i < 32; i++ ) - { - if(storedHash[i] != newHash[i]) - { - CSSSLogger.DbgLog("Hash doesnot match"); - return null; - } - } - - fsDecrypt.Close(); - return tmpEncrypt; - } - catch(Exception e) - { - Console.WriteLine(e.ToString()); - } - if(fsDecrypt != null) - { - fsDecrypt.Close(); - } - return null; - - } - - /* The methods EncryptData() and DecryptData() would be - * required when we use a database to store secrets. - */ - - /* Encrypts the data with the key and returns the encrypted buffer. - */ - - internal static byte[] EncryptData(byte[] data, byte[] key) - { - - try - { - byte[] IV = new byte[16]; - int i = 0; - for(i = 0 ; i < 16; i++ ) - IV[i] = key[i]; - - //Get an encryptor. - RijndaelManaged myRijndael = new RijndaelManaged(); - ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, IV); - MemoryStream ms1 = new MemoryStream(); - CryptoStream csEncrypt = new CryptoStream(ms1, encryptor, CryptoStreamMode.Write); - - //Write all data to the crypto stream and flush it. - csEncrypt.Write(data, 0, data.Length); - csEncrypt.FlushFinalBlock(); - return ms1.ToArray(); - } - catch(Exception e) - { - CSSSLogger.ExpLog(e.ToString()); - } - return null; - } - - /* Decrypts the buffer(encrypted) with the key and returns the - * decrypted data. - */ - - internal static byte[] DecryptData(byte[] buffer, byte[] key) - { - try - { - byte[] IV = new byte[16]; - for(int i = 0 ; i < 16; i++ ) - IV[i] = key[i]; - //Get a decryptor that uses the same key and IV as the encryptor. - RijndaelManaged myRijndael = new RijndaelManaged(); - ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, IV); - MemoryStream ms1 = new MemoryStream(buffer); - CryptoStream csDecrypt = new CryptoStream(ms1, decryptor, CryptoStreamMode.Read); - byte[] fromEncrypt = new byte[buffer.Length]; - //Read the data out of the crypto stream. - csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length); - return fromEncrypt; - } - catch(Exception e) - { - CSSSLogger.ExpLog(e.ToString()); - } - return null; - } - - /* This method checks if we can get the master passcode by - * decrypting the passwds file ( where we store all possible - * passwds cross-encrypted. - * - * TBD : As we are storing master passcode and the keys in 2 - * different files, we need to take care of cases when 1 of the files - * is deleted. - */ - - internal static bool CheckIfMasterPasscodeIsAvailable(string desktopPasswd, string fileName) - { - return (File.Exists(fileName)); - } - - internal static byte[] GetMasterPasscode(string desktopPasswd, string fileName) - { - byte[] mp = DecryptMasterPasscodeUsingString(desktopPasswd, fileName); - return mp; - } - - /* TBD - There must be a way, where we establish the integrity of - * the files where we store the keys and master passcode. - * Use a marker ? - */ - - // Used to save the MasterPasscode encrypted with Desktop login, etc - internal static void EncryptAndStoreMasterPasscodeUsingString( - byte[] baMasterPasscode, - string passwd, - string fileName) - { - try - { - if(File.Exists(fileName)) - File.Delete(fileName); - byte[] baKey = Generate16ByteKeyFromString(passwd); - - - //Get an encryptor. - RijndaelManaged myRijndael = new RijndaelManaged(); - ICryptoTransform encryptor; - encryptor = myRijndael.CreateEncryptor(baKey, baKey); - - //Encrypt the data to a file - FileStream fsEncrypt = new FileStream(fileName,FileMode.Create); -#if LINUX - Mono.Unix.Syscall.chmod(fileName,Mono.Unix.FilePermissions.S_IRUSR | Mono.Unix.FilePermissions.S_IWUSR); -#endif - CryptoStream csEncrypt = new CryptoStream(fsEncrypt, encryptor, - CryptoStreamMode.Write); - - //Write all data to the crypto stream and flush it. - - csEncrypt.Write(baMasterPasscode, 0, baMasterPasscode.Length); - csEncrypt.FlushFinalBlock(); - fsEncrypt.Close(); - } - catch(Exception e) - { - CSSSLogger.ExpLog(e.ToString()); - } - } - public static byte[] DecryptMasterPasscodeUsingString(string passwd, - string fileName) - { - try - { - byte[] baKey = Generate16ByteKeyFromString(passwd); - - /* Get a decryptor that uses the same key and - * IV as the encryptor. - */ - RijndaelManaged myRijndael = new RijndaelManaged(); - ICryptoTransform decryptor = myRijndael.CreateDecryptor(baKey, - baKey); - //Now decrypt - FileStream fsDecrypt = new FileStream(fileName, FileMode.Open); - CryptoStream csDecrypt = new CryptoStream(fsDecrypt, decryptor, - CryptoStreamMode.Read); - byte[] baSavedMasterPasscode = new byte[16]; - - //Read the data out of the crypto stream. - csDecrypt.Read(baSavedMasterPasscode, 0, 16); - fsDecrypt.Close(); - - return baSavedMasterPasscode; - } - catch(Exception e) - { - CSSSLogger.ExpLog(e.ToString()); - CSSSLogger.DbgLog("Unable to decrypt master passode"); - } - return null; - } - - internal static byte[] GetMasterPasscodeUsingMasterPasswd( - string mPasswd, - string fileName) - { - byte[] baMasterPasscode; - try - { - if(File.Exists(fileName)) - { - /* Decrypt the passcode from the file using master passwd. - * and return the decrypted passcode. - */ - baMasterPasscode = DecryptMasterPasscodeUsingString(mPasswd, - fileName); - return baMasterPasscode; - } - else - return null; - } - catch(Exception e) - { - CSSSLogger.ExpLog(e.ToString()); - CSSSLogger.DbgLog("Failed to get master passcode from master password."); - } - return null; - } - - internal static byte[] GetMasterPasscodeUsingDesktopPasswd( - string desktopPasswd, - string fileName) - { - byte[] passcode; - try - { - if(File.Exists(fileName)) - { - /* Decrypt the passcode from the file using desktop passwd. - * and return the decrypted passcode. - */ - passcode = DecryptMasterPasscodeUsingString(desktopPasswd, - fileName); - return passcode; - - } - else - return null; - } - catch(Exception e) - { - CSSSLogger.ExpLog(e.ToString()); - CSSSLogger.DbgLog("Failed to get master passcode using desktop passwd"); - } - return null; - } - //internal static string GenerateMasterPasscodeUsingDesktopPasswd( - internal static byte[] GenerateMasterPasscodeUsingString( - string desktopPasswd, - string fileName, - string validationFile, - UserIdentifier userId - ) - { - try - { - byte[] baPasscode; - // use AES to generate a random 16 byte key; - RijndaelManaged myRijndael = new RijndaelManaged(); - myRijndael.KeySize = 128; - //Create a new key and initialization vector. - myRijndael.GenerateKey(); - baPasscode = myRijndael.Key; - - EncryptAndStoreMasterPasscodeUsingString(baPasscode, - desktopPasswd, - fileName); - EncryptDataAndWriteToFile( - Encoding.Default.GetBytes( - ConstStrings.MICASA_VALIDATION_STRING), - baPasscode, - validationFile); - return baPasscode; - } - catch(Exception e) - { - CSSSLogger.ExpLog(e.ToString()); - CSSSLogger.DbgLog("Generation of master passcode failed."); - } - return null; - } - - public static bool ValidatePasscode(byte[] baPasscode, string fileName) - { - /* Here we decrpyt a well known string, throw exception - * if not successful - * A well-known string is encrpyted by the Passcode and saved - */ - - if ((baPasscode == null) || baPasscode.Length < 1 ) - return false; - - 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)) - { - return true; - } - else - { - return false; - } - } - catch(Exception e) - { - CSSSLogger.ExpLog(e.ToString()); - CSSSLogger.DbgLog("Validation of passcode failed."); - } - return false; - } + internal static byte[] Generate16ByteKeyFromString(string sTheString) + { + byte[] baKey = new byte[16]; //return value + try + { + Rfc2898DeriveBytes pkcs5 = new Rfc2898DeriveBytes(sTheString, SALTSIZE, ITERATION_COUNT); + baKey = pkcs5.GetBytes(16); + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + CSSSLogger.DbgLog("Key generation failed"); + baKey = null; + } + return baKey; + } - } + internal static bool StoreKeySetUsingMasterPasscode(byte[] key, + byte[] IV, byte[] baMasterPasscode, string fileName) + { + bool bRet = false; + FileStream fsEncrypt = null; + CryptoStream csEncrypt = null; + try + { + + //Get an encryptor. + RijndaelManaged myRijndael = new RijndaelManaged(); + ICryptoTransform encryptor; + encryptor = myRijndael.CreateEncryptor(baMasterPasscode, baMasterPasscode); + + //Encrypt the data to a file + fsEncrypt = new FileStream(fileName, FileMode.Create); +#if LINUX + Mono.Unix.Syscall.chmod(fileName,Mono.Unix.FilePermissions.S_IRUSR | Mono.Unix.FilePermissions.S_IWUSR); +#endif + + SHA256 sha = new SHA256Managed(); + byte[] hash = sha.ComputeHash(key); + + fsEncrypt.Write(hash,0,hash.Length); + fsEncrypt.Flush(); + + csEncrypt = new CryptoStream(fsEncrypt, encryptor, CryptoStreamMode.Write); + + //Write all data to the crypto stream and flush it. + csEncrypt.Write(key, 0, key.Length); + csEncrypt.FlushFinalBlock(); + bRet = true; + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + CSSSLogger.DbgLog("Unable to store the generated key"); + bRet = false; + } + if( fsEncrypt != null ) + fsEncrypt.Close(); + if( csEncrypt != null ) + csEncrypt.Close(); + return bRet; + } + + internal static byte[] GetKeySetFromFile(byte[] baMasterPasscode, + string fileName ) + { + byte[] baSavedKey = null; + FileStream fsDecrypt = null; + CryptoStream csDecrypt = null; + try + { + if(!File.Exists(fileName)) + { + return null; + } + + /* Get a decryptor that uses the same key and IV + * as the encryptor. + */ + + RijndaelManaged myRijndael = new RijndaelManaged(); + ICryptoTransform decryptor = myRijndael.CreateDecryptor(baMasterPasscode, baMasterPasscode); + //Now decrypt + fsDecrypt = new FileStream(fileName, FileMode.Open); + + byte[] storedHash = new byte[32]; + fsDecrypt.Read(storedHash,0,storedHash.Length); + + csDecrypt = new CryptoStream(fsDecrypt, decryptor, CryptoStreamMode.Read); + baSavedKey = new byte[32]; + + //Read the data out of the crypto stream. + csDecrypt.Read(baSavedKey, 0, baSavedKey.Length); + + SHA256 sha = new SHA256Managed(); + byte[] newHash = sha.ComputeHash(baSavedKey); + for( int i = 0 ; i < 32; i++ ) + { + if(storedHash[i] != newHash[i]) + { + CSSSLogger.DbgLog("Hash doesnot match"); + fsDecrypt.Close(); + csDecrypt.Close(); + return null; + } + } + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + CSSSLogger.DbgLog("Unable to get the stored key"); + baSavedKey = null; + } + if ( fsDecrypt != null ) + fsDecrypt.Close(); + + if( csDecrypt != null ) + csDecrypt.Close(); + return baSavedKey; + } + + internal static void EncryptDataAndWriteToFile(byte[] xmlData, + byte[] key, string fileName) + { + FileStream fsEncrypt = null; + CryptoStream csEncrypt = null; + try + { + byte[] IV = new byte[16]; + for(int z = 0 ; z < 16; z++ ) + IV[z] = key[z]; + + //Get an encryptor. + RijndaelManaged myRijndael = new RijndaelManaged(); + ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, IV); + + //Encrypt the data to a file + fsEncrypt = new FileStream(fileName, FileMode.Create); +#if LINUX + Mono.Unix.Syscall.chmod(fileName,Mono.Unix.FilePermissions.S_IRUSR | Mono.Unix.FilePermissions.S_IWUSR); +#endif + SHA256 sha = new SHA256Managed(); + + byte[] hash = sha.ComputeHash(xmlData); + + fsEncrypt.Write(hash,0,hash.Length); + fsEncrypt.Flush(); + + csEncrypt = new CryptoStream(fsEncrypt, encryptor, CryptoStreamMode.Write); + + //Write all data to the crypto stream and flush it. + csEncrypt.Write(xmlData, 0, xmlData.Length); + csEncrypt.FlushFinalBlock(); + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + CSSSLogger.DbgLog("Encrypting and storing to file failed."); + } + if( fsEncrypt != null ) + fsEncrypt.Close(); + if( csEncrypt != null ) + csEncrypt.Close(); + } + + internal static byte[] ReadFileAndDecryptData(byte[] key, + string fileName) + { + FileStream fsDecrypt = null; + CryptoStream csDecrypt = null; + try + { + byte[] IV = new byte[16]; + for(int z = 0 ; z < 16; z++ ) + IV[z] = key[z]; + + //Get a decryptor that uses the same key and IV as the encryptor. + RijndaelManaged myRijndael = new RijndaelManaged(); + ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, IV); + if(!File.Exists(fileName)) + { + return null; + } + + //Now decrypt + fsDecrypt = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); + byte[] storedHash = new byte[32]; + fsDecrypt.Read(storedHash,0,storedHash.Length); + + csDecrypt = new CryptoStream(fsDecrypt, decryptor, CryptoStreamMode.Read); + long fileLen = fsDecrypt.Length - 32; + byte[] fromEncrypt = new byte[fileLen]; + + //Read the data out of the crypto stream. + int bytesRead = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length); + byte[] tmpEncrypt = new byte[bytesRead]; + for(int i = 0 ; i < bytesRead; i++ ) + tmpEncrypt[i] = fromEncrypt[i]; + + SHA256 sha = new SHA256Managed(); + byte[] newHash = sha.ComputeHash(tmpEncrypt); + + for( int i = 0 ; i < 32; i++ ) + { + if(storedHash[i] != newHash[i]) + { + CSSSLogger.DbgLog("Hash doesnot match"); + fsDecrypt.Close(); + csDecrypt.Close(); + return null; + } + } + + fsDecrypt.Close(); + csDecrypt.Close(); + return tmpEncrypt; + } + catch(Exception e) + { + Console.WriteLine(e.ToString()); + } + if( fsDecrypt != null ) + { + fsDecrypt.Close(); + } + if( csDecrypt != null ) + { + csDecrypt.Close(); + } + return null; + } + + /* The methods EncryptData() and DecryptData() would be + * required when we use a database to store secrets. + */ + + /* Encrypts the data with the key and returns the encrypted buffer. + */ + + internal static byte[] EncryptData(byte[] data, byte[] key) + { + + try + { + byte[] IV = new byte[16]; + int i = 0; + for(i = 0 ; i < 16; i++ ) + IV[i] = key[i]; + + //Get an encryptor. + RijndaelManaged myRijndael = new RijndaelManaged(); + ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, IV); + MemoryStream ms1 = new MemoryStream(); + CryptoStream csEncrypt = new CryptoStream(ms1, encryptor, CryptoStreamMode.Write); + + //Write all data to the crypto stream and flush it. + csEncrypt.Write(data, 0, data.Length); + csEncrypt.FlushFinalBlock(); + return ms1.ToArray(); + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + } + return null; + } + + /* Decrypts the buffer(encrypted) with the key and returns the + * decrypted data. + */ + + internal static byte[] DecryptData(byte[] buffer, byte[] key) + { + try + { + byte[] IV = new byte[16]; + for(int i = 0 ; i < 16; i++ ) + IV[i] = key[i]; + //Get a decryptor that uses the same key and IV as the encryptor. + RijndaelManaged myRijndael = new RijndaelManaged(); + ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, IV); + MemoryStream ms1 = new MemoryStream(buffer); + CryptoStream csDecrypt = new CryptoStream(ms1, decryptor, CryptoStreamMode.Read); + byte[] fromEncrypt = new byte[buffer.Length]; + //Read the data out of the crypto stream. + csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length); + return fromEncrypt; + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + } + return null; + } + + /* This method checks if we can get the master passcode by + * decrypting the passwds file ( where we store all possible + * passwds cross-encrypted. + * + * TBD : As we are storing master passcode and the keys in 2 + * different files, we need to take care of cases when 1 of the files + * is deleted. + */ + + internal static bool CheckIfMasterPasscodeIsAvailable(string desktopPasswd, string fileName) + { + return (File.Exists(fileName)); + } + + internal static byte[] GetMasterPasscode(string desktopPasswd, string fileName) + { + byte[] mp = DecryptMasterPasscodeUsingString(desktopPasswd, fileName); + return mp; + } + + /* TBD - There must be a way, where we establish the integrity of + * the files where we store the keys and master passcode. + * Use a marker ? + */ + + // Used to save the MasterPasscode encrypted with Desktop login, etc + internal static void EncryptAndStoreMasterPasscodeUsingString( + byte[] baMasterPasscode, + string passwd, + string fileName) + { + FileStream fsEncrypt = null; + CryptoStream csEncrypt = null; + try + { + if(File.Exists(fileName)) + File.Delete(fileName); + byte[] baKey = Generate16ByteKeyFromString(passwd); + + + //Get an encryptor. + RijndaelManaged myRijndael = new RijndaelManaged(); + ICryptoTransform encryptor; + encryptor = myRijndael.CreateEncryptor(baKey, baKey); + + //Encrypt the data to a file + fsEncrypt = new FileStream(fileName,FileMode.Create); +#if LINUX + Mono.Unix.Syscall.chmod(fileName,Mono.Unix.FilePermissions.S_IRUSR | Mono.Unix.FilePermissions.S_IWUSR); +#endif + csEncrypt = new CryptoStream(fsEncrypt, encryptor, + CryptoStreamMode.Write); + + //Write all data to the crypto stream and flush it. + + csEncrypt.Write(baMasterPasscode, 0, baMasterPasscode.Length); + csEncrypt.FlushFinalBlock(); + fsEncrypt.Close(); + csEncrypt.Close(); + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + } + if( fsEncrypt != null ) + { + fsEncrypt.Close(); + } + if( csEncrypt != null ) + { + csEncrypt.Close(); + } + } + + public static byte[] DecryptMasterPasscodeUsingString(string passwd, + string fileName) + { + FileStream fsDecrypt = null; + CryptoStream csDecrypt = null; + byte[] baSavedMasterPasscode = null; + try + { + byte[] baKey = Generate16ByteKeyFromString(passwd); + + /* Get a decryptor that uses the same key and + * IV as the encryptor. + */ + RijndaelManaged myRijndael = new RijndaelManaged(); + ICryptoTransform decryptor = myRijndael.CreateDecryptor(baKey, + baKey); + //Now decrypt + fsDecrypt = new FileStream(fileName, FileMode.Open); + csDecrypt = new CryptoStream(fsDecrypt, decryptor, + CryptoStreamMode.Read); + baSavedMasterPasscode = new byte[16]; + + //Read the data out of the crypto stream. + csDecrypt.Read(baSavedMasterPasscode, 0, 16); + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + CSSSLogger.DbgLog("Unable to decrypt master passode"); + baSavedMasterPasscode = null; + } + if( fsDecrypt != null ) + fsDecrypt.Close(); + if( csDecrypt != null ) + csDecrypt.Close(); + return baSavedMasterPasscode; + } + + internal static byte[] GetMasterPasscodeUsingMasterPasswd( + string mPasswd, + string fileName) + { + byte[] baMasterPasscode; + try + { + if(File.Exists(fileName)) + { + /* Decrypt the passcode from the file using master passwd. + * and return the decrypted passcode. + */ + baMasterPasscode = DecryptMasterPasscodeUsingString(mPasswd, + fileName); + return baMasterPasscode; + } + else + return null; + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + CSSSLogger.DbgLog("Failed to get master passcode from master password."); + } + return null; + } + + internal static byte[] GetMasterPasscodeUsingDesktopPasswd( + string desktopPasswd, + string fileName) + { + byte[] passcode; + try + { + if(File.Exists(fileName)) + { + /* Decrypt the passcode from the file using desktop passwd. + * and return the decrypted passcode. + */ + passcode = DecryptMasterPasscodeUsingString(desktopPasswd, + fileName); + return passcode; + + } + else + return null; + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + CSSSLogger.DbgLog("Failed to get master passcode using desktop passwd"); + } + return null; + } + //internal static string GenerateMasterPasscodeUsingDesktopPasswd( + internal static byte[] GenerateMasterPasscodeUsingString( + string desktopPasswd, + string fileName, + string validationFile, + UserIdentifier userId + ) + { + try + { + byte[] baPasscode; + // use AES to generate a random 16 byte key; + RijndaelManaged myRijndael = new RijndaelManaged(); + myRijndael.KeySize = 128; + //Create a new key and initialization vector. + myRijndael.GenerateKey(); + baPasscode = myRijndael.Key; + + EncryptAndStoreMasterPasscodeUsingString(baPasscode, + desktopPasswd, + fileName); + EncryptDataAndWriteToFile( + Encoding.Default.GetBytes( + ConstStrings.MICASA_VALIDATION_STRING), + baPasscode, + validationFile); + return baPasscode; + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + CSSSLogger.DbgLog("Generation of master passcode failed."); + } + return null; + } + + public static bool ValidatePasscode(byte[] baPasscode, string fileName) + { + /* Here we decrpyt a well known string, throw exception + * if not successful + * A well-known string is encrpyted by the Passcode and saved + */ + + if ((baPasscode == null) || baPasscode.Length < 1 ) + return false; + + 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)) + { + return true; + } + else + { + return false; + } + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + CSSSLogger.DbgLog("Validation of passcode failed."); + } + return false; + } + + } }