diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2015-11-30 11:35:41 +0100 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2015-11-30 13:58:19 +0100 |
commit | efa436974d8203485eec6faa1bf0116bb32f6fcd (patch) | |
tree | 97a5ef2eea0310a12db399151de7ca97dbd47ece | |
parent | cfadb231d24bd292a6ea3708b776bde8f06e50ab (diff) | |
download | VeraCrypt-efa436974d8203485eec6faa1bf0116bb32f6fcd.tar.gz VeraCrypt-efa436974d8203485eec6faa1bf0116bb32f6fcd.zip |
Linux/MacOSX: Implement Unicode passwords suppport. Make validation of parameters in GUI more robust.
-rw-r--r-- | src/Main/CommandLineInterface.cpp | 42 | ||||
-rw-r--r-- | src/Main/CommandLineInterface.h | 3 | ||||
-rw-r--r-- | src/Main/Forms/ChangePasswordDialog.cpp | 66 | ||||
-rw-r--r-- | src/Main/Forms/MountOptionsDialog.cpp | 56 | ||||
-rw-r--r-- | src/Main/Forms/VolumeCreationWizard.cpp | 21 | ||||
-rw-r--r-- | src/Main/Forms/VolumePasswordPanel.cpp | 31 | ||||
-rw-r--r-- | src/Main/Forms/VolumePasswordPanel.h | 3 | ||||
-rw-r--r-- | src/Main/Forms/VolumePasswordWizardPage.cpp | 15 | ||||
-rw-r--r-- | src/Main/Forms/VolumePasswordWizardPage.h | 2 | ||||
-rw-r--r-- | src/Main/Forms/WaitDialog.cpp | 2 | ||||
-rw-r--r-- | src/Main/TextUserInterface.cpp | 54 | ||||
-rw-r--r-- | src/Main/UserInterface.cpp | 6 | ||||
-rw-r--r-- | src/Platform/Buffer.cpp | 8 | ||||
-rw-r--r-- | src/Volume/EncryptionTest.cpp | 2 | ||||
-rw-r--r-- | src/Volume/VolumePassword.cpp | 96 | ||||
-rw-r--r-- | src/Volume/VolumePassword.h | 13 |
16 files changed, 195 insertions, 225 deletions
diff --git a/src/Main/CommandLineInterface.cpp b/src/Main/CommandLineInterface.cpp index 3563f0b0..1b2ec46a 100644 --- a/src/Main/CommandLineInterface.cpp +++ b/src/Main/CommandLineInterface.cpp @@ -376,7 +376,7 @@ namespace VeraCrypt ArgNewKeyfiles = ToKeyfileList (str); if (parser.Found (L"new-password", &str)) - ArgNewPassword.reset (new VolumePassword (wstring (str))); + ArgNewPassword = ToUTF8Password (str); if (parser.Found (L"new-pim", &str)) { @@ -415,7 +415,7 @@ namespace VeraCrypt { if (Preferences.UseStandardInput) throw_err (L"--password cannot be used with --stdin"); - ArgPassword.reset (new VolumePassword (wstring (str))); + ArgPassword = ToUTF8Password (str); } if (parser.Found (L"pim", &str)) @@ -456,7 +456,7 @@ namespace VeraCrypt if (parser.Found (L"protection-password", &str)) { - ArgMountOptions.ProtectionPassword.reset (new VolumePassword (wstring (str))); + ArgMountOptions.ProtectionPassword = ToUTF8Password (str); ArgMountOptions.Protection = VolumeProtection::HiddenVolumeReadOnly; } @@ -713,5 +713,41 @@ namespace VeraCrypt return filteredVolumes; } + shared_ptr<VolumePassword> ToUTF8Password (const wchar_t* str, size_t charCount) + { + if (charCount > 0) + { + shared_ptr<SecureBuffer> utf8Buffer = ToUTF8Buffer (str, charCount); + return shared_ptr<VolumePassword>(new VolumePassword (*utf8Buffer)); + } + else + return shared_ptr<VolumePassword>(new VolumePassword ()); + } + + shared_ptr<SecureBuffer> ToUTF8Buffer (const wchar_t* str, size_t charCount) + { + if (charCount == (size_t) -1) + charCount = wcslen (str); + + if (charCount > 0) + { + wxMBConvUTF8 utf8; + size_t ulen = utf8.FromWChar (NULL, 0, str, charCount); + if (wxCONV_FAILED == ulen) + throw PasswordUTF8Invalid (SRC_POS); + SecureBuffer passwordBuf(ulen); + ulen = utf8.FromWChar ((char*) (byte*) passwordBuf, ulen, str, charCount); + if (wxCONV_FAILED == ulen) + throw PasswordUTF8Invalid (SRC_POS); + if (ulen > VolumePassword::MaxSize) + throw PasswordUTF8TooLong (SRC_POS); + + ConstBufferPtr utf8Buffer ((byte*) passwordBuf, ulen); + return shared_ptr<SecureBuffer>(new SecureBuffer (utf8Buffer)); + } + else + return shared_ptr<SecureBuffer>(new SecureBuffer ()); + } + auto_ptr <CommandLineInterface> CmdLine; } diff --git a/src/Main/CommandLineInterface.h b/src/Main/CommandLineInterface.h index 455baba3..608e9742 100644 --- a/src/Main/CommandLineInterface.h +++ b/src/Main/CommandLineInterface.h @@ -95,6 +95,9 @@ namespace VeraCrypt CommandLineInterface (const CommandLineInterface &); CommandLineInterface &operator= (const CommandLineInterface &); }; + + shared_ptr<VolumePassword> ToUTF8Password (const wchar_t* str, size_t charCount = (size_t) -1); + shared_ptr<SecureBuffer> ToUTF8Buffer (const wchar_t* str, size_t charCount = (size_t) -1); extern auto_ptr <CommandLineInterface> CmdLine; } diff --git a/src/Main/Forms/ChangePasswordDialog.cpp b/src/Main/Forms/ChangePasswordDialog.cpp index 25a85ce6..cb0e2076 100644 --- a/src/Main/Forms/ChangePasswordDialog.cpp +++ b/src/Main/Forms/ChangePasswordDialog.cpp @@ -85,11 +85,11 @@ namespace VeraCrypt try { - shared_ptr <Pkcs5Kdf> currentKdf = CurrentPasswordPanel->GetPkcs5Kdf(); - if (currentKdf && CurrentPasswordPanel->GetTrueCryptMode() && (currentKdf->GetName() == L"HMAC-SHA-256")) + bool bUnsupportedKdf = false; + shared_ptr <Pkcs5Kdf> currentKdf = CurrentPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf); + if (bUnsupportedKdf) { Gui->ShowWarning (LangString ["ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE"]); - event.Skip(); return; } @@ -97,15 +97,23 @@ namespace VeraCrypt int newPim = 0; if (DialogMode == Mode::ChangePasswordAndKeyfiles) { - newPassword = NewPasswordPanel->GetPassword(); + try + { + newPassword = NewPasswordPanel->GetPassword(); + } + catch (PasswordException& e) + { + Gui->ShowWarning (e); + NewPasswordPanel->SetFocusToPasswordTextCtrl(); + return; + } newPim = NewPasswordPanel->GetVolumePim(); - newPassword->CheckPortability(); if (newPassword->Size() > 0) { if (newPassword->Size() < VolumePassword::WarningSizeThreshold) { - if (newPim < 485) + if (newPim > 0 && newPim < 485) { Gui->ShowError ("PIM_REQUIRE_LONG_PASSWORD"); return; @@ -117,7 +125,7 @@ namespace VeraCrypt return; } } - else if (newPim < 485) + else if (newPim > 0 && newPim < 485) { if (!Gui->AskYesNo (LangString ["PIM_SMALL_WARNING"], false, true)) { @@ -141,7 +149,7 @@ namespace VeraCrypt /* force the display of the random enriching interface */ RandomNumberGenerator::SetEnrichedByUserStatus (false); - Gui->UserEnrichRandomPool (this, NewPasswordPanel->GetPkcs5Kdf() ? NewPasswordPanel->GetPkcs5Kdf()->GetHash() : shared_ptr <Hash>()); + Gui->UserEnrichRandomPool (this, NewPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf) ? NewPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf)->GetHash() : shared_ptr <Hash>()); { #ifdef TC_UNIX @@ -162,8 +170,8 @@ namespace VeraCrypt #endif wxBusyCursor busy; ChangePasswordThreadRoutine routine(Path, Gui->GetPreferences().DefaultMountOptions.PreserveTimestamps, - CurrentPasswordPanel->GetPassword(), CurrentPasswordPanel->GetVolumePim(), CurrentPasswordPanel->GetPkcs5Kdf(), CurrentPasswordPanel->GetTrueCryptMode(),CurrentPasswordPanel->GetKeyfiles(), - newPassword, newPim, newKeyfiles, NewPasswordPanel->GetPkcs5Kdf(), NewPasswordPanel->GetHeaderWipeCount()); + CurrentPasswordPanel->GetPassword(), CurrentPasswordPanel->GetVolumePim(), CurrentPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf), CurrentPasswordPanel->GetTrueCryptMode(),CurrentPasswordPanel->GetKeyfiles(), + newPassword, newPim, newKeyfiles, NewPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf), NewPasswordPanel->GetHeaderWipeCount()); Gui->ExecuteWaitThreadRoutine (this, &routine); } @@ -208,26 +216,34 @@ namespace VeraCrypt { bool ok = true; - bool passwordEmpty = CurrentPasswordPanel->GetPassword()->IsEmpty(); - bool keyfilesEmpty = !CurrentPasswordPanel->GetKeyfiles() || CurrentPasswordPanel->GetKeyfiles()->empty(); - - if (passwordEmpty && keyfilesEmpty) - ok = false; - - if (DialogMode == Mode::RemoveAllKeyfiles && (passwordEmpty || keyfilesEmpty)) - ok = false; - - if (DialogMode == Mode::ChangePasswordAndKeyfiles || DialogMode == Mode::ChangeKeyfiles) + try { - bool newKeyfilesEmpty = !NewPasswordPanel->GetKeyfiles() || NewPasswordPanel->GetKeyfiles()->empty(); - if (DialogMode == Mode::ChangeKeyfiles - && ((passwordEmpty && newKeyfilesEmpty) || (keyfilesEmpty && newKeyfilesEmpty))) + bool passwordEmpty = CurrentPasswordPanel->GetPassword()->IsEmpty(); + bool keyfilesEmpty = !CurrentPasswordPanel->GetKeyfiles() || CurrentPasswordPanel->GetKeyfiles()->empty(); + + if (passwordEmpty && keyfilesEmpty) ok = false; - if (DialogMode == Mode::ChangePasswordAndKeyfiles - && ((NewPasswordPanel->GetPassword()->IsEmpty() && newKeyfilesEmpty) || !NewPasswordPanel->PasswordsMatch())) + if (DialogMode == Mode::RemoveAllKeyfiles && (passwordEmpty || keyfilesEmpty)) ok = false; + + if (DialogMode == Mode::ChangePasswordAndKeyfiles || DialogMode == Mode::ChangeKeyfiles) + { + bool newKeyfilesEmpty = !NewPasswordPanel->GetKeyfiles() || NewPasswordPanel->GetKeyfiles()->empty(); + + if (DialogMode == Mode::ChangeKeyfiles + && ((passwordEmpty && newKeyfilesEmpty) || (keyfilesEmpty && newKeyfilesEmpty))) + ok = false; + + if (DialogMode == Mode::ChangePasswordAndKeyfiles + && ((NewPasswordPanel->GetPassword()->IsEmpty() && newKeyfilesEmpty) || !NewPasswordPanel->PasswordsMatch())) + ok = false; + } + } + catch (PasswordException&) + { + ok = false; } OKButton->Enable (ok); diff --git a/src/Main/Forms/MountOptionsDialog.cpp b/src/Main/Forms/MountOptionsDialog.cpp index 890c1ca2..2d53dda7 100644 --- a/src/Main/Forms/MountOptionsDialog.cpp +++ b/src/Main/Forms/MountOptionsDialog.cpp @@ -85,12 +85,26 @@ namespace VeraCrypt } void MountOptionsDialog::OnOKButtonClick (wxCommandEvent& event) - { + { + bool bUnsupportedKdf = false; TransferDataFromWindow(); - Options.Password = PasswordPanel->GetPassword(); + try + { + Options.Password = PasswordPanel->GetPassword(); + } + catch (PasswordException& e) + { + Gui->ShowWarning (e); + return; + } Options.Pim = PasswordPanel->GetVolumePim(); - Options.Kdf = PasswordPanel->GetPkcs5Kdf(); + Options.Kdf = PasswordPanel->GetPkcs5Kdf(bUnsupportedKdf); + if (bUnsupportedKdf) + { + Gui->ShowWarning (LangString ["ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE"]); + return; + } Options.TrueCryptMode = PasswordPanel->GetTrueCryptMode(); Options.Keyfiles = PasswordPanel->GetKeyfiles(); @@ -100,10 +114,23 @@ namespace VeraCrypt } else if (ProtectionCheckBox->IsChecked()) { - Options.Protection = VolumeProtection::HiddenVolumeReadOnly; - Options.ProtectionPassword = ProtectionPasswordPanel->GetPassword(); + try + { + Options.ProtectionPassword = ProtectionPasswordPanel->GetPassword(); + } + catch (PasswordException& e) + { + Gui->ShowWarning (e); + return; + } + Options.Protection = VolumeProtection::HiddenVolumeReadOnly; Options.ProtectionPim = ProtectionPasswordPanel->GetVolumePim(); - Options.ProtectionKdf = ProtectionPasswordPanel->GetPkcs5Kdf(); + Options.ProtectionKdf = ProtectionPasswordPanel->GetPkcs5Kdf(Options.TrueCryptMode, bUnsupportedKdf); + if (bUnsupportedKdf) + { + Gui->ShowWarning (LangString ["ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE"]); + return; + } Options.ProtectionKeyfiles = ProtectionPasswordPanel->GetKeyfiles(); } else @@ -117,23 +144,6 @@ namespace VeraCrypt Options.FilesystemOptions = FilesystemOptionsTextCtrl->GetValue(); - try - { - if (Options.Password) - Options.Password->CheckPortability(); - } - catch (UnportablePassword &) - { - Gui->ShowWarning (LangString ["UNSUPPORTED_CHARS_IN_PWD_RECOM"]); - } - - if (Options.TrueCryptMode && Options.Kdf && (Options.Kdf->GetName() == L"HMAC-SHA-256")) - { - Gui->ShowWarning (LangString ["ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE"]); - event.Skip(); - return; - } - EndModal (wxID_OK); } diff --git a/src/Main/Forms/VolumeCreationWizard.cpp b/src/Main/Forms/VolumeCreationWizard.cpp index 177e4059..a7f52430 100644 --- a/src/Main/Forms/VolumeCreationWizard.cpp +++ b/src/Main/Forms/VolumeCreationWizard.cpp @@ -733,22 +733,21 @@ namespace VeraCrypt case Step::VolumePassword: { VolumePasswordWizardPage *page = dynamic_cast <VolumePasswordWizardPage *> (GetCurrentPage()); - Password = page->GetPassword(); + try + { + Password = page->GetPassword(); + } + catch (PasswordException& e) + { + Gui->ShowWarning (e); + return GetCurrentStep(); + } + Kdf = page->GetPkcs5Kdf(); Keyfiles = page->GetKeyfiles(); if (forward && Password && !Password->IsEmpty()) { - try - { - Password->CheckPortability(); - } - catch (UnportablePassword &e) - { - Gui->ShowError (e); - return GetCurrentStep(); - } - if (Password->Size() < VolumePassword::WarningSizeThreshold) { if (!Gui->AskYesNo (LangString["PASSWORD_LENGTH_WARNING"], false, true)) diff --git a/src/Main/Forms/VolumePasswordPanel.cpp b/src/Main/Forms/VolumePasswordPanel.cpp index 03134535..e55b09f0 100644 --- a/src/Main/Forms/VolumePasswordPanel.cpp +++ b/src/Main/Forms/VolumePasswordPanel.cpp @@ -231,7 +231,7 @@ namespace VeraCrypt #ifdef TC_WINDOWS int len = GetWindowText (static_cast <HWND> (textCtrl->GetHandle()), passwordBuf, VolumePassword::MaxSize + 1); - password.reset (new VolumePassword (passwordBuf, len)); + password = ToUTF8Password (passwordBuf, len); #else wxString passwordStr (textCtrl->GetValue()); // A copy of the password is created here by wxWidgets, which cannot be erased for (size_t i = 0; i < passwordStr.size() && i < VolumePassword::MaxSize; ++i) @@ -239,19 +239,33 @@ namespace VeraCrypt passwordBuf[i] = (wchar_t) passwordStr[i]; passwordStr[i] = L'X'; } - password.reset (new VolumePassword (passwordBuf, passwordStr.size() <= VolumePassword::MaxSize ? passwordStr.size() : VolumePassword::MaxSize)); + password = ToUTF8Password (passwordBuf, passwordStr.size() <= VolumePassword::MaxSize ? passwordStr.size() : VolumePassword::MaxSize); #endif return password; } - shared_ptr <Pkcs5Kdf> VolumePasswordPanel::GetPkcs5Kdf () const + shared_ptr <Pkcs5Kdf> VolumePasswordPanel::GetPkcs5Kdf (bool &bUnsupportedKdf) const { + return GetPkcs5Kdf (GetTrueCryptMode(), bUnsupportedKdf); + } + + shared_ptr <Pkcs5Kdf> VolumePasswordPanel::GetPkcs5Kdf (bool bTrueCryptMode, bool &bUnsupportedKdf) const + { + bUnsupportedKdf = false; try { - return Pkcs5Kdf::GetAlgorithm (wstring (Pkcs5PrfChoice->GetStringSelection()), GetTrueCryptMode()); + int index = Pkcs5PrfChoice->GetSelection (); + if ((wxNOT_FOUND == index) || (0 == index)) + { + // auto-detection + return shared_ptr <Pkcs5Kdf> (); + } + else + return Pkcs5Kdf::GetAlgorithm (wstring (Pkcs5PrfChoice->GetStringSelection()), bTrueCryptMode); } catch (ParameterIncorrect&) { + bUnsupportedKdf = true; return shared_ptr <Pkcs5Kdf> (); } } @@ -419,7 +433,14 @@ namespace VeraCrypt bool VolumePasswordPanel::PasswordsMatch () const { assert (ConfirmPasswordStaticText->IsShown()); - return *GetPassword (PasswordTextCtrl) == *GetPassword (ConfirmPasswordTextCtrl); + try + { + return *GetPassword (PasswordTextCtrl) == *GetPassword (ConfirmPasswordTextCtrl); + } + catch (PasswordException&) + { + return false; + } } void VolumePasswordPanel::WipeTextCtrl (wxTextCtrl *textCtrl) diff --git a/src/Main/Forms/VolumePasswordPanel.h b/src/Main/Forms/VolumePasswordPanel.h index de2475e9..9d602391 100644 --- a/src/Main/Forms/VolumePasswordPanel.h +++ b/src/Main/Forms/VolumePasswordPanel.h @@ -28,7 +28,8 @@ namespace VeraCrypt void AddKeyfile (shared_ptr <Keyfile> keyfile); shared_ptr <KeyfileList> GetKeyfiles () const { return UseKeyfilesCheckBox->IsChecked() ? Keyfiles : shared_ptr <KeyfileList> (); } shared_ptr <VolumePassword> GetPassword () const; - shared_ptr <Pkcs5Kdf> GetPkcs5Kdf () const; + shared_ptr <Pkcs5Kdf> GetPkcs5Kdf (bool &bUnsupportedKdf) const; + shared_ptr <Pkcs5Kdf> GetPkcs5Kdf (bool bTrueCryptMode, bool &bUnsupportedKdf) const; int GetVolumePim () const; bool GetTrueCryptMode () const; int GetHeaderWipeCount () const; diff --git a/src/Main/Forms/VolumePasswordWizardPage.cpp b/src/Main/Forms/VolumePasswordWizardPage.cpp index f90f275c..d2fa48ad 100644 --- a/src/Main/Forms/VolumePasswordWizardPage.cpp +++ b/src/Main/Forms/VolumePasswordWizardPage.cpp @@ -35,9 +35,16 @@ namespace VeraCrypt if (ConfirmationMode && !PasswordPanel->PasswordsMatch()) return false; - shared_ptr <KeyfileList> keyfiles (GetKeyfiles()); - shared_ptr <VolumePassword> password (GetPassword()); - - return (password && !GetPassword()->IsEmpty()) || (keyfiles && !keyfiles->empty()); + try + { + shared_ptr <KeyfileList> keyfiles (GetKeyfiles()); + shared_ptr <VolumePassword> password (GetPassword()); + + return (password && !GetPassword()->IsEmpty()) || (keyfiles && !keyfiles->empty()); + } + catch (PasswordException&) + { + return false; + } } } diff --git a/src/Main/Forms/VolumePasswordWizardPage.h b/src/Main/Forms/VolumePasswordWizardPage.h index 50e48f2b..779988f4 100644 --- a/src/Main/Forms/VolumePasswordWizardPage.h +++ b/src/Main/Forms/VolumePasswordWizardPage.h @@ -30,7 +30,7 @@ namespace VeraCrypt bool IsPimSelected () const { return PasswordPanel->IsUsePimChecked ();} void SetPimSelected (bool selected) const { PasswordPanel->SetUsePimChecked (selected);} - shared_ptr <Pkcs5Kdf> GetPkcs5Kdf () const { return PasswordPanel->GetPkcs5Kdf(); } + shared_ptr <Pkcs5Kdf> GetPkcs5Kdf () const { bool bUnsupportedKdf; return PasswordPanel->GetPkcs5Kdf(bUnsupportedKdf); } bool IsValid (); void SetMaxStaticTextWidth (int width) { InfoStaticText->Wrap (width); } void SetPageText (const wxString &text) { InfoStaticText->SetLabel (text); } diff --git a/src/Main/Forms/WaitDialog.cpp b/src/Main/Forms/WaitDialog.cpp index 13f5eb12..8d06860b 100644 --- a/src/Main/Forms/WaitDialog.cpp +++ b/src/Main/Forms/WaitDialog.cpp @@ -37,6 +37,8 @@ namespace VeraCrypt VC_CONVERT_EXCEPTION (ProtectionPasswordKeyfilesIncorrect); VC_CONVERT_EXCEPTION (PasswordEmpty); VC_CONVERT_EXCEPTION (PasswordTooLong); + VC_CONVERT_EXCEPTION (PasswordUTF8TooLong); + VC_CONVERT_EXCEPTION (PasswordUTF8Invalid); VC_CONVERT_EXCEPTION (UnportablePassword); VC_CONVERT_EXCEPTION (ElevationFailed); VC_CONVERT_EXCEPTION (RootDeviceUnavailable); diff --git a/src/Main/TextUserInterface.cpp b/src/Main/TextUserInterface.cpp index 309a5931..ee2f0b06 100644 --- a/src/Main/TextUserInterface.cpp +++ b/src/Main/TextUserInterface.cpp @@ -97,7 +97,7 @@ namespace VeraCrypt wchar_t passwordBuf[4096]; finally_do_arg (BufferPtr, BufferPtr (reinterpret_cast <byte *> (passwordBuf), sizeof (passwordBuf)), { finally_arg.Erase(); }); - make_shared_auto (VolumePassword, password); + shared_ptr<VolumePassword> password; bool verPhase = false; while (true) @@ -113,8 +113,7 @@ namespace VeraCrypt if (!verPhase && length < 1) { - password->Set (passwordBuf, 0); - return password; + return shared_ptr <VolumePassword>(new VolumePassword ()); } for (size_t i = 0; i < length && i < VolumePassword::MaxSize; ++i) @@ -125,8 +124,7 @@ namespace VeraCrypt if (verify && verPhase) { - make_shared_auto (VolumePassword, verPassword); - verPassword->Set (passwordBuf, length); + shared_ptr <VolumePassword> verPassword = ToUTF8Password (passwordBuf, length); if (*password != *verPassword) { @@ -137,26 +135,10 @@ namespace VeraCrypt } } - password->Set (passwordBuf, length); + password = ToUTF8Password (passwordBuf, length); if (!verPhase) { - try - { - password->CheckPortability(); - } - catch (UnportablePassword &e) - { - if (verify) - { - ShowError (e); - verPhase = false; - continue; - } - - ShowWarning ("UNSUPPORTED_CHARS_IN_PWD_RECOM"); - } - if (verify) { if (password->Size() < VolumePassword::WarningSizeThreshold) @@ -433,14 +415,7 @@ namespace VeraCrypt // Current password if (!passwordInteractive) { - try - { - password->CheckPortability(); - } - catch (UnportablePassword &) - { - ShowWarning ("UNSUPPORTED_CHARS_IN_PWD_RECOM"); - } + } else if (!Preferences.NonInteractive) { @@ -487,9 +462,7 @@ namespace VeraCrypt } // New password - if (newPassword.get()) - newPassword->CheckPortability(); - else if (!Preferences.NonInteractive) + if (!newPassword.get() && !Preferences.NonInteractive) newPassword = AskPassword (_("Enter new password"), true); // New PIM @@ -789,9 +762,6 @@ namespace VeraCrypt ShowString (L"\n"); options->Password = AskPassword (_("Enter password"), true); } - - if (options->Password) - options->Password->CheckPortability(); // PIM if ((options->Pim < 0) && !Preferences.NonInteractive) @@ -1189,18 +1159,6 @@ namespace VeraCrypt { options.Password = AskPassword (StringFormatter (_("Enter password for {0}"), wstring (*options.Path))); } - else - { - try - { - if (options.Password) - options.Password->CheckPortability(); - } - catch (UnportablePassword &) - { - ShowWarning ("UNSUPPORTED_CHARS_IN_PWD_RECOM"); - } - } if (!options.TrueCryptMode && (options.Pim < 0)) { diff --git a/src/Main/UserInterface.cpp b/src/Main/UserInterface.cpp index 070a49c1..73c99142 100644 --- a/src/Main/UserInterface.cpp +++ b/src/Main/UserInterface.cpp @@ -462,6 +462,8 @@ namespace VeraCrypt EX2MSG (PasswordOrKeyboardLayoutIncorrect, LangString["PASSWORD_OR_KEYFILE_WRONG"] + _("\n\nNote that pre-boot authentication passwords need to be typed in the pre-boot environment where non-US keyboard layouts are not available. Therefore, pre-boot authentication passwords must always be typed using the standard US keyboard layout (otherwise, the password will be typed incorrectly in most cases). However, note that you do NOT need a real US keyboard; you just need to change the keyboard layout in your operating system.")); EX2MSG (PasswordOrMountOptionsIncorrect, LangString["PASSWORD_OR_KEYFILE_OR_MODE_WRONG"] + _("\n\nNote: If you are attempting to mount a partition located on an encrypted system drive without pre-boot authentication or to mount the encrypted system partition of an operating system that is not running, you can do so by selecting 'Options >' > 'Mount partition using system encryption'.")); EX2MSG (PasswordTooLong, StringFormatter (_("Password is longer than {0} characters."), (int) VolumePassword::MaxSize)); + EX2MSG (PasswordUTF8TooLong, LangString["PASSWORD_UTF8_TOO_LONG"]); + EX2MSG (PasswordUTF8Invalid, LangString["PASSWORD_UTF8_INVALID"]); EX2MSG (PartitionDeviceRequired, _("Partition device required.")); EX2MSG (ProtectionPasswordIncorrect, _("Incorrect password to the protected hidden volume or the hidden volume does not exist.")); EX2MSG (ProtectionPasswordKeyfilesIncorrect,_("Incorrect keyfile(s) and/or password to the protected hidden volume or the hidden volume does not exist.")); @@ -897,7 +899,7 @@ namespace VeraCrypt wstring pwdInput; wcin >> pwdInput; - cmdLine.ArgPassword = make_shared<VolumePassword> (pwdInput); + cmdLine.ArgPassword = ToUTF8Password ( pwdInput.c_str (), pwdInput.size ()); } switch (cmdLine.ArgCommand) @@ -1549,6 +1551,8 @@ namespace VeraCrypt VC_CONVERT_EXCEPTION (ProtectionPasswordKeyfilesIncorrect); VC_CONVERT_EXCEPTION (PasswordEmpty); VC_CONVERT_EXCEPTION (PasswordTooLong); + VC_CONVERT_EXCEPTION (PasswordUTF8TooLong); + VC_CONVERT_EXCEPTION (PasswordUTF8Invalid); VC_CONVERT_EXCEPTION (UnportablePassword); VC_CONVERT_EXCEPTION (ElevationFailed); VC_CONVERT_EXCEPTION (RootDeviceUnavailable); diff --git a/src/Platform/Buffer.cpp b/src/Platform/Buffer.cpp index 6fd8a01a..f0b7b693 100644 --- a/src/Platform/Buffer.cpp +++ b/src/Platform/Buffer.cpp @@ -58,11 +58,15 @@ namespace VeraCrypt void Buffer::CopyFrom (const ConstBufferPtr &bufferPtr)
{
if (!IsAllocated ())
- Allocate (bufferPtr.Size());
+ {
+ if (bufferPtr.Size())
+ Allocate (bufferPtr.Size());
+ }
else if (bufferPtr.Size() > DataSize)
throw ParameterTooLarge (SRC_POS);
- Memory::Copy (DataPtr, bufferPtr.Get(), bufferPtr.Size());
+ if (bufferPtr.Size())
+ Memory::Copy (DataPtr, bufferPtr.Get(), bufferPtr.Size());
}
void Buffer::Erase ()
diff --git a/src/Volume/EncryptionTest.cpp b/src/Volume/EncryptionTest.cpp index 0d9a0e03..cd94a09c 100644 --- a/src/Volume/EncryptionTest.cpp +++ b/src/Volume/EncryptionTest.cpp @@ -790,7 +790,7 @@ namespace VeraCrypt void EncryptionTest::TestPkcs5 () { - VolumePassword password ("password", 8); + VolumePassword password ((byte*) "password", 8); static const byte saltData[] = { 0x12, 0x34, 0x56, 0x78 }; ConstBufferPtr salt (saltData, sizeof (saltData)); Buffer derivedKey (4); diff --git a/src/Volume/VolumePassword.cpp b/src/Volume/VolumePassword.cpp index c36f910d..c6d27a67 100644 --- a/src/Volume/VolumePassword.cpp +++ b/src/Volume/VolumePassword.cpp @@ -16,31 +16,11 @@ namespace VeraCrypt { - VolumePassword::VolumePassword () : PasswordSize (0), Unportable (false) + VolumePassword::VolumePassword () : PasswordSize (0) { AllocateBuffer (); } - VolumePassword::VolumePassword (const char *password, size_t size) - { - Set ((const byte *) password, size); - } - - VolumePassword::VolumePassword (const byte *password, size_t size) - { - Set (password, size); - } - - VolumePassword::VolumePassword (const wchar_t *password, size_t charCount) - { - Set (password, charCount); - } - - VolumePassword::VolumePassword (const wstring &password) - { - Set (password.c_str(), password.size()); - } - VolumePassword::~VolumePassword () { } @@ -51,12 +31,6 @@ namespace VeraCrypt PasswordBuffer.Allocate (MaxSize); } - void VolumePassword::CheckPortability () const - { - if (Unportable || !IsPortable()) - throw UnportablePassword (SRC_POS); - } - void VolumePassword::Deserialize (shared_ptr <Stream> stream) { Serializer sr (stream); @@ -69,16 +43,6 @@ namespace VeraCrypt sr.Deserialize ("WipeData", wipeBuffer); } - bool VolumePassword::IsPortable () const - { - for (size_t i = 0; i < PasswordSize; i++) - { - if (PasswordBuffer[i] >= 0x7f || PasswordBuffer[i] < 0x20) - return false; - } - return true; - } - void VolumePassword::Serialize (shared_ptr <Stream> stream) const { Serializable::Serialize (stream); @@ -98,62 +62,12 @@ namespace VeraCrypt if (size > MaxSize) throw PasswordTooLong (SRC_POS); - - PasswordBuffer.CopyFrom (ConstBufferPtr (password, size)); - PasswordSize = size; - Unportable = !IsPortable(); - } - - void VolumePassword::Set (const wchar_t *password, size_t charCount) - { - if (charCount > MaxSize) - throw PasswordTooLong (SRC_POS); + PasswordBuffer.Erase (); + if (size > 0) + PasswordBuffer.CopyFrom (ConstBufferPtr (password, size)); - union Conv - { - byte b[sizeof (wchar_t)]; - wchar_t c; - }; - - Conv conv; - conv.c = L'A'; - - int lsbPos = -1; - for (size_t i = 0; i < sizeof (conv.b); ++i) - { - if (conv.b[i] == L'A') - { - lsbPos = i; - break; - } - } - - if (lsbPos == -1) - throw ParameterIncorrect (SRC_POS); - - bool unportable = false; - byte passwordBuf[MaxSize]; - for (size_t i = 0; i < charCount; ++i) - { - conv.c = password[i]; - passwordBuf[i] = conv.b[lsbPos]; - for (int j = 0; j < (int) sizeof (wchar_t); ++j) - { - if (j != lsbPos && conv.b[j] != 0) - unportable = true; - } - } - - Set (passwordBuf, charCount); - - if (unportable) - Unportable = true; - } - - void VolumePassword::Set (const ConstBufferPtr &password) - { - Set (password, password.Size()); + PasswordSize = size; } void VolumePassword::Set (const VolumePassword &password) diff --git a/src/Volume/VolumePassword.h b/src/Volume/VolumePassword.h index bf10eb98..ff7479a5 100644 --- a/src/Volume/VolumePassword.h +++ b/src/Volume/VolumePassword.h @@ -22,10 +22,8 @@ namespace VeraCrypt { public: VolumePassword (); - VolumePassword (const byte *password, size_t size); - VolumePassword (const char *password, size_t size); - VolumePassword (const wchar_t *password, size_t charCount); - VolumePassword (const wstring &password); + VolumePassword (const byte *password, size_t size) { Set (password, size); } + VolumePassword (const SecureBuffer &password) { Set (password.Ptr (), password.Size ()); } VolumePassword (const VolumePassword &password) { Set (password); } virtual ~VolumePassword (); @@ -35,13 +33,10 @@ namespace VeraCrypt operator BufferPtr () const { return BufferPtr (PasswordBuffer); } - void CheckPortability () const; byte *DataPtr () const { return PasswordBuffer; } bool IsEmpty () const { return PasswordSize == 0; } size_t Size () const { return PasswordSize; } void Set (const byte *password, size_t size); - void Set (const wchar_t *password, size_t charCount); - void Set (const ConstBufferPtr &password); void Set (const VolumePassword &password); TC_SERIALIZABLE (VolumePassword); @@ -51,12 +46,10 @@ namespace VeraCrypt protected: void AllocateBuffer (); - bool IsPortable () const; SecureBuffer PasswordBuffer; size_t PasswordSize; - bool Unportable; }; struct PasswordException : public Exception @@ -86,6 +79,8 @@ namespace VeraCrypt TC_EXCEPTION_NODECL (ProtectionPasswordKeyfilesIncorrect); \ TC_EXCEPTION (PasswordEmpty); \ TC_EXCEPTION (PasswordTooLong); \ + TC_EXCEPTION (PasswordUTF8TooLong); \ + TC_EXCEPTION (PasswordUTF8Invalid); \ TC_EXCEPTION (UnportablePassword); TC_EXCEPTION_SET; |