public static byte[] EncryptSEBSettingsWithCredentials(string settingsPassword, bool passwordIsHash, X509Certificate2 certificateRef, SEBSettings.sebConfigPurposes configPurpose, bool forEditing) { byte[] bytes = Encoding.UTF8.GetBytes(Plist.writeXml((object)SEBSettings.settingsCurrent).Replace("<array />", "<array></array>").Replace("<dict />", "<dict></dict>").Replace("<data />", "<data></data>")); string password = (string)null; if (string.IsNullOrEmpty(settingsPassword) && configPurpose == SEBSettings.sebConfigPurposes.sebConfigPurposeConfiguringClient) { password = ""; } else if (string.IsNullOrEmpty(settingsPassword) && certificateRef == null) { if (SEBMessageBox.Show(SEBUIStrings.noEncryptionChosen, SEBUIStrings.noEncryptionChosenSaveUnencrypted, MessageBoxIcon.Question, MessageBoxButtons.YesNo, forEditing) == DialogResult.Yes) { return(bytes); } return((byte[])null); } byte[] data = GZipByte.Compress(bytes); if (!string.IsNullOrEmpty(settingsPassword)) { password = settingsPassword; } byte[] numArray1; if (password != null) { numArray1 = SEBConfigFileManager.EncryptDataUsingPassword(data, password, passwordIsHash, configPurpose); } else { byte[] numArray2 = new byte[data.Length + 4]; Buffer.BlockCopy((Array)Encoding.UTF8.GetBytes("plnd"), 0, (Array)numArray2, 0, 4); Buffer.BlockCopy((Array)data, 0, (Array)numArray2, 4, data.Length); numArray1 = (byte[])numArray2.Clone(); } if (certificateRef != null) { numArray1 = SEBConfigFileManager.EncryptDataUsingIdentity(numArray1, certificateRef); } return(GZipByte.Compress(numArray1)); }
///// ---------------------------------------------------------------------------------------- ///// <summary> ///// Show SEB Password Dialog Form. ///// </summary> ///// ---------------------------------------------------------------------------------------- //public static string ShowPasswordDialogForm(string title, string passwordRequestText) //{ // // Set the title of the dialog window // sebPasswordDialogForm.Text = title; // // Set the text of the dialog // sebPasswordDialogForm.LabelText = passwordRequestText; // sebPasswordDialogForm.txtSEBPassword.Focus(); // // If we are running in SebWindowsClient we need to activate it before showing the password dialog // if (SEBClientInfo.SebWindowsClientForm != null) SebWindowsClientForm.SEBToForeground(); //SEBClientInfo.SebWindowsClientForm.Activate(); // // Show password dialog as a modal dialog and determine if DialogResult = OK. // if (sebPasswordDialogForm.ShowDialog() == DialogResult.OK) // { // // Read the contents of testDialog's TextBox. // string password = sebPasswordDialogForm.txtSEBPassword.Text; // sebPasswordDialogForm.txtSEBPassword.Text = ""; // //sebPasswordDialogForm.txtSEBPassword.Focus(); // return password; // } // else // { // return null; // } //} /// Generate Encrypted .seb Settings Data /// ---------------------------------------------------------------------------------------- /// <summary> /// Read SEB settings from UserDefaults and encrypt them using provided security credentials /// </summary> /// ---------------------------------------------------------------------------------------- public static byte[] EncryptSEBSettingsWithCredentials(string settingsPassword, bool passwordIsHash, X509Certificate2 certificateRef, SEBSettings.sebConfigPurposes configPurpose, bool forEditing) { // Get current settings dictionary and clean it from empty arrays and dictionaries //DictObj cleanedCurrentSettings = SEBSettings.CleanSettingsDictionary(); // Serialize preferences dictionary to an XML string string sebXML = Plist.writeXml(SEBSettings.settingsCurrent); string cleanedSebXML = sebXML.Replace("<array />", "<array></array>"); cleanedSebXML = cleanedSebXML.Replace("<dict />", "<dict></dict>"); cleanedSebXML = cleanedSebXML.Replace("<data />", "<data></data>"); byte[] encryptedSebData = Encoding.UTF8.GetBytes(cleanedSebXML); string encryptingPassword = null; // Check for special case: .seb configures client, empty password if (String.IsNullOrEmpty(settingsPassword) && configPurpose == SEBSettings.sebConfigPurposes.sebConfigPurposeConfiguringClient) { encryptingPassword = ""; } else { // in all other cases: // Check if no password entered and no identity selected if (String.IsNullOrEmpty(settingsPassword) && certificateRef == null) { if (SEBMessageBox.Show(SEBUIStrings.noEncryptionChosen, SEBUIStrings.noEncryptionChosenSaveUnencrypted, MessageBoxIcon.Question, MessageBoxButtons.YesNo, neverShowTouchOptimized: forEditing) == DialogResult.Yes) { // OK: save .seb config data unencrypted return(encryptedSebData); } else { return(null); } } } // gzip the serialized XML data encryptedSebData = GZipByte.Compress(encryptedSebData); // Check if password for encryption is provided and use it then if (!String.IsNullOrEmpty(settingsPassword)) { encryptingPassword = settingsPassword; } // So if password is empty (special case) or provided if (!(encryptingPassword == null)) { // encrypt with password encryptedSebData = EncryptDataUsingPassword(encryptedSebData, encryptingPassword, passwordIsHash, configPurpose); } else { // Create byte array large enough to hold prefix and data byte[] encryptedData = new byte[encryptedSebData.Length + PREFIX_LENGTH]; // if no encryption with password: Add a 4-char prefix identifying plain data string prefixString = PLAIN_DATA_MODE; Buffer.BlockCopy(Encoding.UTF8.GetBytes(prefixString), 0, encryptedData, 0, PREFIX_LENGTH); // append plain data Buffer.BlockCopy(encryptedSebData, 0, encryptedData, PREFIX_LENGTH, encryptedSebData.Length); encryptedSebData = (byte[])encryptedData.Clone(); } // Check if cryptographic identity for encryption is selected if (certificateRef != null) { // Encrypt preferences using a cryptographic identity encryptedSebData = EncryptDataUsingIdentity(encryptedSebData, certificateRef); } // gzip the encrypted data encryptedSebData = GZipByte.Compress(encryptedSebData); return(encryptedSebData); }
/// ---------------------------------------------------------------------------------------- /// <summary> /// Helper method which decrypts the byte array using an empty password, /// or the administrator password currently set in SEB /// or asks for the password used for encrypting this SEB file /// for configuring the client /// </summary> /// ---------------------------------------------------------------------------------------- private static DictObj DecryptDataWithPasswordForConfiguringClient(byte[] sebData, bool forEditing, ref string sebFilePassword, ref bool passwordIsHash) { passwordIsHash = false; string password; // First try to decrypt with the current admin password // get admin password hash string hashedAdminPassword = (string)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, SEBSettings.KeyHashedAdminPassword); if (hashedAdminPassword == null) { hashedAdminPassword = ""; } // We use always uppercase letters in the base16 hashed admin password used for encrypting hashedAdminPassword = hashedAdminPassword.ToUpper(); DictObj sebPreferencesDict = null; byte[] decryptedSebData = SEBProtectionController.DecryptDataWithPassword(sebData, hashedAdminPassword); if (decryptedSebData == null) { // If decryption with admin password didn't work, try it with an empty password decryptedSebData = SEBProtectionController.DecryptDataWithPassword(sebData, ""); if (decryptedSebData == null) { // If decryption with empty and admin password didn't work, ask for the password the .seb file was encrypted with // Allow up to 5 attempts for entering decoding password int i = 5; password = null; string enterPasswordString = SEBUIStrings.enterEncryptionPassword; do { i--; // Prompt for password password = ThreadedDialog.ShowPasswordDialogForm(SEBUIStrings.reconfiguringLocalSettings, enterPasswordString); // If cancel was pressed, abort if (password == null) { return(null); } string hashedPassword = SEBProtectionController.ComputePasswordHash(password); // we try to decrypt with the hashed password decryptedSebData = SEBProtectionController.DecryptDataWithPassword(sebData, hashedPassword); // in case we get an error we allow the user to try it again enterPasswordString = SEBUIStrings.enterEncryptionPasswordAgain; } while (decryptedSebData == null && i > 0); if (decryptedSebData == null) { //wrong password entered in 5th try: stop reading .seb file SEBMessageBox.Show(SEBUIStrings.reconfiguringLocalSettingsFailed, SEBUIStrings.reconfiguringLocalSettingsFailedWrongPassword, MessageBoxIcon.Error, MessageBoxButtons.OK, neverShowTouchOptimized: forEditing); return(null); } else { // Decrypting with entered password worked: We save it for returning it later if (forEditing) { sebFilePassword = password; } } } } else { //decrypting with hashedAdminPassword worked: we save it for returning as decryption password sebFilePassword = hashedAdminPassword; // identify that password as hash passwordIsHash = true; } /// Decryption worked // Ungzip the .seb (according to specification >= v14) decrypted serialized XML plist data decryptedSebData = GZipByte.Decompress(decryptedSebData); // Check if the openend reconfiguring seb file has the same admin password inside like the current one try { sebPreferencesDict = (DictObj)Plist.readPlist(decryptedSebData); } catch (Exception readPlistException) { // Error when deserializing the decrypted configuration data // We abort reading the new settings here SEBMessageBox.Show(SEBUIStrings.loadingSettingsFailed, SEBUIStrings.loadingSettingsFailedReason, MessageBoxIcon.Error, MessageBoxButtons.OK, neverShowTouchOptimized: forEditing); Console.WriteLine(readPlistException.Message); return(null); } // Get the admin password set in these settings string sebFileHashedAdminPassword = (string)SEBSettings.valueForDictionaryKey(sebPreferencesDict, SEBSettings.KeyHashedAdminPassword); if (sebFileHashedAdminPassword == null) { sebFileHashedAdminPassword = ""; } // Has the SEB config file the same admin password inside as the current settings have? if (String.Compare(hashedAdminPassword, sebFileHashedAdminPassword, StringComparison.OrdinalIgnoreCase) != 0) { //No: The admin password inside the .seb file wasn't the same as the current one if (forEditing) { // If the file is openend for editing (and not to reconfigure SEB) // we have to ask the user for the admin password inside the file if (!askForPasswordAndCompareToHashedPassword(sebFileHashedAdminPassword, forEditing)) { // If the user didn't enter the right password we abort return(null); } } else { // The file was actually opened for reconfiguring the SEB client: // we have to ask for the current admin password and // allow reconfiguring only if the user enters the right one // We don't check this for the case the current admin password was used to encrypt the new settings // In this case there can be a new admin pw defined in the new settings and users don't need to enter the old one if (passwordIsHash == false && hashedAdminPassword.Length > 0) { // Allow up to 5 attempts for entering current admin password int i = 5; password = null; string hashedPassword; string enterPasswordString = SEBUIStrings.enterCurrentAdminPwdForReconfiguring; bool passwordsMatch; do { i--; // Prompt for password password = ThreadedDialog.ShowPasswordDialogForm(SEBUIStrings.reconfiguringLocalSettings, enterPasswordString); // If cancel was pressed, abort if (password == null) { return(null); } if (password.Length == 0) { hashedPassword = ""; } else { hashedPassword = SEBProtectionController.ComputePasswordHash(password); } passwordsMatch = (String.Compare(hashedPassword, hashedAdminPassword, StringComparison.OrdinalIgnoreCase) == 0); // in case we get an error we allow the user to try it again enterPasswordString = SEBUIStrings.enterCurrentAdminPwdForReconfiguringAgain; } while (!passwordsMatch && i > 0); if (!passwordsMatch) { //wrong password entered in 5th try: stop reading .seb file SEBMessageBox.Show(SEBUIStrings.reconfiguringLocalSettingsFailed, SEBUIStrings.reconfiguringLocalSettingsFailedWrongCurrentAdminPwd, MessageBoxIcon.Error, MessageBoxButtons.OK, neverShowTouchOptimized: forEditing); return(null); } } } } // We need to set the right value for the key sebConfigPurpose to know later where to store the new settings sebPreferencesDict[SEBSettings.KeySebConfigPurpose] = (int)SEBSettings.sebConfigPurposes.sebConfigPurposeConfiguringClient; // Reading preferences was successful! return(sebPreferencesDict); }
/// ---------------------------------------------------------------------------------------- /// <summary> /// Decrypt and deserialize SEB settings /// When forEditing = true, then the decrypting password the user entered and/or /// certificate reference found in the .seb file is returned /// </summary> /// ---------------------------------------------------------------------------------------- public static DictObj DecryptSEBSettings(byte[] sebData, bool forEditing, ref string sebFilePassword, ref bool passwordIsHash, ref X509Certificate2 sebFileCertificateRef) { // Ungzip the .seb (according to specification >= v14) source data byte[] unzippedSebData = GZipByte.Decompress(sebData); // if unzipped data is not null, then unzipping worked, we use unzipped data // if unzipped data is null, then the source data may be an uncompressed .seb file, we proceed with it if (unzippedSebData != null) { sebData = unzippedSebData; } string prefixString; // save the data including the first 4 bytes for the case that it's acutally an unencrypted XML plist byte[] sebDataUnencrypted = sebData.Clone() as byte[]; // Get 4-char prefix prefixString = GetPrefixStringFromData(ref sebData); //// Check prefix identifying encryption modes // Prefix = pkhs ("Public Key Hash") ? if (prefixString.CompareTo(PUBLIC_KEY_HASH_MODE) == 0) { // Decrypt with cryptographic identity/private key sebData = DecryptDataWithPublicKeyHashPrefix(sebData, forEditing, ref sebFileCertificateRef); if (sebData == null) { return(null); } // Get 4-char prefix again // and remaining data without prefix, which is either plain or still encoded with password prefixString = GetPrefixStringFromData(ref sebData); } // Prefix = pswd ("Password") ? if (prefixString.CompareTo(PASSWORD_MODE) == 0) { // Decrypt with password // if the user enters the right one byte[] sebDataDecrypted = null; string password; // Allow up to 5 attempts for entering decoding password string enterPasswordString = SEBUIStrings.enterPassword; int i = 5; do { i--; // Prompt for password password = ThreadedDialog.ShowPasswordDialogForm(SEBUIStrings.loadingSettings, enterPasswordString); if (password == null) { return(null); } //error = nil; sebDataDecrypted = SEBProtectionController.DecryptDataWithPassword(sebData, password); enterPasswordString = SEBUIStrings.enterPasswordAgain; // in case we get an error we allow the user to try it again } while ((sebDataDecrypted == null) && i > 0); if (sebDataDecrypted == null) { //wrong password entered in 5th try: stop reading .seb file SEBMessageBox.Show(SEBUIStrings.decryptingSettingsFailed, SEBUIStrings.decryptingSettingsFailedReason, MessageBoxIcon.Error, MessageBoxButtons.OK, neverShowTouchOptimized: forEditing); return(null); } sebData = sebDataDecrypted; // If these settings are being decrypted for editing, we return the decryption password if (forEditing) { sebFilePassword = password; } } else { // Prefix = pwcc ("Password Configuring Client") ? if (prefixString.CompareTo(PASSWORD_CONFIGURING_CLIENT_MODE) == 0) { // Decrypt with password and configure local client settings // and quit afterwards, returning if reading the .seb file was successfull DictObj sebSettings = DecryptDataWithPasswordForConfiguringClient(sebData, forEditing, ref sebFilePassword, ref passwordIsHash); return(sebSettings); } else { // Prefix = plnd ("Plain Data") ? if (prefixString.CompareTo(PLAIN_DATA_MODE) != 0) { // No valid 4-char prefix was found in the .seb file // Check if .seb file is unencrypted if (prefixString.CompareTo(UNENCRYPTED_MODE) == 0) { // .seb file seems to be an unencrypted XML plist // get the original data including the first 4 bytes sebData = sebDataUnencrypted; } else { // No valid prefix and no unencrypted file with valid header // cancel reading .seb file SEBMessageBox.Show(SEBUIStrings.settingsNotUsable, SEBUIStrings.settingsNotUsableReason, MessageBoxIcon.Error, MessageBoxButtons.OK, neverShowTouchOptimized: forEditing); return(null); } } } } // If we don't deal with an unencrypted seb file // ungzip the .seb (according to specification >= v14) decrypted serialized XML plist data if (prefixString.CompareTo(UNENCRYPTED_MODE) != 0) { sebData = GZipByte.Decompress(sebData); } // Get preferences dictionary from decrypted data DictObj sebPreferencesDict = GetPreferencesDictFromConfigData(sebData, forEditing); // If we didn't get a preferences dict back, we abort reading settings if (sebPreferencesDict == null) { return(null); } // We need to set the right value for the key sebConfigPurpose to know later where to store the new settings sebPreferencesDict[SEBSettings.KeySebConfigPurpose] = (int)SEBSettings.sebConfigPurposes.sebConfigPurposeStartingExam; // Reading preferences was successful! return(sebPreferencesDict); }
private static Dictionary <string, object> DecryptDataWithPasswordForConfiguringClient(byte[] sebData, bool forEditing, ref string sebFilePassword, ref bool passwordIsHash) { passwordIsHash = false; string upper = ((string)SEBSettings.valueForDictionaryKey(SEBSettings.settingsCurrent, "hashedAdminPassword") ?? "").ToUpper(); byte[] input1 = SEBProtectionController.DecryptDataWithPassword(sebData, upper); string str1; if (input1 == null) { input1 = SEBProtectionController.DecryptDataWithPassword(sebData, ""); if (input1 == null) { int num1 = 5; str1 = (string)null; string passwordRequestText = SEBUIStrings.enterEncryptionPassword; string input2; do { --num1; input2 = ThreadedDialog.ShowPasswordDialogForm(SEBUIStrings.reconfiguringLocalSettings, passwordRequestText); if (input2 == null) { return((Dictionary <string, object>)null); } string passwordHash = SEBProtectionController.ComputePasswordHash(input2); input1 = SEBProtectionController.DecryptDataWithPassword(sebData, passwordHash); passwordRequestText = SEBUIStrings.enterEncryptionPasswordAgain; }while (input1 == null && num1 > 0); if (input1 == null) { int num2 = (int)SEBMessageBox.Show(SEBUIStrings.reconfiguringLocalSettingsFailed, SEBUIStrings.reconfiguringLocalSettingsFailedWrongPassword, MessageBoxIcon.Hand, MessageBoxButtons.OK, forEditing); return((Dictionary <string, object>)null); } if (forEditing) { sebFilePassword = input2; } } } else { sebFilePassword = upper; passwordIsHash = true; } byte[] data = GZipByte.Decompress(input1); Dictionary <string, object> dictionary; try { dictionary = (Dictionary <string, object>)Plist.readPlist(data); } catch (Exception ex) { int num = (int)SEBMessageBox.Show(SEBUIStrings.loadingSettingsFailed, SEBUIStrings.loadingSettingsFailedReason, MessageBoxIcon.Hand, MessageBoxButtons.OK, forEditing); Console.WriteLine(ex.Message); return((Dictionary <string, object>)null); } string str2 = (string)SEBSettings.valueForDictionaryKey(dictionary, "hashedAdminPassword") ?? ""; if (string.Compare(upper, str2, StringComparison.OrdinalIgnoreCase) != 0) { if (forEditing) { if (!SEBConfigFileManager.askForPasswordAndCompareToHashedPassword(str2, forEditing)) { return((Dictionary <string, object>)null); } } else if (!passwordIsHash && upper.Length > 0) { int num1 = 5; str1 = (string)null; string passwordRequestText = SEBUIStrings.enterCurrentAdminPwdForReconfiguring; bool flag; do { --num1; string input2 = ThreadedDialog.ShowPasswordDialogForm(SEBUIStrings.reconfiguringLocalSettings, passwordRequestText); if (input2 == null) { return((Dictionary <string, object>)null); } flag = string.Compare(input2.Length != 0 ? SEBProtectionController.ComputePasswordHash(input2) : "", upper, StringComparison.OrdinalIgnoreCase) == 0; passwordRequestText = SEBUIStrings.enterCurrentAdminPwdForReconfiguringAgain; }while (!flag && num1 > 0); if (!flag) { int num2 = (int)SEBMessageBox.Show(SEBUIStrings.reconfiguringLocalSettingsFailed, SEBUIStrings.reconfiguringLocalSettingsFailedWrongCurrentAdminPwd, MessageBoxIcon.Hand, MessageBoxButtons.OK, forEditing); return((Dictionary <string, object>)null); } } } dictionary["sebConfigPurpose"] = (object)1; return(dictionary); }
public static Dictionary <string, object> DecryptSEBSettings(byte[] sebData, bool forEditing, ref string sebFilePassword, ref bool passwordIsHash, ref X509Certificate2 sebFileCertificateRef) { byte[] numArray1 = GZipByte.Decompress(sebData); if (numArray1 != null) { sebData = numArray1; } byte[] numArray2 = sebData.Clone() as byte[]; string prefixStringFromData = SEBConfigFileManager.GetPrefixStringFromData(ref sebData); if (prefixStringFromData.CompareTo("pkhs") == 0) { sebData = SEBConfigFileManager.DecryptDataWithPublicKeyHashPrefix(sebData, forEditing, ref sebFileCertificateRef); if (sebData == null) { return((Dictionary <string, object>)null); } prefixStringFromData = SEBConfigFileManager.GetPrefixStringFromData(ref sebData); } if (prefixStringFromData.CompareTo("pswd") == 0) { string passwordRequestText = SEBUIStrings.enterPassword; int num1 = 5; string passphrase; byte[] numArray3; do { --num1; passphrase = ThreadedDialog.ShowPasswordDialogForm(SEBUIStrings.loadingSettings, passwordRequestText); if (passphrase == null) { return((Dictionary <string, object>)null); } numArray3 = SEBProtectionController.DecryptDataWithPassword(sebData, passphrase); passwordRequestText = SEBUIStrings.enterPasswordAgain; }while (numArray3 == null && num1 > 0); if (numArray3 == null) { int num2 = (int)SEBMessageBox.Show(SEBUIStrings.decryptingSettingsFailed, SEBUIStrings.decryptingSettingsFailedReason, MessageBoxIcon.Hand, MessageBoxButtons.OK, forEditing); return((Dictionary <string, object>)null); } sebData = numArray3; if (forEditing) { sebFilePassword = passphrase; } } else { if (prefixStringFromData.CompareTo("pwcc") == 0) { return(SEBConfigFileManager.DecryptDataWithPasswordForConfiguringClient(sebData, forEditing, ref sebFilePassword, ref passwordIsHash)); } if (prefixStringFromData.CompareTo("plnd") != 0) { if (prefixStringFromData.CompareTo("<?xm") == 0) { sebData = numArray2; } else { int num = (int)SEBMessageBox.Show(SEBUIStrings.settingsNotUsable, SEBUIStrings.settingsNotUsableReason, MessageBoxIcon.Hand, MessageBoxButtons.OK, forEditing); return((Dictionary <string, object>)null); } } } if (prefixStringFromData.CompareTo("<?xm") != 0) { sebData = GZipByte.Decompress(sebData); } Dictionary <string, object> dictFromConfigData = SEBConfigFileManager.GetPreferencesDictFromConfigData(sebData, forEditing); if (dictFromConfigData == null) { return((Dictionary <string, object>)null); } dictFromConfigData["sebConfigPurpose"] = (object)0; return(dictFromConfigData); }