Linux/MacOSX: Implement Unicode passwords suppport. Make validation of parameters in GUI more robust.

This commit is contained in:
Mounir IDRASSI 2015-11-30 11:35:41 +01:00
parent cfadb231d2
commit efa436974d
16 changed files with 195 additions and 225 deletions

View File

@ -376,7 +376,7 @@ namespace VeraCrypt
ArgNewKeyfiles = ToKeyfileList (str); ArgNewKeyfiles = ToKeyfileList (str);
if (parser.Found (L"new-password", &str)) if (parser.Found (L"new-password", &str))
ArgNewPassword.reset (new VolumePassword (wstring (str))); ArgNewPassword = ToUTF8Password (str);
if (parser.Found (L"new-pim", &str)) if (parser.Found (L"new-pim", &str))
{ {
@ -415,7 +415,7 @@ namespace VeraCrypt
{ {
if (Preferences.UseStandardInput) if (Preferences.UseStandardInput)
throw_err (L"--password cannot be used with --stdin"); throw_err (L"--password cannot be used with --stdin");
ArgPassword.reset (new VolumePassword (wstring (str))); ArgPassword = ToUTF8Password (str);
} }
if (parser.Found (L"pim", &str)) if (parser.Found (L"pim", &str))
@ -456,7 +456,7 @@ namespace VeraCrypt
if (parser.Found (L"protection-password", &str)) if (parser.Found (L"protection-password", &str))
{ {
ArgMountOptions.ProtectionPassword.reset (new VolumePassword (wstring (str))); ArgMountOptions.ProtectionPassword = ToUTF8Password (str);
ArgMountOptions.Protection = VolumeProtection::HiddenVolumeReadOnly; ArgMountOptions.Protection = VolumeProtection::HiddenVolumeReadOnly;
} }
@ -713,5 +713,41 @@ namespace VeraCrypt
return filteredVolumes; 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; auto_ptr <CommandLineInterface> CmdLine;
} }

View File

@ -96,6 +96,9 @@ namespace VeraCrypt
CommandLineInterface &operator= (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; extern auto_ptr <CommandLineInterface> CmdLine;
} }

View File

@ -85,27 +85,35 @@ namespace VeraCrypt
try try
{ {
shared_ptr <Pkcs5Kdf> currentKdf = CurrentPasswordPanel->GetPkcs5Kdf(); bool bUnsupportedKdf = false;
if (currentKdf && CurrentPasswordPanel->GetTrueCryptMode() && (currentKdf->GetName() == L"HMAC-SHA-256")) shared_ptr <Pkcs5Kdf> currentKdf = CurrentPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf);
if (bUnsupportedKdf)
{ {
Gui->ShowWarning (LangString ["ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE"]); Gui->ShowWarning (LangString ["ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE"]);
event.Skip();
return; return;
} }
shared_ptr <VolumePassword> newPassword; shared_ptr <VolumePassword> newPassword;
int newPim = 0; int newPim = 0;
if (DialogMode == Mode::ChangePasswordAndKeyfiles) if (DialogMode == Mode::ChangePasswordAndKeyfiles)
{
try
{ {
newPassword = NewPasswordPanel->GetPassword(); newPassword = NewPasswordPanel->GetPassword();
}
catch (PasswordException& e)
{
Gui->ShowWarning (e);
NewPasswordPanel->SetFocusToPasswordTextCtrl();
return;
}
newPim = NewPasswordPanel->GetVolumePim(); newPim = NewPasswordPanel->GetVolumePim();
newPassword->CheckPortability();
if (newPassword->Size() > 0) if (newPassword->Size() > 0)
{ {
if (newPassword->Size() < VolumePassword::WarningSizeThreshold) if (newPassword->Size() < VolumePassword::WarningSizeThreshold)
{ {
if (newPim < 485) if (newPim > 0 && newPim < 485)
{ {
Gui->ShowError ("PIM_REQUIRE_LONG_PASSWORD"); Gui->ShowError ("PIM_REQUIRE_LONG_PASSWORD");
return; return;
@ -117,7 +125,7 @@ namespace VeraCrypt
return; return;
} }
} }
else if (newPim < 485) else if (newPim > 0 && newPim < 485)
{ {
if (!Gui->AskYesNo (LangString ["PIM_SMALL_WARNING"], false, true)) if (!Gui->AskYesNo (LangString ["PIM_SMALL_WARNING"], false, true))
{ {
@ -141,7 +149,7 @@ namespace VeraCrypt
/* force the display of the random enriching interface */ /* force the display of the random enriching interface */
RandomNumberGenerator::SetEnrichedByUserStatus (false); 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 #ifdef TC_UNIX
@ -162,8 +170,8 @@ namespace VeraCrypt
#endif #endif
wxBusyCursor busy; wxBusyCursor busy;
ChangePasswordThreadRoutine routine(Path, Gui->GetPreferences().DefaultMountOptions.PreserveTimestamps, ChangePasswordThreadRoutine routine(Path, Gui->GetPreferences().DefaultMountOptions.PreserveTimestamps,
CurrentPasswordPanel->GetPassword(), CurrentPasswordPanel->GetVolumePim(), CurrentPasswordPanel->GetPkcs5Kdf(), CurrentPasswordPanel->GetTrueCryptMode(),CurrentPasswordPanel->GetKeyfiles(), CurrentPasswordPanel->GetPassword(), CurrentPasswordPanel->GetVolumePim(), CurrentPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf), CurrentPasswordPanel->GetTrueCryptMode(),CurrentPasswordPanel->GetKeyfiles(),
newPassword, newPim, newKeyfiles, NewPasswordPanel->GetPkcs5Kdf(), NewPasswordPanel->GetHeaderWipeCount()); newPassword, newPim, newKeyfiles, NewPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf), NewPasswordPanel->GetHeaderWipeCount());
Gui->ExecuteWaitThreadRoutine (this, &routine); Gui->ExecuteWaitThreadRoutine (this, &routine);
} }
@ -208,6 +216,9 @@ namespace VeraCrypt
{ {
bool ok = true; bool ok = true;
try
{
bool passwordEmpty = CurrentPasswordPanel->GetPassword()->IsEmpty(); bool passwordEmpty = CurrentPasswordPanel->GetPassword()->IsEmpty();
bool keyfilesEmpty = !CurrentPasswordPanel->GetKeyfiles() || CurrentPasswordPanel->GetKeyfiles()->empty(); bool keyfilesEmpty = !CurrentPasswordPanel->GetKeyfiles() || CurrentPasswordPanel->GetKeyfiles()->empty();
@ -229,6 +240,11 @@ namespace VeraCrypt
&& ((NewPasswordPanel->GetPassword()->IsEmpty() && newKeyfilesEmpty) || !NewPasswordPanel->PasswordsMatch())) && ((NewPasswordPanel->GetPassword()->IsEmpty() && newKeyfilesEmpty) || !NewPasswordPanel->PasswordsMatch()))
ok = false; ok = false;
} }
}
catch (PasswordException&)
{
ok = false;
}
OKButton->Enable (ok); OKButton->Enable (ok);

View File

@ -86,11 +86,25 @@ namespace VeraCrypt
void MountOptionsDialog::OnOKButtonClick (wxCommandEvent& event) void MountOptionsDialog::OnOKButtonClick (wxCommandEvent& event)
{ {
bool bUnsupportedKdf = false;
TransferDataFromWindow(); TransferDataFromWindow();
try
{
Options.Password = PasswordPanel->GetPassword(); Options.Password = PasswordPanel->GetPassword();
}
catch (PasswordException& e)
{
Gui->ShowWarning (e);
return;
}
Options.Pim = PasswordPanel->GetVolumePim(); 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.TrueCryptMode = PasswordPanel->GetTrueCryptMode();
Options.Keyfiles = PasswordPanel->GetKeyfiles(); Options.Keyfiles = PasswordPanel->GetKeyfiles();
@ -100,10 +114,23 @@ namespace VeraCrypt
} }
else if (ProtectionCheckBox->IsChecked()) else if (ProtectionCheckBox->IsChecked())
{ {
Options.Protection = VolumeProtection::HiddenVolumeReadOnly; try
{
Options.ProtectionPassword = ProtectionPasswordPanel->GetPassword(); Options.ProtectionPassword = ProtectionPasswordPanel->GetPassword();
}
catch (PasswordException& e)
{
Gui->ShowWarning (e);
return;
}
Options.Protection = VolumeProtection::HiddenVolumeReadOnly;
Options.ProtectionPim = ProtectionPasswordPanel->GetVolumePim(); 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(); Options.ProtectionKeyfiles = ProtectionPasswordPanel->GetKeyfiles();
} }
else else
@ -117,23 +144,6 @@ namespace VeraCrypt
Options.FilesystemOptions = FilesystemOptionsTextCtrl->GetValue(); 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); EndModal (wxID_OK);
} }

View File

@ -733,22 +733,21 @@ namespace VeraCrypt
case Step::VolumePassword: case Step::VolumePassword:
{ {
VolumePasswordWizardPage *page = dynamic_cast <VolumePasswordWizardPage *> (GetCurrentPage()); VolumePasswordWizardPage *page = dynamic_cast <VolumePasswordWizardPage *> (GetCurrentPage());
try
{
Password = page->GetPassword(); Password = page->GetPassword();
}
catch (PasswordException& e)
{
Gui->ShowWarning (e);
return GetCurrentStep();
}
Kdf = page->GetPkcs5Kdf(); Kdf = page->GetPkcs5Kdf();
Keyfiles = page->GetKeyfiles(); Keyfiles = page->GetKeyfiles();
if (forward && Password && !Password->IsEmpty()) if (forward && Password && !Password->IsEmpty())
{ {
try
{
Password->CheckPortability();
}
catch (UnportablePassword &e)
{
Gui->ShowError (e);
return GetCurrentStep();
}
if (Password->Size() < VolumePassword::WarningSizeThreshold) if (Password->Size() < VolumePassword::WarningSizeThreshold)
{ {
if (!Gui->AskYesNo (LangString["PASSWORD_LENGTH_WARNING"], false, true)) if (!Gui->AskYesNo (LangString["PASSWORD_LENGTH_WARNING"], false, true))

View File

@ -231,7 +231,7 @@ namespace VeraCrypt
#ifdef TC_WINDOWS #ifdef TC_WINDOWS
int len = GetWindowText (static_cast <HWND> (textCtrl->GetHandle()), passwordBuf, VolumePassword::MaxSize + 1); int len = GetWindowText (static_cast <HWND> (textCtrl->GetHandle()), passwordBuf, VolumePassword::MaxSize + 1);
password.reset (new VolumePassword (passwordBuf, len)); password = ToUTF8Password (passwordBuf, len);
#else #else
wxString passwordStr (textCtrl->GetValue()); // A copy of the password is created here by wxWidgets, which cannot be erased 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) for (size_t i = 0; i < passwordStr.size() && i < VolumePassword::MaxSize; ++i)
@ -239,19 +239,33 @@ namespace VeraCrypt
passwordBuf[i] = (wchar_t) passwordStr[i]; passwordBuf[i] = (wchar_t) passwordStr[i];
passwordStr[i] = L'X'; 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 #endif
return password; 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 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&) catch (ParameterIncorrect&)
{ {
bUnsupportedKdf = true;
return shared_ptr <Pkcs5Kdf> (); return shared_ptr <Pkcs5Kdf> ();
} }
} }
@ -419,8 +433,15 @@ namespace VeraCrypt
bool VolumePasswordPanel::PasswordsMatch () const bool VolumePasswordPanel::PasswordsMatch () const
{ {
assert (ConfirmPasswordStaticText->IsShown()); assert (ConfirmPasswordStaticText->IsShown());
try
{
return *GetPassword (PasswordTextCtrl) == *GetPassword (ConfirmPasswordTextCtrl); return *GetPassword (PasswordTextCtrl) == *GetPassword (ConfirmPasswordTextCtrl);
} }
catch (PasswordException&)
{
return false;
}
}
void VolumePasswordPanel::WipeTextCtrl (wxTextCtrl *textCtrl) void VolumePasswordPanel::WipeTextCtrl (wxTextCtrl *textCtrl)
{ {

View File

@ -28,7 +28,8 @@ namespace VeraCrypt
void AddKeyfile (shared_ptr <Keyfile> keyfile); void AddKeyfile (shared_ptr <Keyfile> keyfile);
shared_ptr <KeyfileList> GetKeyfiles () const { return UseKeyfilesCheckBox->IsChecked() ? Keyfiles : shared_ptr <KeyfileList> (); } shared_ptr <KeyfileList> GetKeyfiles () const { return UseKeyfilesCheckBox->IsChecked() ? Keyfiles : shared_ptr <KeyfileList> (); }
shared_ptr <VolumePassword> GetPassword () const; 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; int GetVolumePim () const;
bool GetTrueCryptMode () const; bool GetTrueCryptMode () const;
int GetHeaderWipeCount () const; int GetHeaderWipeCount () const;

View File

@ -35,9 +35,16 @@ namespace VeraCrypt
if (ConfirmationMode && !PasswordPanel->PasswordsMatch()) if (ConfirmationMode && !PasswordPanel->PasswordsMatch())
return false; return false;
try
{
shared_ptr <KeyfileList> keyfiles (GetKeyfiles()); shared_ptr <KeyfileList> keyfiles (GetKeyfiles());
shared_ptr <VolumePassword> password (GetPassword()); shared_ptr <VolumePassword> password (GetPassword());
return (password && !GetPassword()->IsEmpty()) || (keyfiles && !keyfiles->empty()); return (password && !GetPassword()->IsEmpty()) || (keyfiles && !keyfiles->empty());
} }
catch (PasswordException&)
{
return false;
}
}
} }

View File

@ -30,7 +30,7 @@ namespace VeraCrypt
bool IsPimSelected () const { return PasswordPanel->IsUsePimChecked ();} bool IsPimSelected () const { return PasswordPanel->IsUsePimChecked ();}
void SetPimSelected (bool selected) const { PasswordPanel->SetUsePimChecked (selected);} 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 (); bool IsValid ();
void SetMaxStaticTextWidth (int width) { InfoStaticText->Wrap (width); } void SetMaxStaticTextWidth (int width) { InfoStaticText->Wrap (width); }
void SetPageText (const wxString &text) { InfoStaticText->SetLabel (text); } void SetPageText (const wxString &text) { InfoStaticText->SetLabel (text); }

View File

@ -37,6 +37,8 @@ namespace VeraCrypt
VC_CONVERT_EXCEPTION (ProtectionPasswordKeyfilesIncorrect); VC_CONVERT_EXCEPTION (ProtectionPasswordKeyfilesIncorrect);
VC_CONVERT_EXCEPTION (PasswordEmpty); VC_CONVERT_EXCEPTION (PasswordEmpty);
VC_CONVERT_EXCEPTION (PasswordTooLong); VC_CONVERT_EXCEPTION (PasswordTooLong);
VC_CONVERT_EXCEPTION (PasswordUTF8TooLong);
VC_CONVERT_EXCEPTION (PasswordUTF8Invalid);
VC_CONVERT_EXCEPTION (UnportablePassword); VC_CONVERT_EXCEPTION (UnportablePassword);
VC_CONVERT_EXCEPTION (ElevationFailed); VC_CONVERT_EXCEPTION (ElevationFailed);
VC_CONVERT_EXCEPTION (RootDeviceUnavailable); VC_CONVERT_EXCEPTION (RootDeviceUnavailable);

View File

@ -97,7 +97,7 @@ namespace VeraCrypt
wchar_t passwordBuf[4096]; wchar_t passwordBuf[4096];
finally_do_arg (BufferPtr, BufferPtr (reinterpret_cast <byte *> (passwordBuf), sizeof (passwordBuf)), { finally_arg.Erase(); }); 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; bool verPhase = false;
while (true) while (true)
@ -113,8 +113,7 @@ namespace VeraCrypt
if (!verPhase && length < 1) if (!verPhase && length < 1)
{ {
password->Set (passwordBuf, 0); return shared_ptr <VolumePassword>(new VolumePassword ());
return password;
} }
for (size_t i = 0; i < length && i < VolumePassword::MaxSize; ++i) for (size_t i = 0; i < length && i < VolumePassword::MaxSize; ++i)
@ -125,8 +124,7 @@ namespace VeraCrypt
if (verify && verPhase) if (verify && verPhase)
{ {
make_shared_auto (VolumePassword, verPassword); shared_ptr <VolumePassword> verPassword = ToUTF8Password (passwordBuf, length);
verPassword->Set (passwordBuf, length);
if (*password != *verPassword) if (*password != *verPassword)
{ {
@ -137,26 +135,10 @@ namespace VeraCrypt
} }
} }
password->Set (passwordBuf, length); password = ToUTF8Password (passwordBuf, length);
if (!verPhase) if (!verPhase)
{ {
try
{
password->CheckPortability();
}
catch (UnportablePassword &e)
{
if (verify)
{
ShowError (e);
verPhase = false;
continue;
}
ShowWarning ("UNSUPPORTED_CHARS_IN_PWD_RECOM");
}
if (verify) if (verify)
{ {
if (password->Size() < VolumePassword::WarningSizeThreshold) if (password->Size() < VolumePassword::WarningSizeThreshold)
@ -433,14 +415,7 @@ namespace VeraCrypt
// Current password // Current password
if (!passwordInteractive) if (!passwordInteractive)
{ {
try
{
password->CheckPortability();
}
catch (UnportablePassword &)
{
ShowWarning ("UNSUPPORTED_CHARS_IN_PWD_RECOM");
}
} }
else if (!Preferences.NonInteractive) else if (!Preferences.NonInteractive)
{ {
@ -487,9 +462,7 @@ namespace VeraCrypt
} }
// New password // New password
if (newPassword.get()) if (!newPassword.get() && !Preferences.NonInteractive)
newPassword->CheckPortability();
else if (!Preferences.NonInteractive)
newPassword = AskPassword (_("Enter new password"), true); newPassword = AskPassword (_("Enter new password"), true);
// New PIM // New PIM
@ -790,9 +763,6 @@ namespace VeraCrypt
options->Password = AskPassword (_("Enter password"), true); options->Password = AskPassword (_("Enter password"), true);
} }
if (options->Password)
options->Password->CheckPortability();
// PIM // PIM
if ((options->Pim < 0) && !Preferences.NonInteractive) if ((options->Pim < 0) && !Preferences.NonInteractive)
{ {
@ -1189,18 +1159,6 @@ namespace VeraCrypt
{ {
options.Password = AskPassword (StringFormatter (_("Enter password for {0}"), wstring (*options.Path))); 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)) if (!options.TrueCryptMode && (options.Pim < 0))
{ {

View File

@ -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 (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 (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 (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 (PartitionDeviceRequired, _("Partition device required."));
EX2MSG (ProtectionPasswordIncorrect, _("Incorrect password to the protected hidden volume or the hidden volume does not exist.")); 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.")); 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; wstring pwdInput;
wcin >> pwdInput; wcin >> pwdInput;
cmdLine.ArgPassword = make_shared<VolumePassword> (pwdInput); cmdLine.ArgPassword = ToUTF8Password ( pwdInput.c_str (), pwdInput.size ());
} }
switch (cmdLine.ArgCommand) switch (cmdLine.ArgCommand)
@ -1549,6 +1551,8 @@ namespace VeraCrypt
VC_CONVERT_EXCEPTION (ProtectionPasswordKeyfilesIncorrect); VC_CONVERT_EXCEPTION (ProtectionPasswordKeyfilesIncorrect);
VC_CONVERT_EXCEPTION (PasswordEmpty); VC_CONVERT_EXCEPTION (PasswordEmpty);
VC_CONVERT_EXCEPTION (PasswordTooLong); VC_CONVERT_EXCEPTION (PasswordTooLong);
VC_CONVERT_EXCEPTION (PasswordUTF8TooLong);
VC_CONVERT_EXCEPTION (PasswordUTF8Invalid);
VC_CONVERT_EXCEPTION (UnportablePassword); VC_CONVERT_EXCEPTION (UnportablePassword);
VC_CONVERT_EXCEPTION (ElevationFailed); VC_CONVERT_EXCEPTION (ElevationFailed);
VC_CONVERT_EXCEPTION (RootDeviceUnavailable); VC_CONVERT_EXCEPTION (RootDeviceUnavailable);

View File

@ -58,10 +58,14 @@ namespace VeraCrypt
void Buffer::CopyFrom (const ConstBufferPtr &bufferPtr) void Buffer::CopyFrom (const ConstBufferPtr &bufferPtr)
{ {
if (!IsAllocated ()) if (!IsAllocated ())
{
if (bufferPtr.Size())
Allocate (bufferPtr.Size()); Allocate (bufferPtr.Size());
}
else if (bufferPtr.Size() > DataSize) else if (bufferPtr.Size() > DataSize)
throw ParameterTooLarge (SRC_POS); throw ParameterTooLarge (SRC_POS);
if (bufferPtr.Size())
Memory::Copy (DataPtr, bufferPtr.Get(), bufferPtr.Size()); Memory::Copy (DataPtr, bufferPtr.Get(), bufferPtr.Size());
} }

View File

@ -790,7 +790,7 @@ namespace VeraCrypt
void EncryptionTest::TestPkcs5 () void EncryptionTest::TestPkcs5 ()
{ {
VolumePassword password ("password", 8); VolumePassword password ((byte*) "password", 8);
static const byte saltData[] = { 0x12, 0x34, 0x56, 0x78 }; static const byte saltData[] = { 0x12, 0x34, 0x56, 0x78 };
ConstBufferPtr salt (saltData, sizeof (saltData)); ConstBufferPtr salt (saltData, sizeof (saltData));
Buffer derivedKey (4); Buffer derivedKey (4);

View File

@ -16,31 +16,11 @@
namespace VeraCrypt namespace VeraCrypt
{ {
VolumePassword::VolumePassword () : PasswordSize (0), Unportable (false) VolumePassword::VolumePassword () : PasswordSize (0)
{ {
AllocateBuffer (); 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 () VolumePassword::~VolumePassword ()
{ {
} }
@ -51,12 +31,6 @@ namespace VeraCrypt
PasswordBuffer.Allocate (MaxSize); PasswordBuffer.Allocate (MaxSize);
} }
void VolumePassword::CheckPortability () const
{
if (Unportable || !IsPortable())
throw UnportablePassword (SRC_POS);
}
void VolumePassword::Deserialize (shared_ptr <Stream> stream) void VolumePassword::Deserialize (shared_ptr <Stream> stream)
{ {
Serializer sr (stream); Serializer sr (stream);
@ -69,16 +43,6 @@ namespace VeraCrypt
sr.Deserialize ("WipeData", wipeBuffer); 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 void VolumePassword::Serialize (shared_ptr <Stream> stream) const
{ {
Serializable::Serialize (stream); Serializable::Serialize (stream);
@ -99,61 +63,11 @@ namespace VeraCrypt
if (size > MaxSize) if (size > MaxSize)
throw PasswordTooLong (SRC_POS); throw PasswordTooLong (SRC_POS);
PasswordBuffer.Erase ();
if (size > 0)
PasswordBuffer.CopyFrom (ConstBufferPtr (password, size)); PasswordBuffer.CopyFrom (ConstBufferPtr (password, size));
PasswordSize = size; PasswordSize = size;
Unportable = !IsPortable();
}
void VolumePassword::Set (const wchar_t *password, size_t charCount)
{
if (charCount > MaxSize)
throw PasswordTooLong (SRC_POS);
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());
} }
void VolumePassword::Set (const VolumePassword &password) void VolumePassword::Set (const VolumePassword &password)

View File

@ -22,10 +22,8 @@ namespace VeraCrypt
{ {
public: public:
VolumePassword (); VolumePassword ();
VolumePassword (const byte *password, size_t size); VolumePassword (const byte *password, size_t size) { Set (password, size); }
VolumePassword (const char *password, size_t size); VolumePassword (const SecureBuffer &password) { Set (password.Ptr (), password.Size ()); }
VolumePassword (const wchar_t *password, size_t charCount);
VolumePassword (const wstring &password);
VolumePassword (const VolumePassword &password) { Set (password); } VolumePassword (const VolumePassword &password) { Set (password); }
virtual ~VolumePassword (); virtual ~VolumePassword ();
@ -35,13 +33,10 @@ namespace VeraCrypt
operator BufferPtr () const { return BufferPtr (PasswordBuffer); } operator BufferPtr () const { return BufferPtr (PasswordBuffer); }
void CheckPortability () const;
byte *DataPtr () const { return PasswordBuffer; } byte *DataPtr () const { return PasswordBuffer; }
bool IsEmpty () const { return PasswordSize == 0; } bool IsEmpty () const { return PasswordSize == 0; }
size_t Size () const { return PasswordSize; } size_t Size () const { return PasswordSize; }
void Set (const byte *password, size_t size); 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); void Set (const VolumePassword &password);
TC_SERIALIZABLE (VolumePassword); TC_SERIALIZABLE (VolumePassword);
@ -51,12 +46,10 @@ namespace VeraCrypt
protected: protected:
void AllocateBuffer (); void AllocateBuffer ();
bool IsPortable () const;
SecureBuffer PasswordBuffer; SecureBuffer PasswordBuffer;
size_t PasswordSize; size_t PasswordSize;
bool Unportable;
}; };
struct PasswordException : public Exception struct PasswordException : public Exception
@ -86,6 +79,8 @@ namespace VeraCrypt
TC_EXCEPTION_NODECL (ProtectionPasswordKeyfilesIncorrect); \ TC_EXCEPTION_NODECL (ProtectionPasswordKeyfilesIncorrect); \
TC_EXCEPTION (PasswordEmpty); \ TC_EXCEPTION (PasswordEmpty); \
TC_EXCEPTION (PasswordTooLong); \ TC_EXCEPTION (PasswordTooLong); \
TC_EXCEPTION (PasswordUTF8TooLong); \
TC_EXCEPTION (PasswordUTF8Invalid); \
TC_EXCEPTION (UnportablePassword); TC_EXCEPTION (UnportablePassword);
TC_EXCEPTION_SET; TC_EXCEPTION_SET;