diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2016-03-23 00:14:07 +0100 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2016-03-24 01:36:03 +0100 |
commit | ece26c74815c431b0c489a24292e7834181463a7 (patch) | |
tree | c09e4679304489e0c6a2356e26a83de29f0ac438 | |
parent | 6738cba617cf8cbb8a63db9e01193717a1dee2e4 (diff) | |
download | VeraCrypt-ece26c74815c431b0c489a24292e7834181463a7.tar.gz VeraCrypt-ece26c74815c431b0c489a24292e7834181463a7.zip |
Windows: Implement passing smart card PIN as command line argument (/tokenpin switch) when explicitly mounting a volume.
-rw-r--r-- | src/Common/Common.rc | 8 | ||||
-rw-r--r-- | src/Common/Keyfiles.c | 7 | ||||
-rw-r--r-- | src/Common/Keyfiles.h | 1 | ||||
-rw-r--r-- | src/Common/SecurityToken.cpp | 36 | ||||
-rw-r--r-- | src/Common/SecurityToken.h | 9 | ||||
-rw-r--r-- | src/Mount/Mount.c | 23 |
6 files changed, 63 insertions, 21 deletions
diff --git a/src/Common/Common.rc b/src/Common/Common.rc index 8fa6c5ab..1abd1bbd 100644 --- a/src/Common/Common.rc +++ b/src/Common/Common.rc @@ -45,14 +45,14 @@ BEGIN CONTROL IDB_TEXTUAL_LOGO_96DPI,IDC_TEXTUAL_LOGO_IMG,"Static",SS_BITMAP,12,26,157,16
END
-IDD_COMMANDHELP_DLG DIALOGEX 0, 0, 249, 274
+IDD_COMMANDHELP_DLG DIALOGEX 0, 0, 249, 289
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Command Line Help"
CLASS "VeraCryptCustomDlg"
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
- DEFPUSHBUTTON "OK",IDOK,93,252,59,14
- LTEXT "",IDC_COMMANDHELP_TEXT,20,10,208,241
+ DEFPUSHBUTTON "OK",IDOK,93,267,59,14
+ LTEXT "",IDC_COMMANDHELP_TEXT,20,7,208,256
END
IDD_RAWDEVICES_DLG DIALOGEX 0, 0, 305, 209
@@ -345,7 +345,7 @@ BEGIN IDD_COMMANDHELP_DLG, DIALOG
BEGIN
- BOTTOMMARGIN, 266
+ BOTTOMMARGIN, 281
END
IDD_RAWDEVICES_DLG, DIALOG
diff --git a/src/Common/Keyfiles.c b/src/Common/Keyfiles.c index 366d65ee..8b3825d5 100644 --- a/src/Common/Keyfiles.c +++ b/src/Common/Keyfiles.c @@ -238,6 +238,11 @@ 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;
KeyFile *kf;
@@ -266,7 +271,7 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con // Apply security token keyfile
vector <byte> keyfileData;
SecurityTokenKeyfilePath secPath (kf->FileName);
- SecurityToken::GetKeyfileData (SecurityTokenKeyfile (secPath), keyfileData);
+ SecurityToken::GetKeyfileData (SecurityTokenKeyfile (secPath, pin), pin, keyfileData);
if (keyfileData.empty())
{
diff --git a/src/Common/Keyfiles.h b/src/Common/Keyfiles.h index 10b9b77e..899cd9e4 100644 --- a/src/Common/Keyfiles.h +++ b/src/Common/Keyfiles.h @@ -40,6 +40,7 @@ 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 fcabce88..db80ff0d 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)
+ SecurityTokenKeyfile::SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path, char* pin)
{
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 <SecurityTokenKeyfile> keyfiles = SecurityToken::GetAvailableKeyfiles (&SlotId, Id);
+ vector <SecurityTokenKeyfile> keyfiles = SecurityToken::GetAvailableKeyfiles (&SlotId, Id, pin);
if (keyfiles.empty())
throw SecurityTokenKeyfileNotFound();
@@ -180,7 +180,7 @@ namespace VeraCrypt throw Pkcs11Exception (status);
}
- vector <SecurityTokenKeyfile> SecurityToken::GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter, const wstring keyfileIdFilter)
+ vector <SecurityTokenKeyfile> SecurityToken::GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter, const wstring keyfileIdFilter, char* pin)
{
bool unrecognizedTokenPresent = false;
vector <SecurityTokenKeyfile> keyfiles;
@@ -194,7 +194,7 @@ namespace VeraCrypt try
{
- LoginUserIfRequired (slotId);
+ LoginUserIfRequired (slotId, pin);
token = GetTokenInfo (slotId);
}
catch (UserAbort &)
@@ -314,7 +314,12 @@ namespace VeraCrypt void SecurityToken::GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector <byte> &keyfileData)
{
- LoginUserIfRequired (keyfile.SlotId);
+ GetKeyfileData (keyfile, nullptr, keyfileData);
+ }
+
+ void SecurityToken::GetKeyfileData (const SecurityTokenKeyfile &keyfile, char* pin, vector <byte> &keyfileData)
+ {
+ LoginUserIfRequired (keyfile.SlotId, pin);
GetObjectAttribute (keyfile.SlotId, keyfile.Handle, CKA_VALUE, keyfileData);
}
@@ -417,22 +422,23 @@ namespace VeraCrypt return securityTokenKeyfilePath.find (TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX) == 0;
}
- void SecurityToken::Login (CK_SLOT_ID slotId, const string &pin)
+ void SecurityToken::Login (CK_SLOT_ID slotId, const char* pin)
{
if (Sessions.find (slotId) == Sessions.end())
OpenSession (slotId);
else if (Sessions[slotId].UserLoggedIn)
return;
- CK_RV status = Pkcs11Functions->C_Login (Sessions[slotId].Handle, CKU_USER, (CK_CHAR_PTR) pin.c_str(), (CK_ULONG) pin.size());
+ size_t pinLen = pin? strlen (pin) : 0;
+ CK_RV status = Pkcs11Functions->C_Login (Sessions[slotId].Handle, CKU_USER, (CK_CHAR_PTR) pin, (CK_ULONG) pinLen);
if (status != CKR_OK)
throw Pkcs11Exception (status);
Sessions[slotId].UserLoggedIn = true;
}
-
- void SecurityToken::LoginUserIfRequired (CK_SLOT_ID slotId)
+
+ void SecurityToken::LoginUserIfRequired (CK_SLOT_ID slotId, char* cmdPin)
{
CheckLibraryStatus();
CK_RV status;
@@ -473,6 +479,10 @@ namespace VeraCrypt if (status != CKR_OK)
throw Pkcs11Exception (status);
}
+ else if (cmdPin && cmdPin [0])
+ {
+ Login (slotId, cmdPin);
+ }
else
{
string pin = tokenInfo.LabelUtf8;
@@ -486,7 +496,7 @@ namespace VeraCrypt finally_do_arg (string*, &pin, { burn ((void *) finally_arg->c_str(), finally_arg->size()); });
(*PinCallback) (pin);
- Login (slotId, pin);
+ Login (slotId, pin.c_str());
}
Sessions[slotId].UserLoggedIn = true;
@@ -501,6 +511,12 @@ 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);
+ }
(*WarningCallback) (Pkcs11Exception (CKR_PIN_INCORRECT));
continue;
}
diff --git a/src/Common/SecurityToken.h b/src/Common/SecurityToken.h index c282365e..9c6c47cf 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);
+ SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path, char* pin = nullptr);
operator SecurityTokenKeyfilePath () const;
@@ -185,8 +185,9 @@ namespace VeraCrypt static void CloseLibrary ();
static void CreateKeyfile (CK_SLOT_ID slotId, vector <byte> &keyfileData, const string &name);
static void DeleteKeyfile (const SecurityTokenKeyfile &keyfile);
- static vector <SecurityTokenKeyfile> GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter = nullptr, const wstring keyfileIdFilter = wstring());
+ static vector <SecurityTokenKeyfile> GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter = nullptr, const wstring keyfileIdFilter = wstring(), char* pin = nullptr);
static void GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector <byte> &keyfileData);
+ static void GetKeyfileData (const SecurityTokenKeyfile &keyfile, char* pin, vector <byte> &keyfileData);
static list <SecurityTokenInfo> GetAvailableTokens ();
static SecurityTokenInfo GetTokenInfo (CK_SLOT_ID slotId);
#ifdef TC_WINDOWS
@@ -204,8 +205,8 @@ namespace VeraCrypt static vector <CK_OBJECT_HANDLE> GetObjects (CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass);
static void GetObjectAttribute (CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector <byte> &attributeValue);
static list <CK_SLOT_ID> GetTokenSlots ();
- static void Login (CK_SLOT_ID slotId, const string &pin);
- static void LoginUserIfRequired (CK_SLOT_ID slotId);
+ static void Login (CK_SLOT_ID slotId, const char* pin);
+ static void LoginUserIfRequired (CK_SLOT_ID slotId, char* cmdPin = nullptr);
static void OpenSession (CK_SLOT_ID slotId);
static void CheckLibraryStatus ();
diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 6bb02d79..fbf631f8 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -129,6 +129,7 @@ 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;
@@ -237,6 +238,7 @@ 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 ();
@@ -6334,7 +6336,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa BOOL reportBadPasswd = CmdVolumePassword.Length > 0;
if (FirstCmdKeyFile)
- KeyFilesApply (hwndDlg, &CmdVolumePassword, FirstCmdKeyFile, szFileName);
+ KeyFilesApplyWithPin (hwndDlg, &CmdVolumePassword, CmdTokenPin, FirstCmdKeyFile, szFileName);
mounted = MountVolume (hwndDlg, szDriveLetter[0] - L'A',
szFileName, &CmdVolumePassword, EffectiveVolumePkcs5, CmdVolumePim, EffectiveVolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount,
@@ -6379,7 +6381,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa WaitCursor ();
if (KeyFilesEnable && FirstKeyFile)
- KeyFilesApply (hwndDlg, &VolumePassword, FirstKeyFile, szFileName);
+ KeyFilesApplyWithPin (hwndDlg, &VolumePassword, CmdTokenPin, FirstKeyFile, szFileName);
mounted = MountVolume (hwndDlg, szDriveLetter[0] - L'A', szFileName, &VolumePassword, VolumePkcs5, VolumePim, VolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, FALSE, TRUE);
@@ -8136,6 +8138,7 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine) OptionQuit,
OptionSilent,
OptionTokenLib,
+ OptionTokenPin,
OptionVolume,
CommandWipeCache,
OptionPkcs5,
@@ -8163,6 +8166,7 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine) { OptionQuit, L"/quit", L"/q", FALSE },
{ OptionSilent, L"/silent", L"/s", FALSE },
{ OptionTokenLib, L"/tokenlib", NULL, FALSE },
+ { OptionTokenPin, L"/tokenpin", NULL, FALSE },
{ OptionTrueCryptMode, L"/truecrypt", L"/tc", FALSE },
{ OptionVolume, L"/volume", L"/v", FALSE },
{ CommandWipeCache, L"/wipecache", L"/w", FALSE },
@@ -8449,6 +8453,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, array_capacity (CmdTokenPin), nullptr, nullptr))
+ AbortProcess ("COMMAND_LINE_ERROR");
+ }
+ else
+ AbortProcess ("COMMAND_LINE_ERROR");
+ }
+
+ break;
+
case CommandWipeCache:
bWipe = TRUE;
break;
@@ -8667,6 +8685,7 @@ 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 ();
|