From 99c4031d89ce4f72e3899b3cac660082a1820a48 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 29 May 2016 01:30:53 +0200 Subject: Windows: better implementation for support of smart card PIN in command line. Supported now also on Format. --- src/Common/Dlgcode.c | 29 +++++++++++++++++++++++------ src/Common/Dlgcode.h | 1 + src/Common/Keyfiles.c | 7 +------ src/Common/Keyfiles.h | 1 - src/Common/SecurityToken.cpp | 27 ++++++--------------------- src/Common/SecurityToken.h | 7 +++---- src/Format/Tcformat.c | 17 +++++++++++++++++ src/Mount/Mount.c | 9 +++------ 8 files changed, 54 insertions(+), 44 deletions(-) diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 13a439e0..d70dfbcd 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -78,6 +78,7 @@ char *LastDialogId; wchar_t szHelpFile[TC_MAX_PATH]; wchar_t szHelpFile2[TC_MAX_PATH]; wchar_t SecurityTokenLibraryPath[TC_MAX_PATH]; +char CmdTokenPin [TC_MAX_PATH] = {0}; HFONT hFixedDigitFont = NULL; HFONT hBoldFont = NULL; @@ -329,6 +330,8 @@ typedef struct void cleanup () { + burn (&CmdTokenPin, sizeof (CmdTokenPin)); + /* Cleanup the GDI fonts */ if (hFixedFont != NULL) DeleteObject (hFixedFont); @@ -2535,6 +2538,8 @@ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine) InitOSVersionInfo(); + VirtualLock (&CmdTokenPin, sizeof (CmdTokenPin)); + InitializeCriticalSection (&csWNetCalls); LoadSystemDll (L"ntmarta.dll", &hntmartadll, TRUE, SRC_POS); @@ -10980,15 +10985,27 @@ BOOL InitSecurityTokenLibrary (HWND hwndDlg) PinRequestHandler(HWND hwnd) : m_hwnd(hwnd) {} virtual void operator() (string &str) { - HWND hParent = IsWindow (m_hwnd)? m_hwnd : GetActiveWindow(); - if (!hParent) - hParent = GetForegroundWindow (); - if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_PASSWORD), hParent, (DLGPROC) SecurityTokenPasswordDlgProc, (LPARAM) &str) == IDCANCEL) - throw UserAbort (SRC_POS); - + if (CmdTokenPin[0]) + { + str = CmdTokenPin; + } + else + { + HWND hParent = IsWindow (m_hwnd)? m_hwnd : GetActiveWindow(); + if (!hParent) + hParent = GetForegroundWindow (); + if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_PASSWORD), hParent, (DLGPROC) SecurityTokenPasswordDlgProc, (LPARAM) &str) == IDCANCEL) + throw UserAbort (SRC_POS); + } if (hCursor != NULL) SetCursor (hCursor); } + + virtual void notifyIncorrectPin () + { + // clear wrong PIN + burn (&CmdTokenPin, sizeof (CmdTokenPin)); + } }; struct WarningHandler : public SendExceptionFunctor diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 9387336e..bc818e77 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -102,6 +102,7 @@ extern char *ConfigBuffer; extern wchar_t szHelpFile[TC_MAX_PATH]; extern wchar_t szHelpFile2[TC_MAX_PATH]; extern wchar_t SecurityTokenLibraryPath[TC_MAX_PATH]; +extern char CmdTokenPin [TC_MAX_PATH]; extern HFONT hFixedDigitFont; extern HFONT hBoldFont; extern HFONT hTitleFont; diff --git a/src/Common/Keyfiles.c b/src/Common/Keyfiles.c index 5ee5bccf..14d415f0 100644 --- a/src/Common/Keyfiles.c +++ b/src/Common/Keyfiles.c @@ -237,11 +237,6 @@ close: BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, const wchar_t* volumeFileName) -{ - return KeyFilesApplyWithPin (hwndDlg, password, nullptr, firstKeyFile, volumeFileName); -} - -BOOL KeyFilesApplyWithPin (HWND hwndDlg, Password *password, char* pin, KeyFile *firstKeyFile, const wchar_t* volumeFileName) { BOOL status = TRUE; KeyFile kfSubStruct; @@ -271,7 +266,7 @@ BOOL KeyFilesApplyWithPin (HWND hwndDlg, Password *password, char* pin, KeyFile // Apply security token keyfile vector keyfileData; SecurityTokenKeyfilePath secPath (kf->FileName); - SecurityToken::GetKeyfileData (SecurityTokenKeyfile (secPath, pin), pin, keyfileData); + SecurityToken::GetKeyfileData (SecurityTokenKeyfile (secPath), keyfileData); if (keyfileData.empty()) { diff --git a/src/Common/Keyfiles.h b/src/Common/Keyfiles.h index c94f1378..a247cbc7 100644 --- a/src/Common/Keyfiles.h +++ b/src/Common/Keyfiles.h @@ -40,7 +40,6 @@ void KeyFileRemoveAll (KeyFile **firstKeyFile); KeyFile *KeyFileClone (KeyFile *keyFile); void KeyFileCloneAll (KeyFile *firstKeyFile, KeyFile **outputKeyFile); BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFilem, const wchar_t* volumeFileName); -BOOL KeyFilesApplyWithPin (HWND hwndDlg, Password *password, char* pin, KeyFile *firstKeyFilem, const wchar_t* volumeFileName); BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); BOOL KeyfilesPopupMenu (HWND hwndDlg, POINT popupPosition, KeyFilesDlgParam *dialogParam); diff --git a/src/Common/SecurityToken.cpp b/src/Common/SecurityToken.cpp index 597c6a2f..05defe5b 100644 --- a/src/Common/SecurityToken.cpp +++ b/src/Common/SecurityToken.cpp @@ -36,7 +36,7 @@ using namespace std; namespace VeraCrypt { - SecurityTokenKeyfile::SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path, char* pin) + SecurityTokenKeyfile::SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path) { wstring pathStr = path; unsigned long slotId; @@ -52,7 +52,7 @@ namespace VeraCrypt Id = pathStr.substr (keyIdPos + wstring (L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/").size()); - vector keyfiles = SecurityToken::GetAvailableKeyfiles (&SlotId, Id, pin); + vector keyfiles = SecurityToken::GetAvailableKeyfiles (&SlotId, Id); if (keyfiles.empty()) throw SecurityTokenKeyfileNotFound(); @@ -180,7 +180,7 @@ namespace VeraCrypt throw Pkcs11Exception (status); } - vector SecurityToken::GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter, const wstring keyfileIdFilter, char* pin) + vector SecurityToken::GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter, const wstring keyfileIdFilter) { bool unrecognizedTokenPresent = false; vector keyfiles; @@ -194,7 +194,7 @@ namespace VeraCrypt try { - LoginUserIfRequired (slotId, pin); + LoginUserIfRequired (slotId); token = GetTokenInfo (slotId); } catch (UserAbort &) @@ -314,12 +314,7 @@ namespace VeraCrypt void SecurityToken::GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector &keyfileData) { - GetKeyfileData (keyfile, nullptr, keyfileData); - } - - void SecurityToken::GetKeyfileData (const SecurityTokenKeyfile &keyfile, char* pin, vector &keyfileData) - { - LoginUserIfRequired (keyfile.SlotId, pin); + LoginUserIfRequired (keyfile.SlotId); GetObjectAttribute (keyfile.SlotId, keyfile.Handle, CKA_VALUE, keyfileData); } @@ -438,7 +433,7 @@ namespace VeraCrypt Sessions[slotId].UserLoggedIn = true; } - void SecurityToken::LoginUserIfRequired (CK_SLOT_ID slotId, char* cmdPin) + void SecurityToken::LoginUserIfRequired (CK_SLOT_ID slotId) { CheckLibraryStatus(); CK_RV status; @@ -479,10 +474,6 @@ namespace VeraCrypt if (status != CKR_OK) throw Pkcs11Exception (status); } - else if (cmdPin && cmdPin [0]) - { - Login (slotId, cmdPin); - } else { string pin = tokenInfo.LabelUtf8; @@ -511,12 +502,6 @@ namespace VeraCrypt } else if (error == CKR_PIN_INCORRECT && !(tokenInfo.Flags & CKF_PROTECTED_AUTHENTICATION_PATH)) { - if (cmdPin && cmdPin [0]) - { - // clear wrong PIN - size_t cmdPinLen = strlen (cmdPin); - burn (cmdPin, cmdPinLen); - } PinCallback->notifyIncorrectPin (); (*WarningCallback) (Pkcs11Exception (CKR_PIN_INCORRECT)); continue; diff --git a/src/Common/SecurityToken.h b/src/Common/SecurityToken.h index 89f60dfb..32abfcb5 100644 --- a/src/Common/SecurityToken.h +++ b/src/Common/SecurityToken.h @@ -74,7 +74,7 @@ namespace VeraCrypt struct SecurityTokenKeyfile { SecurityTokenKeyfile () : Handle(CK_INVALID_HANDLE), SlotId(CK_UNAVAILABLE_INFORMATION) { Token.SlotId = CK_UNAVAILABLE_INFORMATION; Token.Flags = 0; } - SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path, char* pin = nullptr); + SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path); operator SecurityTokenKeyfilePath () const; @@ -186,9 +186,8 @@ namespace VeraCrypt static void CloseLibrary (); static void CreateKeyfile (CK_SLOT_ID slotId, vector &keyfileData, const string &name); static void DeleteKeyfile (const SecurityTokenKeyfile &keyfile); - static vector GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter = nullptr, const wstring keyfileIdFilter = wstring(), char* pin = nullptr); + static vector GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter = nullptr, const wstring keyfileIdFilter = wstring()); static void GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector &keyfileData); - static void GetKeyfileData (const SecurityTokenKeyfile &keyfile, char* pin, vector &keyfileData); static list GetAvailableTokens (); static SecurityTokenInfo GetTokenInfo (CK_SLOT_ID slotId); #ifdef TC_WINDOWS @@ -207,7 +206,7 @@ namespace VeraCrypt static void GetObjectAttribute (CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector &attributeValue); static list GetTokenSlots (); static void Login (CK_SLOT_ID slotId, const char* pin); - static void LoginUserIfRequired (CK_SLOT_ID slotId, char* cmdPin = nullptr); + static void LoginUserIfRequired (CK_SLOT_ID slotId); static void OpenSession (CK_SLOT_ID slotId); static void CheckLibraryStatus (); diff --git a/src/Format/Tcformat.c b/src/Format/Tcformat.c index 40c17d66..fc888886 100644 --- a/src/Format/Tcformat.c +++ b/src/Format/Tcformat.c @@ -51,6 +51,7 @@ #include "Volumes.h" #include "Wipe.h" #include "Xml.h" +#include "SecurityToken.h" #include @@ -8777,6 +8778,7 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine) OptionNoIsoCheck, OptionQuit, OptionTokenLib, + OptionTokenPin, CommandResumeSysEncLogOn, CommandResumeSysEnc, CommandDecryptSysEnc, @@ -8806,6 +8808,7 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine) { OptionHistory, L"/history", L"/h", FALSE }, { OptionNoIsoCheck, L"/noisocheck", L"/n", FALSE }, { OptionTokenLib, L"/tokenlib", NULL, FALSE }, + { OptionTokenPin, L"/tokenpin", NULL, FALSE }, { OptionQuit, L"/quit", L"/q", FALSE }, { OptionEncryption, L"/encryption", NULL , FALSE }, { OptionFilesystem, L"/filesystem", NULL , FALSE }, @@ -9190,6 +9193,20 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine) break; + case OptionTokenPin: + { + wchar_t szTmp[SecurityToken::MaxPasswordLength + 1] = {0}; + if (GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp)) == HAS_ARGUMENT) + { + if (0 == WideCharToMultiByte (CP_UTF8, 0, szTmp, -1, CmdTokenPin, TC_MAX_PATH, nullptr, nullptr)) + AbortProcess ("COMMAND_LINE_ERROR"); + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + + break; + case OptionQuit: { // Used to indicate non-install elevation diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 62ac5e0f..82fa4134 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -129,7 +129,6 @@ int nSelectedDriveIndex = -1; /* Item number of selected drive */ int cmdUnmountDrive = -2; /* Volume drive letter to unmount (-1 = all) */ Password VolumePassword; /* Password used for mounting volumes */ Password CmdVolumePassword; /* Password passed from command line */ -char CmdTokenPin [SecurityToken::MaxPasswordLength + 1] = {0}; int VolumePkcs5 = 0; int CmdVolumePkcs5 = 0; int VolumePim = -1; @@ -238,7 +237,6 @@ static void localcleanup (void) burn (&mountOptions, sizeof (mountOptions)); burn (&defaultMountOptions, sizeof (defaultMountOptions)); burn (szFileName, sizeof(szFileName)); - burn (&CmdTokenPin, sizeof (CmdTokenPin)); /* Cleanup common code resources */ cleanup (); @@ -6513,7 +6511,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa BOOL reportBadPasswd = CmdVolumePassword.Length > 0; if (FirstCmdKeyFile) - KeyFilesApplyWithPin (hwndDlg, &CmdVolumePassword, CmdTokenPin, FirstCmdKeyFile, szFileName); + KeyFilesApply (hwndDlg, &CmdVolumePassword, FirstCmdKeyFile, szFileName); mounted = MountVolume (hwndDlg, szDriveLetter[0] - L'A', szFileName, &CmdVolumePassword, EffectiveVolumePkcs5, CmdVolumePim, EffectiveVolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, @@ -6558,7 +6556,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa WaitCursor (); if (KeyFilesEnable && FirstKeyFile) - KeyFilesApplyWithPin (hwndDlg, &VolumePassword, CmdTokenPin, FirstKeyFile, szFileName); + KeyFilesApply (hwndDlg, &VolumePassword, FirstKeyFile, szFileName); mounted = MountVolume (hwndDlg, szDriveLetter[0] - L'A', szFileName, &VolumePassword, VolumePkcs5, VolumePim, VolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, FALSE, TRUE); @@ -8695,7 +8693,7 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine) wchar_t szTmp[SecurityToken::MaxPasswordLength + 1] = {0}; if (GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp)) == HAS_ARGUMENT) { - if (0 == WideCharToMultiByte (CP_UTF8, 0, szTmp, -1, CmdTokenPin, array_capacity (CmdTokenPin), nullptr, nullptr)) + if (0 == WideCharToMultiByte (CP_UTF8, 0, szTmp, -1, CmdTokenPin, TC_MAX_PATH, nullptr, nullptr)) AbortProcess ("COMMAND_LINE_ERROR"); } else @@ -8924,7 +8922,6 @@ int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpsz VirtualLock (&mountOptions, sizeof (mountOptions)); VirtualLock (&defaultMountOptions, sizeof (defaultMountOptions)); VirtualLock (&szFileName, sizeof(szFileName)); - VirtualLock (&CmdTokenPin, sizeof (CmdTokenPin)); DetectX86Features (); -- cgit v1.2.3