From 502ab9112a7624dbd7c1c90c2e12ed45512b8b3c Mon Sep 17 00:00:00 2001 From: mmauv <99472743+mmauv@users.noreply.github.com> Date: Wed, 28 Jun 2023 22:51:43 +0200 Subject: Add EMV functionality (#1080) * Add basic strcture needed for EMV implementation * Add demo EMV functionality with C code pasted in a very dirty and unsafe way. NOT FINAL * Refactor IccExtractor Structure * Fix Makefile * fix include file * move global variables from h to c * revert to memcpy * fix icc data recovery functions * Add EMV functionalities on windows * Make EMVToken structures like SecurityToken * Define constants instead of hard coded values * Token structures created with inheritance * refactor TokenKeyfile to use inherit. + polymor. * add Token.h + Token.cpp in modules in VS2010 * Add a comment at each use of SecurityToken class or objects * SecurityTokenKeyfilesDialog preparation * Implemennt GetAvailableTokens in Token class on windows * merge * up (patching for Windows) * foreach Token.cpp corrected * Display EMV keyfiles on first window in graphic interface * Add token to Windows UI * EMVToken selection on OKButton on Linux * Keyfile.cpp optimization * Move getKeyfileData in the token class * EMV::Token GetAvailableKeyfiles() base * Move getKeyfileData in the token class on unix * Remove test comments * Warnings resolved * RemoveeSecurityTokenLibraryNotInitialized exception if at least one emv token is detected * Adding new files * Remove old files and add the new version to the windows project * Change make_shared to shared_ptr constructor * IccExtractor integration working on linux * Throwing card not EMV execption * catch error when not EMV type in EMVToken::GetAvailableKeyfiles * Change types to compile on windows * list all keyfiles, security keyfiles and emv keyfiles in command line * Change type to be coherent and remove old todo comments * Remove todo comments * Change indentation and resolve a bug from previous commit * Use polymorphism for GetKeyfileData and add export option for EMVTokens on Linux * Linux : Allow to export EMV Tokens in command lines, Windows : Disable the delete button when EMV Keyfiles are selected * Remove SlotId from TokenInfo as it is already in Token * Correct errors on Linux * Disable delete option if one EMV Token is selected on Linux * Fix bug enabling delete button if nothing is selected * emv data used as reference then burnt * use of normal files in linux corrected * help updated * help updated for export functionnality * option EMV added to graphic interface but not yet working * Bug fix : Allow to use multiple EMV on windows * EMV Option added to UserPreferences * EMV Option working for Linux * EMV option added to Windows (not working yet) * [NOT TESTED] EMV option for Windows * Working EMV option on Windows * EMV Option for data extraction working for volume creation * EMV Option for data extraction working for Mount * EMV Option for data extraction working for mounting favorites volumes * EMV Option for extraction working for Changing volume password, Set Derivation Key Algorithm and Add or remove keyfile from volume * Windows : re-checking EMV Option when getting data * Removing error catches in the IccDataExtractor classe (It only throws error now). Changing GetPan signature to resemble the other functions signatures more * Changing EMV errors - Only throwing ICCExtractionException from outside of the ICC module. - Catching all TLVExceptions and PCSCExceptions to throw the right ICCExtractionException - Deleting APDU exceptions. * First version of the documentation * Adding function pointers for winscard library (but it crashes VeraCrypt) * Debugging function pointers * The import of the library on windows work as expected now * Reverting EMVToken.cpp changes used to test to library import * Searching for the System32 path instead of hard codding it * Fixing the bug were VeraCrypt crashes if there is no readers when "add Token files" is clicked * Winscard library not initialized in object constructor anymore to delay it after EMVOption check * Remove winscard lib from windows dependencies * Properly displaying errors * Adding a dot in Language.xml * Catching TLVException * Removing unused code * Remove unusefull comments * Trying to fix 0x1f error * Update IccDataExtractor.cpp * Delete History.xml * Fix get data without get pan * Cleanup code * changes for linux compilation but linking not working * error handling for linux * erasing emv data * Burn PAN * Burn PAN from memory * Uncomment selfcheck before merging master * burn corrected * EMV errors handling for Linux * EMV working for Linux CLI * Doc : Winscard Linux package and VeraCrypt versions --------- Co-authored-by: doriandu45 Co-authored-by: red4game Co-authored-by: Brice.Namy Co-authored-by: vocthor Co-authored-by: vocthor <67202139+vocthor@users.noreply.github.com> Co-authored-by: Andrei COCAN Co-authored-by: AndreiCocan <95496161+AndreiCocan@users.noreply.github.com> Co-authored-by: francoisLEROUX --- src/Common/Dlgcode.c | 58 +- src/Common/Dlgcode.h | 1 + src/Common/EMVToken.cpp | 121 ++++ src/Common/EMVToken.h | 50 ++ src/Common/IccDataExtractor.cpp | 777 +++++++++++++++++++++++++ src/Common/IccDataExtractor.h | 231 ++++++++ src/Common/Keyfiles.c | 15 +- src/Common/Language.xml | 8 + src/Common/SecurityToken.cpp | 522 +++++++++-------- src/Common/SecurityToken.h | 126 ++-- src/Common/TLVParser.cpp | 179 ++++++ src/Common/TLVParser.h | 80 +++ src/Common/Token.cpp | 82 +++ src/Common/Token.h | 57 ++ src/Core/Core.h | 19 +- src/Core/CoreBase.cpp | 18 +- src/Core/CoreBase.h | 8 +- src/Core/MountOptions.h | 1 + src/Core/Unix/CoreServiceProxy.h | 6 +- src/Core/Unix/CoreUnix.cpp | 1 + src/Core/VolumeCreator.cpp | 2 +- src/Core/VolumeCreator.h | 1 + src/ExpandVolume/ExpandVolume.vcxproj | 16 +- src/ExpandVolume/ExpandVolume.vcxproj.filters | 24 + src/ExpandVolume/WinMain.cpp | 1 + src/Format/Format.vcxproj | 20 +- src/Format/Format.vcxproj.filters | 24 + src/Format/Tcformat.c | 4 +- src/Main/CommandLineInterface.cpp | 16 +- src/Main/CommandLineInterface.h | 4 +- src/Main/Forms/ChangePasswordDialog.cpp | 2 +- src/Main/Forms/Forms.cpp | 13 +- src/Main/Forms/Forms.h | 1 + src/Main/Forms/KeyfilesPanel.cpp | 2 +- src/Main/Forms/MainFrame.cpp | 3 +- src/Main/Forms/MountOptionsDialog.cpp | 1 + src/Main/Forms/PreferencesDialog.cpp | 1 + src/Main/Forms/SecurityTokenKeyfilesDialog.cpp | 53 +- src/Main/Forms/SecurityTokenKeyfilesDialog.h | 8 +- src/Main/Forms/VolumeCreationWizard.cpp | 8 +- src/Main/Forms/VolumePasswordPanel.cpp | 2 +- src/Main/Forms/WaitDialog.cpp | 9 + src/Main/GraphicUserInterface.cpp | 27 +- src/Main/GraphicUserInterface.h | 4 +- src/Main/TextUserInterface.cpp | 62 +- src/Main/TextUserInterface.h | 4 +- src/Main/UserInterface.cpp | 67 ++- src/Main/UserInterface.h | 2 + src/Main/UserPreferences.cpp | 2 + src/Main/UserPreferences.h | 2 + src/Makefile | 4 + src/Mount/Mount.c | 27 +- src/Mount/Mount.rc | 8 +- src/Mount/Mount.vcxproj | 16 +- src/Mount/Mount.vcxproj.filters | 24 + src/Mount/Resource.h | 2 + src/Volume/Keyfile.cpp | 84 ++- src/Volume/Keyfile.h | 4 +- src/Volume/Volume.cpp | 9 +- src/Volume/Volume.h | 4 +- src/Volume/Volume.make | 4 + 61 files changed, 2396 insertions(+), 535 deletions(-) create mode 100644 src/Common/EMVToken.cpp create mode 100644 src/Common/EMVToken.h create mode 100644 src/Common/IccDataExtractor.cpp create mode 100644 src/Common/IccDataExtractor.h create mode 100644 src/Common/TLVParser.cpp create mode 100644 src/Common/TLVParser.h create mode 100644 src/Common/Token.cpp create mode 100644 src/Common/Token.h (limited to 'src') diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index e1170d84..dfcc3d03 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -207,6 +207,7 @@ BOOL LastMountedVolumeDirty; BOOL MountVolumesAsSystemFavorite = FALSE; BOOL FavoriteMountOnArrivalInProgress = FALSE; BOOL MultipleMountOperationInProgress = FALSE; +BOOL ActivateEMVOption = FALSE; volatile BOOL NeedPeriodicDeviceListUpdate = FALSE; BOOL DisablePeriodicDeviceListUpdate = FALSE; @@ -12206,11 +12207,11 @@ static BOOL CALLBACK NewSecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPA WaitCursor(); finally_do ({ NormalCursor(); }); - list tokens; + list > tokens; try { - tokens = SecurityToken::GetAvailableTokens(); + tokens = Token::GetAvailableTokens(); } catch (Exception &e) { @@ -12224,12 +12225,12 @@ static BOOL CALLBACK NewSecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPA return 1; } - foreach (const SecurityTokenInfo &token, tokens) + foreach (const shared_ptr token, tokens) { wstringstream tokenLabel; - tokenLabel << L"[" << token.SlotId << L"] " << token.Label; + tokenLabel << L"[" << token->SlotId << L"] " << token->Label; - AddComboPair (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), tokenLabel.str().c_str(), token.SlotId); + AddComboPair (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), tokenLabel.str().c_str(), token->SlotId); } ComboBox_SetCurSel (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), 0); @@ -12283,7 +12284,7 @@ static BOOL CALLBACK NewSecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPA } -static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector &keyfiles) +static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector > &keyfiles) { HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST); LVITEMW lvItem; @@ -12291,18 +12292,18 @@ static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector keyfile, keyfiles) { memset (&lvItem, 0, sizeof(lvItem)); lvItem.mask = LVIF_TEXT; lvItem.iItem = line++; wstringstream s; - s << keyfile.SlotId; + s << keyfile->Token->SlotId; ListItemAdd (tokenListControl, lvItem.iItem, (wchar_t *) s.str().c_str()); - ListSubItemSet (tokenListControl, lvItem.iItem, 1, (wchar_t *) keyfile.Token.Label.c_str()); - ListSubItemSet (tokenListControl, lvItem.iItem, 2, (wchar_t *) keyfile.Id.c_str()); + ListSubItemSet (tokenListControl, lvItem.iItem, 1, (wchar_t *) keyfile->Token->Label.c_str()); + ListSubItemSet (tokenListControl, lvItem.iItem, 2, (wchar_t *) keyfile->Id.c_str()); } BOOL selected = (ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST), -1, LVIS_SELECTED) != -1); @@ -12311,10 +12312,10 @@ static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector SecurityTokenKeyfileDlgGetSelected (HWND hwndDlg, const vector &keyfiles) +static list > SecurityTokenKeyfileDlgGetSelected (HWND hwndDlg, const vector > &keyfiles) { HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST); - list selectedKeyfiles; + list > selectedKeyfiles; int itemId = -1; while ((itemId = ListView_GetNextItem (tokenListControl, itemId, LVIS_SELECTED)) != -1) @@ -12328,8 +12329,8 @@ static list SecurityTokenKeyfileDlgGetSelected (HWND hwnd BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - static list *selectedTokenKeyfiles; - static vector keyfiles; + static list *selectedTokenKeyfiles; + static vector > keyfiles; WORD lw = LOWORD (wParam); @@ -12337,7 +12338,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam { case WM_INITDIALOG: { - selectedTokenKeyfiles = (list *) lParam; + selectedTokenKeyfiles = (list *) lParam; LVCOLUMNW LvCol; HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST); @@ -12372,7 +12373,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam WaitCursor(); finally_do ({ NormalCursor(); }); - keyfiles = SecurityToken::GetAvailableKeyfiles(); + keyfiles = Token::GetAvailableKeyfiles(ActivateEMVOption); } catch (UserAbort&) { @@ -12400,9 +12401,9 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam { if (selectedTokenKeyfiles) { - foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles)) + foreach (const shared_ptr &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles)) { - selectedTokenKeyfiles->push_back (SecurityTokenKeyfilePath (keyfile)); + selectedTokenKeyfiles->push_back (TokenKeyfilePath (*keyfile)); } } @@ -12413,8 +12414,15 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam if (msg == WM_NOTIFY && ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) { BOOL selected = (ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST), -1, LVIS_SELECTED) != -1); + BOOL deletable = selected; + foreach (const shared_ptr &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles)) + { + if( ! keyfile->Token->isEditable()){ + deletable = false; + } + } EnableWindow (GetDlgItem (hwndDlg, IDC_EXPORT), selected); - EnableWindow (GetDlgItem (hwndDlg, IDC_DELETE), selected); + EnableWindow (GetDlgItem (hwndDlg, IDC_DELETE), deletable); return 1; } @@ -12461,7 +12469,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam SecurityToken::CreateKeyfile (newParams.SlotId, keyfileDataVector, newParams.Name); - keyfiles = SecurityToken::GetAvailableKeyfiles(); + keyfiles = Token::GetAvailableKeyfiles(ActivateEMVOption); SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles); } catch (Exception &e) @@ -12489,7 +12497,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam { try { - foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles)) + foreach (const shared_ptr &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles)) { wchar_t keyfilePath[TC_MAX_PATH]; @@ -12502,7 +12510,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam vector keyfileData; - SecurityToken::GetKeyfileData (keyfile, keyfileData); + keyfile->GetKeyfileData (keyfileData); if (keyfileData.empty()) { @@ -12538,12 +12546,12 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam WaitCursor(); finally_do ({ NormalCursor(); }); - foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles)) + foreach (const shared_ptr keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles)) { - SecurityToken::DeleteKeyfile (keyfile); + SecurityToken::DeleteKeyfile (dynamic_cast(*keyfile.get())); } - keyfiles = SecurityToken::GetAvailableKeyfiles(); + keyfiles = Token::GetAvailableKeyfiles(ActivateEMVOption); SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles); } catch (Exception &e) diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 362b2d6d..2004eb2a 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -166,6 +166,7 @@ extern BOOL LastMountedVolumeDirty; extern BOOL MountVolumesAsSystemFavorite; extern BOOL FavoriteMountOnArrivalInProgress; extern BOOL MultipleMountOperationInProgress; +extern BOOL ActivateEMVOption; extern volatile BOOL NeedPeriodicDeviceListUpdate; extern BOOL DisablePeriodicDeviceListUpdate; diff --git a/src/Common/EMVToken.cpp b/src/Common/EMVToken.cpp new file mode 100644 index 00000000..aac59a6a --- /dev/null +++ b/src/Common/EMVToken.cpp @@ -0,0 +1,121 @@ +#include "EMVToken.h" + +#include "Platform/Finally.h" +#include "Platform/ForEach.h" +#include +#include + + + +#if !defined(TC_WINDOWS) || defined(TC_PROTOTYPE) +#include "Platform/SerializerFactory.h" +#include "Platform/StringConverter.h" +#include "Platform/SystemException.h" +#else +#include "Dictionary.h" +#include "Language.h" +#endif + + +using namespace std; + +namespace VeraCrypt +{ + + IccDataExtractor EMVToken::extractor; + + EMVTokenInfo::~EMVTokenInfo() + { + burn(&Label,Label.size()); + } + + EMVTokenKeyfile::EMVTokenKeyfile(const TokenKeyfilePath& path) + { + Id = EMV_CARDS_LABEL; + Token = shared_ptr(new EMVTokenInfo()); + wstring pathStr = path; + unsigned long slotId; + + if (swscanf(pathStr.c_str(), TC_EMV_TOKEN_KEYFILE_URL_PREFIX TC_EMV_TOKEN_KEYFILE_URL_SLOT L"/%lu", &slotId) != 1) + throw InvalidEMVPath(); + + Token->SlotId = slotId; + } + + EMVTokenKeyfile::operator TokenKeyfilePath () const + { + wstringstream path; + path << TC_EMV_TOKEN_KEYFILE_URL_PREFIX TC_EMV_TOKEN_KEYFILE_URL_SLOT L"/" << Token->SlotId; + return path.str(); + } + + void EMVTokenKeyfile::GetKeyfileData(vector & keyfileData) const + { + #ifdef TC_WINDOWS + EMVToken::extractor.InitLibrary(); + #endif + + EMVToken::extractor.GetReaders(); + EMVToken::extractor.GettingAllCerts(Token->SlotId, keyfileData); + } + + bool EMVToken::IsKeyfilePathValid(const wstring& emvTokenKeyfilePath) + { + return emvTokenKeyfilePath.find(TC_EMV_TOKEN_KEYFILE_URL_PREFIX) == 0; + } + + vector EMVToken::GetAvailableKeyfiles(unsigned long int* slotIdFilter, const wstring keyfileIdFilter) { + #ifdef TC_WINDOWS + EMVToken::extractor.InitLibrary(); + #endif + + vector keyfiles; + unsigned long int nb = 0; + + nb = EMVToken::extractor.GetReaders(); + + + for(unsigned long int slotId = 0; slotIdSlotId = slotId; + keyfile.Token = shared_ptr(new EMVTokenInfo(token)); + + keyfiles.push_back(keyfile); + + if (!keyfileIdFilter.empty()) + break; + } + + return keyfiles; + + } + + + EMVTokenInfo EMVToken::GetTokenInfo(unsigned long int slotId) { + EMVTokenInfo token; + token.SlotId = slotId; + //card numbers extraction + std::string pan; + EMVToken::extractor.GettingPAN(slotId, pan); + token.Label = L"EMV card **** "; + token.Label += wstring (pan.begin(), pan.end()); + burn(&pan[0],pan.size()); + return token; + } + +} diff --git a/src/Common/EMVToken.h b/src/Common/EMVToken.h new file mode 100644 index 00000000..1d84ec28 --- /dev/null +++ b/src/Common/EMVToken.h @@ -0,0 +1,50 @@ +#ifndef TC_HEADER_Common_EMVToken +#define TC_HEADER_Common_EMVToken + +#define TC_EMV_TOKEN_KEYFILE_URL_PREFIX L"emv://" +#define TC_EMV_TOKEN_KEYFILE_URL_SLOT L"slot" + +#define EMV_CARDS_LABEL L"EMV Certificates" + +#include "Platform/PlatformBase.h" +#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE) +# include "Exception.h" +#else +# include "Platform/Exception.h" +#endif + +#include "Token.h" +#include "IccDataExtractor.h" + +namespace VeraCrypt { + + struct EMVTokenInfo: TokenInfo + { + virtual ~EMVTokenInfo(); + virtual BOOL isEditable() const {return false;} + }; + + struct EMVTokenKeyfile: TokenKeyfile + { + EMVTokenKeyfile(){Id = EMV_CARDS_LABEL; Token = shared_ptr(new EMVTokenInfo());}; + EMVTokenKeyfile(const TokenKeyfilePath& path); + + virtual operator TokenKeyfilePath () const; + virtual void GetKeyfileData(vector & keyfileData) const; + + }; + + class EMVToken { + private: + static IccDataExtractor extractor; + public: + static bool IsKeyfilePathValid(const wstring& emvTokenKeyfilePath); + static vector GetAvailableKeyfiles(unsigned long int* slotIdFilter = nullptr, const wstring keyfileIdFilter = wstring()); + static EMVTokenInfo GetTokenInfo(unsigned long int slotId); + + friend void EMVTokenKeyfile::GetKeyfileData(vector & keyfileData) const; + + }; +} + +#endif diff --git a/src/Common/IccDataExtractor.cpp b/src/Common/IccDataExtractor.cpp new file mode 100644 index 00000000..d98bc360 --- /dev/null +++ b/src/Common/IccDataExtractor.cpp @@ -0,0 +1,777 @@ +// +// Created by bshp on 1/14/23. +// + +#include "IccDataExtractor.h" + +#if !defined (TC_WINDOWS) || defined (TC_PROTOTYPE) +# include "Platform/SerializerFactory.h" +# include "Platform/StringConverter.h" +# include "Platform/SystemException.h" +#else +# include "Dictionary.h" +# include "Language.h" +#endif + +#include "Tcdefs.h" + +namespace VeraCrypt +{ + + + #ifdef TC_WINDOWS + bool VeraCrypt::IccDataExtractor::Initialized; + #endif + //using namespace std; + const BYTE IccDataExtractor::SELECT_MASTERCARD[] = {00, 0xA4, 0x04, 00, 0x07, 0xA0, 00, 00, 00, 0x04, 0x10, 0x10}; + const BYTE IccDataExtractor::SELECT_VISA[] = {00, 0xA4, 0x04, 00, 0x07, 0xA0, 00, 00, 00, 0x03, 0x10, 0x10}; + const BYTE IccDataExtractor::SELECT_AMEX[] = {00, 0xA4, 0x04, 00, 0x07, 0xA0, 00, 00, 00, 00, 0x25, 0x10}; + const BYTE * IccDataExtractor::SELECT_TYPES[]={SELECT_MASTERCARD, SELECT_VISA, SELECT_AMEX}; + + IccDataExtractor::IccDataExtractor(){} + + IccDataExtractor::~IccDataExtractor(){ + /* Disconnect card if connected */ + if(hCard){ + #ifdef TC_WINDOWS + WSCardDisconnect(hContext,hCard); + #else + SCardDisconnect(hContext,hCard); + #endif + } + /* Release memory that has been returned from the resource manager using the SCARD_AUTOALLOCATE length + * designator*/ + if (mszReaders){ + #ifdef TC_WINDOWS + WSCardFreeMemory(hContext, mszReaders); + #else + SCardFreeMemory(hContext, mszReaders); + #endif + } + + /* Closing the established resource manager context freeing any resources allocated under that context + * including SCARDHANDLE objects and memory allocated using the SCARD_AUTOALLOCATE length designator*/ + if(hContext){ + #ifdef TC_WINDOWS + WSCardReleaseContext(hContext); + #else + SCardReleaseContext(hContext); + #endif + } + + /* Freeing winscard library */ + #ifdef TC_WINDOWS + FreeLibrary(WinscardLibraryHandle); + #endif + } + + #ifdef TC_WINDOWS + void IccDataExtractor::InitLibrary(){ + + if(Initialized) return; + + /* Getting the System32 directory */ + char sysDir[MAX_PATH-20]; + GetSystemDirectoryA(sysDir, MAX_PATH); + + /* Getting the winscard dll path directory */ + char winscardPath[MAX_PATH]; + sprintf_s(winscardPath, "%s\\Winscard.dll", sysDir); + + /* Loading the winscard dll from System32 */ + WinscardLibraryHandle = LoadLibraryA(winscardPath); + throw_sys_if(!WinscardLibraryHandle); + + /* Fetching the functions pointers from the dll */ + WSCardEstablishContext = (SCardEstablishContextPtr) GetProcAddress(WinscardLibraryHandle,"SCardEstablishContext"); + if(!WSCardEstablishContext) throw WinscardLibraryNotInitialized(); + + WSCardReleaseContext= (SCardReleaseContextPtr) GetProcAddress(WinscardLibraryHandle,"SCardReleaseContext"); + if(!WSCardReleaseContext) throw WinscardLibraryNotInitialized(); + + WSCardConnectA = (SCardConnectAPtr) GetProcAddress(WinscardLibraryHandle,"SCardConnectA"); + if(!WSCardConnectA) throw WinscardLibraryNotInitialized(); + + WSCardDisconnect = (SCardDisconnectPtr) GetProcAddress(WinscardLibraryHandle,"SCardDisconnect"); + if(!WSCardDisconnect) throw WinscardLibraryNotInitialized(); + + WSCardFreeMemory = ( SCardFreeMemoryPtr) GetProcAddress(WinscardLibraryHandle,"SCardFreeMemory"); + if(!WSCardFreeMemory) throw WinscardLibraryNotInitialized(); + + WSCardListReadersA = (SCardListReadersAPtr) GetProcAddress(WinscardLibraryHandle,"SCardListReadersA"); + if(!WSCardListReadersA) throw WinscardLibraryNotInitialized(); + + WSCardTransmit = ( SCardTransmitPtr) GetProcAddress(WinscardLibraryHandle,"SCardTransmit"); + if(!WSCardTransmit) throw WinscardLibraryNotInitialized(); + + Initialized = true; + + } + #endif + + /* Establishing the resource manager context (the scope) within which database operations are performed. + * The module of the smart card subsystem that manages access to multiple readers and smart cards. The + * resource manager identifies and tracks resources, allocates readers and resources across multiple + * applications,and supports transaction primitives for accessing services available on a given card.*/ + int IccDataExtractor::EstablishRSContext(){ + + #ifdef TC_WINDOWS + LONG returnValue = WSCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); + #else + LONG returnValue = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); + #endif + + /* Check if the establishment of the context was unsuccessful */ + if (returnValue != SCARD_S_SUCCESS) + throw PCSCException(returnValue); + + return EXIT_SUCCESS; + } + + /* Detecting available readers and filling the reader table */ + unsigned long IccDataExtractor::GetReaders(){ + + #ifdef TC_WINDOWS + if(!Initialized) + throw WinscardLibraryNotInitialized(); + #endif + + EstablishRSContext(); + + /* Length of the mszReaders buffer in characters. If the buffer length is specified as + * SCARD_AUTOALLOCATE, then mszReaders is converted to a pointer to a byte pointer, and + * receives the address of a block of memory containing the multi-string structure */ + DWORD dwReaders = SCARD_AUTOALLOCATE; + + /* Retrieving the available readers list and putting it in mszReaders*/ // Use LPSTR on linux + #ifdef TC_WINDOWS + LONG returnValue = WSCardListReadersA(hContext, NULL, (LPSTR)&mszReaders, &dwReaders); + #else + LONG returnValue = SCardListReaders(hContext, NULL, (LPTSTR)&mszReaders, &dwReaders); + #endif + + /* If the is no readers, return */ + if(returnValue == SCARD_E_NO_READERS_AVAILABLE) return 0; + + /* Check if the listing of the connected readers was unsuccessful */ + if (returnValue != SCARD_S_SUCCESS) + throw PCSCException(returnValue); + + nbReaders = 0; + LPSTR ReaderPtr = mszReaders; + + /* Getting the total number of readers */ + while (*ReaderPtr != '\0') + { + readers.push_back(ReaderPtr); + ReaderPtr += strlen((char*)ReaderPtr) + 1; + nbReaders++; + } + + return nbReaders; + } + + /* Connecting to the card in the given reader*/ + int IccDataExtractor::ConnectCard(unsigned long int reader_nb){ + + /* Check if the given reader slot number is possible */ + if (reader_nb < 0 || reader_nb >= nbReaders) + throw InvalidEMVPath(); + + dwActiveProtocol = SCARD_PROTOCOL_UNDEFINED; + + #ifdef TC_WINDOWS + LONG returnValue = WSCardConnectA(hContext, readers[reader_nb], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); + #else + LONG returnValue = SCardConnect(hContext, readers[reader_nb], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); + #endif + + /* Check is the card connection was unsuccessful */ + if (returnValue != SCARD_S_SUCCESS) + throw PCSCException(returnValue); + + return EXIT_SUCCESS; + } + + /* Disconnect the card currently connected*/ + int IccDataExtractor::DisconnectCard(){ + #ifdef TC_WINDOWS + LONG returnValue = WSCardDisconnect(hCard, SCARD_UNPOWER_CARD); + #else + LONG returnValue = SCardDisconnect(hCard, SCARD_UNPOWER_CARD); + #endif + + /* Check is the card deconnection was unsuccessful */ + if (returnValue != SCARD_S_SUCCESS) + throw PCSCException(returnValue); + + return EXIT_SUCCESS; + } + + /* Testing if the card contains the application of the given EMV type (0:Mastercard, 1:Visa, 2:Amex) */ + bool IccDataExtractor::TestingCardType(const int SELECT_TYPE_NUMBER){ + + const BYTE * SELECTED_TYPE = SELECT_TYPES[SELECT_TYPE_NUMBER]; + + BYTE pbRecvBuffer[64]; /* Buffer to receive the card response */ + + DWORD dwSendLength = SELECT_TYPE_SIZE; /* Set the size of the send buffer */ + DWORD dwRecvLength = sizeof(pbRecvBuffer); /* Set the size of the reception buffer */ + + /* Set up the io request */ + SCARD_IO_REQUEST ioRequest; + ioRequest.dwProtocol = dwActiveProtocol; + ioRequest.cbPciLength = sizeof(ioRequest); + + #ifdef TC_WINDOWS + LONG returnValue = WSCardTransmit(hCard, &ioRequest, SELECTED_TYPE, dwSendLength, NULL, pbRecvBuffer, &dwRecvLength); + #else + LONG returnValue = SCardTransmit(hCard, &ioRequest, SELECTED_TYPE, dwSendLength, NULL, pbRecvBuffer, &dwRecvLength); + #endif + + /* Check if the transmission was unsuccessful */ + if (returnValue != SCARD_S_SUCCESS) + throw PCSCException(returnValue); + + /* It received a response. Check if it didn't get a recognisable response */ + if (dwRecvLength < 2) + return false; + + /* Check if the command successfully executed (the card is the type passed in the parameter) */ + if (pbRecvBuffer[0] == 0x61) + return true; + + return false; + } + + /* Getting the ICC Public Key Certificates and the Issuer Public Key Certificates by parsing the application + * (!NEED TO TEST CARD TYPE TO SELECT APPLICATION FIRST!)*/ + void IccDataExtractor::GetCerts(vector &CERTS){ + + CERTS.clear(); + + bool iccFound= false; + bool issuerFound= false; + + shared_ptr node; + shared_ptr ICC_Public_Key_Certificate; + shared_ptr Issuer_PK_Certificate; + + BYTE pbRecvBuffer[64]; /* Buffer to receive the card response */ + BYTE pbRecvBufferFat[256]; /* Bigger buffer to receive the card response */ + + DWORD dwSendLength; /* Size of the send buffer */ + DWORD dwRecvLength; /* Size of the reception buffer */ + + /* Set up the io request */ + SCARD_IO_REQUEST ioRequest; + ioRequest.dwProtocol = dwActiveProtocol; + ioRequest.cbPciLength = sizeof(ioRequest); + + LONG returnValue; + + /* Parsing root folders */ + for (int sfi = 0; sfi < 32; sfi++) + { + /* Parsing sub folders */ + for (int rec = 0; rec < 17; rec++) + { + BYTE SELECT_APDU_FILE[] = {00, 0xB2, static_cast(rec), static_cast((sfi << 3) | 4), 0x00}; + + dwSendLength = sizeof(SELECT_APDU_FILE); + dwRecvLength = sizeof(pbRecvBuffer); + + /* Check if there is data in the folder */ + #ifdef TC_WINDOWS + returnValue = WSCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength,NULL, pbRecvBuffer, &dwRecvLength); + #else + returnValue = SCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength,NULL, pbRecvBuffer, &dwRecvLength); + #endif + + /* Check if the transmission was unsuccessful */ + if (returnValue != SCARD_S_SUCCESS) + throw PCSCException(returnValue); + + /* There is no data in the folder */ + if (pbRecvBuffer[0] != 0x6C) + continue; + + /* It set the proper expected length of the data in the APDU */ + SELECT_APDU_FILE[4] = pbRecvBuffer[1]; + + dwRecvLength = sizeof(pbRecvBufferFat); + + /* Get the data from the folder */ + #ifdef TC_WINDOWS + returnValue = WSCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength, NULL, pbRecvBufferFat, &dwRecvLength); + #else + returnValue = SCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength, NULL, pbRecvBufferFat, &dwRecvLength); + #endif + + /* Check if the transmission was unsuccessful */ + if (returnValue != SCARD_S_SUCCESS) + throw PCSCException(returnValue); + + /* It received a response. Check if it didn't get a recognisable response */ + if (dwRecvLength < 2) + continue; + + /* Parsing the TLV */ + try{ + node = TLVParser::TLV_Parse(pbRecvBufferFat,sizeof(pbRecvBufferFat)); + }catch(TLVException){ + continue; + } + + /* Finding the ICC_Public_Key_Certificate */ + try{ + ICC_Public_Key_Certificate = TLVParser::TLV_Find(node, 0x9F46); + }catch(TLVException){ + continue; + } + if(ICC_Public_Key_Certificate) { + iccFound=true; + for (int i = 0; i < ICC_Public_Key_Certificate->Length;i++) { + CERTS.push_back(static_cast(ICC_Public_Key_Certificate->Value[i])); + } + } + + /* Finding the Issuer_Public_Key_Certificate */ + try{ + Issuer_PK_Certificate = TLVParser::TLV_Find(node, 0x90); + }catch(TLVException){ + continue; + } + + if(Issuer_PK_Certificate) { + issuerFound=true; + for (int i = 0; i < Issuer_PK_Certificate->Length;i++) { + CERTS.push_back(static_cast(Issuer_PK_Certificate->Value[i])); + } + } + + /* Limiting the search to at least one occurrence of both PKs to speed up the process. + * There might be more certificates tho */ + if(iccFound && issuerFound){ + burn(pbRecvBuffer, sizeof(pbRecvBuffer)); + burn(pbRecvBufferFat, sizeof(pbRecvBufferFat)); + return; + } + } + } + burn(pbRecvBuffer, sizeof(pbRecvBuffer)); + burn(pbRecvBufferFat, sizeof(pbRecvBufferFat)); + throw EMVKeyfileDataNotFound(); + } + + /* Getting CPCL data from the card*/ + void IccDataExtractor::GetCPCL(vector &v){ + + BYTE SELECT_APDU_CPCL[] = {0x80,0xCA, 0x9F, 0x7F, 0x00}; + + BYTE pbRecvBuffer[64]; /* Buffer to receive the card response */ + BYTE pbRecvBufferFat[256]; /* Bigger buffer to receive the card response */ + + DWORD dwSendLength = sizeof (SELECT_APDU_CPCL); /* Set the size of the send buffer */ + DWORD dwRecvLength = sizeof(pbRecvBuffer); /* Set the size of the reception buffer */ + + /* Set up the io request */ + SCARD_IO_REQUEST ioRequest; + ioRequest.dwProtocol = dwActiveProtocol; + ioRequest.cbPciLength = sizeof(ioRequest); + + /* Check if there is the TAG for CPCL Data in the card */ + #ifdef TC_WINDOWS + LONG returnValue = WSCardTransmit(hCard, &ioRequest, SELECT_APDU_CPCL, dwSendLength, NULL, pbRecvBuffer, &dwRecvLength); + #else + LONG returnValue = SCardTransmit(hCard, &ioRequest, SELECT_APDU_CPCL, dwSendLength, NULL, pbRecvBuffer, &dwRecvLength); + #endif + + /* Check if the transmission was unsuccessful */ + if (returnValue != SCARD_S_SUCCESS) + throw PCSCException(returnValue); + + /* Not the correct APDU response code */ + if (pbRecvBuffer[0] != 0x6C) + throw EMVKeyfileDataNotFound(); + + /* It set the proper expected length of the data in the APDU */ + SELECT_APDU_CPCL[4] = pbRecvBuffer[1]; + + dwRecvLength = sizeof(pbRecvBufferFat); + + /* Get the CPCL data */ + #ifdef TC_WINDOWS + returnValue = WSCardTransmit(hCard, &ioRequest, SELECT_APDU_CPCL, dwSendLength,NULL, pbRecvBufferFat, &dwRecvLength); + #else + returnValue = SCardTransmit(hCard, &ioRequest, SELECT_APDU_CPCL, dwSendLength,NULL, pbRecvBufferFat, &dwRecvLength); + #endif + + /* Check if the transmission was unsuccessful */ + if (returnValue != SCARD_S_SUCCESS) + throw PCSCException(returnValue); + + /* It received a response. Check if it didn't get a recognisable response */ + if (dwRecvLength < 2) + throw EMVKeyfileDataNotFound(); + + /* We add CPCL data and crop the TAG and the data length at the start and the trailer at the end */ + for (unsigned long i = 3; i < dwRecvLength-2; i++) { + v.push_back(static_cast(pbRecvBufferFat[i])); + } + burn(pbRecvBuffer, sizeof(pbRecvBuffer)); + burn(pbRecvBufferFat, sizeof(pbRecvBufferFat)); + + } + + /* Getting an ICC Public Key Certificates and an Issuer Public Key Certificates for the first application with the cpcl + * data present on the card and finally merge it into one byte array */ + void IccDataExtractor::GettingAllCerts(int readerNumber, vector &v){ + + #ifdef TC_WINDOWS + if(!Initialized) + throw WinscardLibraryNotInitialized(); + #endif + + bool isEMV= false; + + ConnectCard(readerNumber); + + /* Test all the type of applications and get the certificates from the first one found */ + for(int i=0;i &v) { + + bool PANFound= false; + shared_ptr node; + shared_ptr PAN; + + BYTE pbRecvBuffer[64]; /* Buffer to receive the card response */ + BYTE pbRecvBufferFat[256]; /* Bigger buffer to receive the card response */ + + DWORD dwSendLength; /* Size of the send buffer */ + DWORD dwRecvLength; /* Size of the reception buffer */ + + /* Set up the io request */ + SCARD_IO_REQUEST ioRequest; + ioRequest.dwProtocol = dwActiveProtocol; + ioRequest.cbPciLength = sizeof(ioRequest); + + LONG returnValue; + + /* Parsing root folders */ + for (int sfi = 0; sfi < 32; sfi++) + { + /* Parsing sub folders */ + for (int rec = 0; rec < 17; rec++) + { + BYTE SELECT_APDU_FILE[] = {00, 0xB2, static_cast(rec), static_cast((sfi << 3) | 4), 0x00}; + + dwSendLength = sizeof(SELECT_APDU_FILE); + dwRecvLength = sizeof(pbRecvBuffer); + + /* Check if there is data in the folder */ + #ifdef TC_WINDOWS + returnValue = WSCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength,NULL, pbRecvBuffer, &dwRecvLength); + #else + returnValue = SCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength,NULL, pbRecvBuffer, &dwRecvLength); + #endif + + /* Check if the transmission was unsuccessful */ + if (returnValue != SCARD_S_SUCCESS) + throw PCSCException(returnValue); + + /* There is no data in the folder */ + if (pbRecvBuffer[0] != 0x6C) + continue; + + /* It set the proper expected length of the data in the APDU */ + SELECT_APDU_FILE[4] = pbRecvBuffer[1]; + + dwRecvLength = sizeof(pbRecvBufferFat); + + /* Get the data from the folder */ + #ifdef TC_WINDOWS + returnValue = WSCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength,NULL, pbRecvBufferFat, &dwRecvLength); + #else + returnValue = SCardTransmit(hCard, &ioRequest, SELECT_APDU_FILE, dwSendLength,NULL, pbRecvBufferFat, &dwRecvLength); + #endif + + /* Check if the transmission was unsuccessful */ + if (returnValue != SCARD_S_SUCCESS) + throw PCSCException(returnValue); + + /* It received a response. Check if it didn't get a recognisable response */ + if (dwRecvLength < 2) + continue; + + /* Parsing the TLV */ + try{ + node = TLVParser::TLV_Parse(pbRecvBufferFat,sizeof(pbRecvBufferFat)); + }catch(TLVException){ + continue; + } + + /* Finding the PAN */ + try{ + PAN = TLVParser::TLV_Find(node, 0x5A); + }catch(TLVException){ + continue; + } + if(PAN) { + PANFound=true; + if (PAN->Length >= 8){ + for (int i = 6; i < 8;i++) { + v.push_back(static_cast(PAN->Value[i])); + } + } + } + + if(PANFound){ + burn(pbRecvBuffer, sizeof(pbRecvBuffer)); + burn(pbRecvBufferFat, sizeof(pbRecvBufferFat)); + return ; + } + } + } + burn(pbRecvBuffer, sizeof(pbRecvBuffer)); + burn(pbRecvBufferFat, sizeof(pbRecvBufferFat)); + throw EMVPANNotFound(); + } + + /* Helper function to transform the PAN received (vector of byte) to a string */ + template + void IccDataExtractor::make_hex_string(TInputIter first, TInputIter last, string& returnValue, bool use_uppercase, bool insert_spaces) { + ostringstream ss; + ss << hex << std::setfill('0'); + if (use_uppercase) + ss << uppercase; + while (first != last) + { + ss << setw(2) << static_cast(*first++); + if (insert_spaces && first != last) + ss << " "; + } + + returnValue = ss.str(); + } + + /* Wrapper function to get the PAN of the card*/ + void IccDataExtractor::GettingPAN(int readerNumber, string& panString) { + + #ifdef TC_WINDOWS + if(!Initialized) + throw WinscardLibraryNotInitialized(); + #endif + + vector PAN; + + bool isEMV= false; + + ConnectCard(readerNumber); + + /* Test all the type of applications and get the PAN from the first one found */ + for(int i=0;i stream) + { + Exception::Deserialize(stream); + Serializer sr(stream); + uint64 code; + sr.Deserialize("ErrorCode", code); + sr.Deserialize("SubjectErrorCodeValid", SubjectErrorCodeValid); + sr.Deserialize("SubjectErrorCode", SubjectErrorCode); + ErrorCode = (LONG)code; + } + + void PCSCException::Serialize(shared_ptr stream) const + { + Exception::Serialize(stream); + Serializer sr(stream); + sr.Serialize("ErrorCode", (uint64)ErrorCode); + sr.Serialize("SubjectErrorCodeValid", SubjectErrorCodeValid); + sr.Serialize("SubjectErrorCode", SubjectErrorCode); + } + +# define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) +# undef TC_EXCEPTION_NODECL +# define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) + + TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET(PCSCTokenException); + +#endif + +} \ No newline at end of file diff --git a/src/Common/IccDataExtractor.h b/src/Common/IccDataExtractor.h new file mode 100644 index 00000000..777a3555 --- /dev/null +++ b/src/Common/IccDataExtractor.h @@ -0,0 +1,231 @@ +// +// Created by bshp on 1/14/23. +// + +#ifndef NEWEMV_ICCDATAEXTRACTOR_H +#define NEWEMV_ICCDATAEXTRACTOR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Platform/PlatformBase.h" +#include "TLVParser.h" + +#ifdef __linux__ +#include +#endif + +#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE) +# include "Exception.h" +#else +# include "Platform/Exception.h" +#endif + +#ifdef TC_WINDOWS +#include +#include +#endif +#ifdef TC_UNIX +#undef BOOL +#include +using VeraCrypt::byte; +#define BOOL int +//#include //Works without on windows +#endif + +#ifdef _WIN32 +#include +#endif + +#ifdef _WIN64 +#define ssize_t __int64 +#else +#define ssize_t long +#endif + +#define SELECT_TYPE_SIZE 12 /* Size of the SELECT_TYPE APDU */ + +/* Winscard function pointers definitions for windows import */ +#ifdef TC_WINDOWS +typedef LONG (WINAPI *SCardEstablishContextPtr)(DWORD dwScope,LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext); +typedef LONG (WINAPI *SCardReleaseContextPtr)(SCARDCONTEXT hContext); +typedef LONG (WINAPI *SCardConnectAPtr)(SCARDCONTEXT hContext,LPCSTR szReader,DWORD dwShareMode,DWORD dwPreferredProtocols,LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol); +typedef LONG (WINAPI *SCardDisconnectPtr)(SCARDHANDLE hCard, DWORD dwDisposition); +typedef LONG (WINAPI *SCardTransmitPtr)(SCARDHANDLE hCard,LPCSCARD_IO_REQUEST pioSendPci,const BYTE* pbSendBuffer, DWORD cbSendLength,LPSCARD_IO_REQUEST pioRecvPci,BYTE* pbRecvBuffer, LPDWORD pcbRecvLength); +typedef LONG (WINAPI *SCardListReadersAPtr)(SCARDCONTEXT hContext,LPCSTR mszGroups,LPSTR mszReaders, LPDWORD pcchReaders); +typedef LONG (WINAPI *SCardFreeMemoryPtr)(SCARDCONTEXT hContext,LPCVOID pvMem); +#endif + +namespace VeraCrypt +{ + class IccDataExtractor { + private: + + /* Used for loading winscard on windows */ + #ifdef TC_WINDOWS + /* Winscard Library Handle */ + HMODULE WinscardLibraryHandle; + + /* Winscard function pointers */ + SCardEstablishContextPtr WSCardEstablishContext; + SCardReleaseContextPtr WSCardReleaseContext; + SCardConnectAPtr WSCardConnectA; + SCardDisconnectPtr WSCardDisconnect; + SCardFreeMemoryPtr WSCardFreeMemory; + SCardListReadersAPtr WSCardListReadersA; + SCardTransmitPtr WSCardTransmit; + + /* Is the winscard library loaded */ + static bool Initialized; + #endif + + /* SELECT_TYPES FOR DIFFERENT AIDs*/ + const static BYTE SELECT_MASTERCARD[SELECT_TYPE_SIZE]; + const static BYTE SELECT_VISA[SELECT_TYPE_SIZE]; + const static BYTE SELECT_AMEX[SELECT_TYPE_SIZE]; + const static BYTE * SELECT_TYPES[3]; + + + SCARDCONTEXT hContext; /* Handle that identifies the resource manager context.*/ + + SCARDHANDLE hCard; /* A handle that identifies the connection to the smart card in the designated reader*/ + + std::vector readers; /* Card reader list */ + + unsigned long int nbReaders; /* Number of connected (available) readers */ + + LPSTR mszReaders; /* Names of the reader groups defined to the system, as a multi-string. Use a NULL value to + * list all readers in the system */ + + DWORD dwActiveProtocol; /* A flag that indicates the established active protocol. + * SCARD_PROTOCOL_T0: An asynchronous, character-oriented half-duplex transmission protocol. + * SCARD_PROTOCOL_T1: An asynchronous, block-oriented half-duplex transmission protocol.*/ + + + /* Establishing the resource manager context (the scope) within which database operations are performed. + * The module of the smart card subsystem that manages access to multiple readers and smart cards. The + * resource manager identifies and tracks resources, allocates readers and resources across multiple + * applications,and supports transaction primitives for accessing services available on a given card.*/ + int EstablishRSContext(); + + /* Connecting to the card in the given reader*/ + int ConnectCard(unsigned long int reader_nb); + + /* Disconnect the card currently connected*/ + int DisconnectCard(); + + /* Testing if the card contains the application of the given EMV type */ + bool TestingCardType(const int SELECT_TYPE_NUMBER); + + /* Getting the ICC Public Key Certificates and the Issuer Public Key Certificates by parsing the application + * (!NEED TO TEST CARD TYPE TO SELECT APPLICATION FIRST!)*/ + void GetCerts(vector &CERTS); + + /* Getting CPCL data from the card and put it into a reference*/ + void GetCPCL(vector &v); + + /* Getting the PAN by parsing the application + * (!NEED TO TEST CARD TYPE TO SELECT APPLICATION FIRST!)*/ + void GetPAN(vector &v); + + /* Helper function to make a string from plain arrays and various standard containers of bytes */ + template + void make_hex_string(TInputIter first, TInputIter last, std::string& panString, bool use_uppercase = true, bool insert_spaces = false); + + public: + IccDataExtractor(); + + ~IccDataExtractor(); + + /* Used to initialize the winscard library on windows to make sure the dll is in System32 */ + #ifdef TC_WINDOWS + void IccDataExtractor::InitLibrary(); + #endif + + /* Detecting available readers and filling the reader table. Returns + * the number of available readers */ + unsigned long GetReaders(); + + + /* Getting an ICC Public Key Certificates, an Issuer Public Key Certificates and the CPCL data + * from the card designated by the reader number. Appending them into a byte vector */ + void GettingAllCerts(int readerNumber, vector &v); + + /* Getting the PAN from the card designated by the reader number */ + void GettingPAN(int readerNumber, string& panString); + }; + + struct PCSCException: public Exception + { + PCSCException(LONG errorCode = (LONG) -1): ErrorCode(errorCode), SubjectErrorCodeValid(false), SubjectErrorCode((uint64)-1){} + PCSCException(LONG errorCode, uint64 subjectErrorCode): ErrorCode(errorCode), SubjectErrorCodeValid(true), SubjectErrorCode(subjectErrorCode){} + + #ifdef TC_HEADER_Platform_Exception + virtual ~PCSCException() throw () { } + TC_SERIALIZABLE_EXCEPTION(PCSCException); + #else + + void Show(HWND parent) const; + #endif + + operator string () const; + LONG GetErrorCode() const { return ErrorCode; } + + protected: + LONG ErrorCode; + bool SubjectErrorCodeValid; + uint64 SubjectErrorCode; + }; + + #ifdef TC_HEADER_Platform_Exception + + #define TC_EXCEPTION(NAME) TC_EXCEPTION_DECL(NAME,Exception) + + #undef TC_EXCEPTION_SET + #define TC_EXCEPTION_SET \ + TC_EXCEPTION_NODECL (PCSCException); \ + TC_EXCEPTION (WinscardLibraryNotInitialized); \ + TC_EXCEPTION (InvalidEMVPath); \ + TC_EXCEPTION (EMVKeyfileDataNotFound); \ + TC_EXCEPTION (EMVPANNotFound); \ + TC_EXCEPTION (EMVUnknownCardType); + TC_EXCEPTION_SET; + + #undef TC_EXCEPTION + + #else // !TC_HEADER_Platform_Exception + + struct WinscardLibraryNotInitialized: public Exception + { + void Show(HWND parent) const { Error("WINSCARD_MODULE_INIT_FAILED", parent); } + }; + + struct InvalidEMVPath: public Exception + { + void Show(HWND parent) const { Error("INVALID_EMV_PATH", parent); } + }; + + struct EMVKeyfileDataNotFound: public Exception + { + void Show(HWND parent) const { Error("EMV_KEYFILE_DATA_NOT_FOUND", parent); } + }; + + struct EMVPANNotFound: public Exception + { + void Show(HWND parent) const { Error("EMV_PAN_NOT_FOUND", parent); } + }; + + struct EMVUnknownCardType: public Exception + { + void Show(HWND parent) const { Error("EMV_UNKNOWN_CARD_TYPE", parent); } + }; + + #endif // !TC_HEADER_Platform_Exception +} + +#endif //NEWEMV_ICCDATAEXTRACTOR_H diff --git a/src/Common/Keyfiles.c b/src/Common/Keyfiles.c index 174aed92..d2207f5f 100644 --- a/src/Common/Keyfiles.c +++ b/src/Common/Keyfiles.c @@ -23,6 +23,7 @@ #include "Dlgcode.h" #include "Language.h" #include "SecurityToken.h" +#include "EMVToken.h" #include "Common/resource.h" #include "Platform/Finally.h" #include "Platform/ForEach.h" @@ -249,12 +250,12 @@ BOOL KeyFilesApply (HWND hwndDlg, Password *password, KeyFile *firstKeyFile, con // Determine whether it's a security token path try { - if (SecurityToken::IsKeyfilePathValid (kf->FileName)) + if (Token::IsKeyfilePathValid (kf->FileName, ActivateEMVOption)) { // Apply security token keyfile vector keyfileData; - SecurityTokenKeyfilePath secPath (kf->FileName); - SecurityToken::GetKeyfileData (SecurityTokenKeyfile (secPath), keyfileData); + TokenKeyfilePath secPath (kf->FileName); + Token::getTokenKeyfile (secPath)->GetKeyfileData (keyfileData); if (keyfileData.empty()) { @@ -551,10 +552,10 @@ BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa if (lw == IDC_TOKEN_FILES_ADD) { - list selectedTokenKeyfiles; + list selectedTokenKeyfiles; if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, (LPARAM) &selectedTokenKeyfiles) == IDOK) { - foreach (const SecurityTokenKeyfilePath &keyPath, selectedTokenKeyfiles) + foreach (const TokenKeyfilePath &keyPath, selectedTokenKeyfiles) { KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile)); if (kf) @@ -758,10 +759,10 @@ BOOL KeyfilesPopupMenu (HWND hwndDlg, POINT popupPosition, KeyFilesDlgParam *par case IDM_KEYFILES_POPUP_ADD_TOKEN_FILES: { - list selectedTokenKeyfiles; + list selectedTokenKeyfiles; if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, (LPARAM) &selectedTokenKeyfiles) == IDOK) { - foreach (const SecurityTokenKeyfilePath &keyPath, selectedTokenKeyfiles) + foreach (const TokenKeyfilePath &keyPath, selectedTokenKeyfiles) { KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile)); if (kf) diff --git a/src/Common/Language.xml b/src/Common/Language.xml index 540f6867..cd996bce 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -113,6 +113,7 @@ Cache passwords and keyfil&es in memory Exit when there are no mounted volumes &Close token session (log out) after a volume is successfully mounted + Activate EMV Option Include VeraCrypt Volume Expander Include VeraCrypt Volume Creation Wizard Create @@ -295,6 +296,7 @@ PKCS-5 PRF: Password Cache Security Options + EMV Options VeraCrypt Background Task VeraCrypt volume to mount (relative to traveler disk root): Upon insertion of traveler disk: @@ -1278,6 +1280,12 @@ Password for security token is incorrect. The security token does not have enough memory/space to perform the requested operation.\n\nIf you are attempting to import a keyfile, you should select a smaller file or use a keyfile generated by VeraCrypt (select 'Tools' > 'Keyfile Generator'). All open security token sessions have been closed. + Error when loading the winscard library.\n\nPlease make sure the WinSCard.dll is present in your System32 folder. + EMV path is invalid. + Unable to build a keyfile from the EMV card's data.\n\nOne of the following is missing:\n- ICC Public Key Certificate.\n- Issuer Public Key Certificate.\n- CPCL data. + No Primary Account Number (PAN) found in the EMV card. + The card in the reader is not a supported EMV card. + No card in the reader.\n\nPlease make sure the card is correctly slotted. Select Security Token Keyfiles Slot Token name diff --git a/src/Common/SecurityToken.cpp b/src/Common/SecurityToken.cpp index 8401a0eb..ad8ed33e 100644 --- a/src/Common/SecurityToken.cpp +++ b/src/Common/SecurityToken.cpp @@ -36,23 +36,31 @@ using namespace std; namespace VeraCrypt { - SecurityTokenKeyfile::SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path) + SecurityTokenKeyfile::SecurityTokenKeyfile(): Handle(CK_INVALID_HANDLE) { + SecurityTokenInfo* token = new SecurityTokenInfo(); + Token = shared_ptr(token); + Token->SlotId = CK_UNAVAILABLE_INFORMATION; + token->Flags = 0; + } + + SecurityTokenKeyfile::SecurityTokenKeyfile(const TokenKeyfilePath& path) { + Token = shared_ptr(new SecurityTokenInfo()); wstring pathStr = path; unsigned long slotId; - if (swscanf (pathStr.c_str(), TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/%lu", &slotId) != 1) + if (swscanf(pathStr.c_str(), TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/%lu", &slotId) != 1) throw InvalidSecurityTokenKeyfilePath(); - SlotId = slotId; + Token->SlotId = slotId; - size_t keyIdPos = pathStr.find (L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/"); + size_t keyIdPos = pathStr.find(L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/"); if (keyIdPos == wstring::npos) throw InvalidSecurityTokenKeyfilePath(); - Id = pathStr.substr (keyIdPos + wstring (L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/").size()); + Id = pathStr.substr(keyIdPos + wstring(L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/").size()); - vector keyfiles = SecurityToken::GetAvailableKeyfiles (&SlotId, Id); + vector keyfiles = SecurityToken::GetAvailableKeyfiles(&Token->SlotId, Id); if (keyfiles.empty()) throw SecurityTokenKeyfileNotFound(); @@ -60,69 +68,69 @@ namespace VeraCrypt *this = keyfiles.front(); } - SecurityTokenKeyfile::operator SecurityTokenKeyfilePath () const + SecurityTokenKeyfile::operator TokenKeyfilePath () const { wstringstream path; - path << TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/" << SlotId << L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/" << Id; + path << TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/" << Token->SlotId << L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/" << Id; return path.str(); } - void SecurityToken::CheckLibraryStatus () + void SecurityToken::CheckLibraryStatus() { if (!Initialized) throw SecurityTokenLibraryNotInitialized(); } - void SecurityToken::CloseLibrary () + void SecurityToken::CloseLibrary() { if (Initialized) { CloseAllSessions(); - Pkcs11Functions->C_Finalize (NULL_PTR); + Pkcs11Functions->C_Finalize(NULL_PTR); #ifdef TC_WINDOWS - FreeLibrary (Pkcs11LibraryHandle); + FreeLibrary(Pkcs11LibraryHandle); #else - dlclose (Pkcs11LibraryHandle); + dlclose(Pkcs11LibraryHandle); #endif Initialized = false; } } - void SecurityToken::CloseAllSessions () throw () + void SecurityToken::CloseAllSessions() throw () { if (!Initialized) return; typedef pair SessionMapPair; - foreach (SessionMapPair p, Sessions) + foreach(SessionMapPair p, Sessions) { try { - CloseSession (p.first); + CloseSession(p.first); } - catch (...) { } + catch (...) {} } } - void SecurityToken::CloseSession (CK_SLOT_ID slotId) + void SecurityToken::CloseSession(CK_SLOT_ID slotId) { - if (Sessions.find (slotId) == Sessions.end()) - throw ParameterIncorrect (SRC_POS); + if (Sessions.find(slotId) == Sessions.end()) + throw ParameterIncorrect(SRC_POS); - Pkcs11Functions->C_CloseSession (Sessions[slotId].Handle); - Sessions.erase (Sessions.find (slotId)); + Pkcs11Functions->C_CloseSession(Sessions[slotId].Handle); + Sessions.erase(Sessions.find(slotId)); } - void SecurityToken::CreateKeyfile (CK_SLOT_ID slotId, vector &keyfileData, const string &name) + void SecurityToken::CreateKeyfile(CK_SLOT_ID slotId, vector & keyfileData, const string& name) { if (name.empty()) - throw ParameterIncorrect (SRC_POS); + throw ParameterIncorrect(SRC_POS); - LoginUserIfRequired (slotId); + LoginUserIfRequired(slotId); - foreach (const SecurityTokenKeyfile &keyfile, GetAvailableKeyfiles (&slotId)) + foreach(const SecurityTokenKeyfile & keyfile, GetAvailableKeyfiles(&slotId)) { if (keyfile.IdUtf8 == name) throw SecurityTokenKeyfileAlreadyExists(); @@ -133,16 +141,16 @@ namespace VeraCrypt CK_ATTRIBUTE keyfileTemplate[] = { - { CKA_CLASS, &dataClass, sizeof (dataClass) }, - { CKA_TOKEN, &trueVal, sizeof (trueVal) }, - { CKA_PRIVATE, &trueVal, sizeof (trueVal) }, - { CKA_LABEL, (CK_UTF8CHAR *) name.c_str(), (CK_ULONG) name.size() }, - { CKA_VALUE, &keyfileData.front(), (CK_ULONG) keyfileData.size() } + { CKA_CLASS, &dataClass, sizeof(dataClass) }, + { CKA_TOKEN, &trueVal, sizeof(trueVal) }, + { CKA_PRIVATE, &trueVal, sizeof(trueVal) }, + { CKA_LABEL, (CK_UTF8CHAR*)name.c_str(), (CK_ULONG)name.size() }, + { CKA_VALUE, &keyfileData.front(), (CK_ULONG)keyfileData.size() } }; CK_OBJECT_HANDLE keyfileHandle; - CK_RV status = Pkcs11Functions->C_CreateObject (Sessions[slotId].Handle, keyfileTemplate, array_capacity (keyfileTemplate), &keyfileHandle); + CK_RV status = Pkcs11Functions->C_CreateObject(Sessions[slotId].Handle, keyfileTemplate, array_capacity(keyfileTemplate), &keyfileHandle); switch (status) { @@ -156,36 +164,36 @@ namespace VeraCrypt } if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); // Some tokens report success even if the new object was truncated to fit in the available memory vector objectData; - GetObjectAttribute (slotId, keyfileHandle, CKA_VALUE, objectData); - finally_do_arg (vector *, &objectData, { if (!finally_arg->empty()) burn (&finally_arg->front(), finally_arg->size()); }); + GetObjectAttribute(slotId, keyfileHandle, CKA_VALUE, objectData); + finally_do_arg(vector *, &objectData, { if (!finally_arg->empty()) burn(&finally_arg->front(), finally_arg->size()); }); if (objectData.size() != keyfileData.size()) { - Pkcs11Functions->C_DestroyObject (Sessions[slotId].Handle, keyfileHandle); - throw Pkcs11Exception (CKR_DEVICE_MEMORY); + Pkcs11Functions->C_DestroyObject(Sessions[slotId].Handle, keyfileHandle); + throw Pkcs11Exception(CKR_DEVICE_MEMORY); } } - void SecurityToken::DeleteKeyfile (const SecurityTokenKeyfile &keyfile) + void SecurityToken::DeleteKeyfile(const SecurityTokenKeyfile& keyfile) { - LoginUserIfRequired (keyfile.SlotId); + LoginUserIfRequired(keyfile.Token->SlotId); - CK_RV status = Pkcs11Functions->C_DestroyObject (Sessions[keyfile.SlotId].Handle, keyfile.Handle); + CK_RV status = Pkcs11Functions->C_DestroyObject(Sessions[keyfile.Token->SlotId].Handle, keyfile.Handle); if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); } - vector SecurityToken::GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter, const wstring keyfileIdFilter) + vector SecurityToken::GetAvailableKeyfiles(CK_SLOT_ID* slotIdFilter, const wstring keyfileIdFilter) { bool unrecognizedTokenPresent = false; vector keyfiles; - foreach (const CK_SLOT_ID &slotId, GetTokenSlots()) + foreach(const CK_SLOT_ID & slotId, GetTokenSlots()) { SecurityTokenInfo token; @@ -194,14 +202,14 @@ namespace VeraCrypt try { - LoginUserIfRequired (slotId); - token = GetTokenInfo (slotId); + LoginUserIfRequired(slotId); + token = GetTokenInfo(slotId); } - catch (UserAbort &) + catch (UserAbort&) { continue; } - catch (Pkcs11Exception &e) + catch (Pkcs11Exception& e) { if (e.GetErrorCode() == CKR_TOKEN_NOT_RECOGNIZED) { @@ -212,34 +220,34 @@ namespace VeraCrypt throw; } - foreach (const CK_OBJECT_HANDLE &dataHandle, GetObjects (slotId, CKO_DATA)) + foreach(const CK_OBJECT_HANDLE & dataHandle, GetObjects(slotId, CKO_DATA)) { SecurityTokenKeyfile keyfile; keyfile.Handle = dataHandle; - keyfile.SlotId = slotId; - keyfile.Token = token; + keyfile.Token->SlotId = slotId; + keyfile.Token = shared_ptr(new SecurityTokenInfo(token)); vector privateAttrib; - GetObjectAttribute (slotId, dataHandle, CKA_PRIVATE, privateAttrib); + GetObjectAttribute(slotId, dataHandle, CKA_PRIVATE, privateAttrib); - if (privateAttrib.size() == sizeof (CK_BBOOL) && *(CK_BBOOL *) &privateAttrib.front() != CK_TRUE) + if (privateAttrib.size() == sizeof(CK_BBOOL) && *(CK_BBOOL*)&privateAttrib.front() != CK_TRUE) continue; vector label; - GetObjectAttribute (slotId, dataHandle, CKA_LABEL, label); - label.push_back (0); + GetObjectAttribute(slotId, dataHandle, CKA_LABEL, label); + label.push_back(0); - keyfile.IdUtf8 = (char *) &label.front(); + keyfile.IdUtf8 = (char*)&label.front(); #if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE) - keyfile.Id = Utf8StringToWide ((const char *) &label.front()); + keyfile.Id = Utf8StringToWide((const char*)&label.front()); #else - keyfile.Id = StringConverter::ToWide ((const char *) &label.front()); + keyfile.Id = StringConverter::ToWide((const char*)&label.front()); #endif if (keyfile.Id.empty() || (!keyfileIdFilter.empty() && keyfileIdFilter != keyfile.Id)) continue; - keyfiles.push_back (keyfile); + keyfiles.push_back(keyfile); if (!keyfileIdFilter.empty()) break; @@ -247,23 +255,23 @@ namespace VeraCrypt } if (keyfiles.empty() && unrecognizedTokenPresent) - throw Pkcs11Exception (CKR_TOKEN_NOT_RECOGNIZED); + throw Pkcs11Exception(CKR_TOKEN_NOT_RECOGNIZED); return keyfiles; } - list SecurityToken::GetAvailableTokens () + list SecurityToken::GetAvailableTokens() { bool unrecognizedTokenPresent = false; list tokens; - foreach (const CK_SLOT_ID &slotId, GetTokenSlots()) + foreach(const CK_SLOT_ID & slotId, GetTokenSlots()) { try { - tokens.push_back (GetTokenInfo (slotId)); + tokens.push_back(GetTokenInfo(slotId)); } - catch (Pkcs11Exception &e) + catch (Pkcs11Exception& e) { if (e.GetErrorCode() == CKR_TOKEN_NOT_RECOGNIZED) { @@ -276,63 +284,63 @@ namespace VeraCrypt } if (tokens.empty() && unrecognizedTokenPresent) - throw Pkcs11Exception (CKR_TOKEN_NOT_RECOGNIZED); + throw Pkcs11Exception(CKR_TOKEN_NOT_RECOGNIZED); return tokens; } - SecurityTokenInfo SecurityToken::GetTokenInfo (CK_SLOT_ID slotId) + SecurityTokenInfo SecurityToken::GetTokenInfo(CK_SLOT_ID slotId) { CK_TOKEN_INFO info; - CK_RV status = Pkcs11Functions->C_GetTokenInfo (slotId, &info); + CK_RV status = Pkcs11Functions->C_GetTokenInfo(slotId, &info); if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); SecurityTokenInfo token; token.SlotId = slotId; token.Flags = info.flags; - char label[sizeof (info.label) + 1]; - memset (label, 0, sizeof (label)); - memcpy (label, info.label, sizeof (info.label)); + char label[sizeof(info.label) + 1]; + memset(label, 0, sizeof(label)); + memcpy(label, info.label, sizeof(info.label)); token.LabelUtf8 = label; - size_t lastSpace = token.LabelUtf8.find_last_not_of (' '); + size_t lastSpace = token.LabelUtf8.find_last_not_of(' '); if (lastSpace == string::npos) token.LabelUtf8.clear(); else - token.LabelUtf8 = token.LabelUtf8.substr (0, lastSpace + 1); + token.LabelUtf8 = token.LabelUtf8.substr(0, lastSpace + 1); #if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE) - token.Label = Utf8StringToWide (token.LabelUtf8); + token.Label = Utf8StringToWide(token.LabelUtf8); #else - token.Label = StringConverter::ToWide (token.LabelUtf8); + token.Label = StringConverter::ToWide(token.LabelUtf8); #endif return token; } - void SecurityToken::GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector &keyfileData) + void SecurityTokenKeyfile::GetKeyfileData(vector & keyfileData) const { - LoginUserIfRequired (keyfile.SlotId); - GetObjectAttribute (keyfile.SlotId, keyfile.Handle, CKA_VALUE, keyfileData); + SecurityToken::LoginUserIfRequired(Token->SlotId); + SecurityToken::GetObjectAttribute(Token->SlotId, Handle, CKA_VALUE, keyfileData); } - vector SecurityToken::GetObjects (CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass) + vector SecurityToken::GetObjects(CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass) { - if (Sessions.find (slotId) == Sessions.end()) - throw ParameterIncorrect (SRC_POS); + if (Sessions.find(slotId) == Sessions.end()) + throw ParameterIncorrect(SRC_POS); CK_ATTRIBUTE findTemplate; findTemplate.type = CKA_CLASS; findTemplate.pValue = &objectClass; - findTemplate.ulValueLen = sizeof (objectClass); + findTemplate.ulValueLen = sizeof(objectClass); - CK_RV status = Pkcs11Functions->C_FindObjectsInit (Sessions[slotId].Handle, &findTemplate, 1); + CK_RV status = Pkcs11Functions->C_FindObjectsInit(Sessions[slotId].Handle, &findTemplate, 1); if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); - finally_do_arg (CK_SLOT_ID, slotId, { Pkcs11Functions->C_FindObjectsFinal (Sessions[finally_arg].Handle); }); + finally_do_arg(CK_SLOT_ID, slotId, { Pkcs11Functions->C_FindObjectsFinal(Sessions[finally_arg].Handle); }); CK_ULONG objectCount; vector objects; @@ -340,112 +348,112 @@ namespace VeraCrypt while (true) { CK_OBJECT_HANDLE object; - CK_RV status = Pkcs11Functions->C_FindObjects (Sessions[slotId].Handle, &object, 1, &objectCount); + CK_RV status = Pkcs11Functions->C_FindObjects(Sessions[slotId].Handle, &object, 1, &objectCount); if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); if (objectCount != 1) break; - objects.push_back (object); + objects.push_back(object); } return objects; } - void SecurityToken::GetObjectAttribute (CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector &attributeValue) + void SecurityToken::GetObjectAttribute(CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector & attributeValue) { attributeValue.clear(); - if (Sessions.find (slotId) == Sessions.end()) - throw ParameterIncorrect (SRC_POS); + if (Sessions.find(slotId) == Sessions.end()) + throw ParameterIncorrect(SRC_POS); CK_ATTRIBUTE attribute; attribute.type = attributeType; attribute.pValue = NULL_PTR; - CK_RV status = Pkcs11Functions->C_GetAttributeValue (Sessions[slotId].Handle, tokenObject, &attribute, 1); + CK_RV status = Pkcs11Functions->C_GetAttributeValue(Sessions[slotId].Handle, tokenObject, &attribute, 1); if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); if (attribute.ulValueLen == 0) return; - attributeValue = vector (attribute.ulValueLen); + attributeValue = vector (attribute.ulValueLen); attribute.pValue = &attributeValue.front(); - status = Pkcs11Functions->C_GetAttributeValue (Sessions[slotId].Handle, tokenObject, &attribute, 1); + status = Pkcs11Functions->C_GetAttributeValue(Sessions[slotId].Handle, tokenObject, &attribute, 1); if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); } - list SecurityToken::GetTokenSlots () + list SecurityToken::GetTokenSlots() { CheckLibraryStatus(); list slots; CK_ULONG slotCount; - CK_RV status = Pkcs11Functions->C_GetSlotList (TRUE, NULL_PTR, &slotCount); + CK_RV status = Pkcs11Functions->C_GetSlotList(TRUE, NULL_PTR, &slotCount); if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); if (slotCount > 0) { - vector slotArray (slotCount); - status = Pkcs11Functions->C_GetSlotList (TRUE, &slotArray.front(), &slotCount); + vector slotArray(slotCount); + status = Pkcs11Functions->C_GetSlotList(TRUE, &slotArray.front(), &slotCount); if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); for (size_t i = 0; i < slotCount; i++) { CK_SLOT_INFO slotInfo; - status = Pkcs11Functions->C_GetSlotInfo (slotArray[i], &slotInfo); + status = Pkcs11Functions->C_GetSlotInfo(slotArray[i], &slotInfo); if (status != CKR_OK || !(slotInfo.flags & CKF_TOKEN_PRESENT)) continue; - slots.push_back (slotArray[i]); + slots.push_back(slotArray[i]); } } return slots; } - bool SecurityToken::IsKeyfilePathValid (const wstring &securityTokenKeyfilePath) + bool SecurityToken::IsKeyfilePathValid(const wstring& securityTokenKeyfilePath) { - return securityTokenKeyfilePath.find (TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX) == 0; + return securityTokenKeyfilePath.find(TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX) == 0; } - void SecurityToken::Login (CK_SLOT_ID slotId, const char* pin) + void SecurityToken::Login(CK_SLOT_ID slotId, const char* pin) { - if (Sessions.find (slotId) == Sessions.end()) - OpenSession (slotId); + if (Sessions.find(slotId) == Sessions.end()) + OpenSession(slotId); else if (Sessions[slotId].UserLoggedIn) return; - 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); + 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); + throw Pkcs11Exception(status); Sessions[slotId].UserLoggedIn = true; } - void SecurityToken::LoginUserIfRequired (CK_SLOT_ID slotId) + void SecurityToken::LoginUserIfRequired(CK_SLOT_ID slotId) { CheckLibraryStatus(); CK_RV status; - if (Sessions.find (slotId) == Sessions.end()) + if (Sessions.find(slotId) == Sessions.end()) { - OpenSession (slotId); + OpenSession(slotId); } else { CK_SESSION_INFO sessionInfo; - status = Pkcs11Functions->C_GetSessionInfo (Sessions[slotId].Handle, &sessionInfo); + status = Pkcs11Functions->C_GetSessionInfo(Sessions[slotId].Handle, &sessionInfo); if (status == CKR_OK) { @@ -455,14 +463,14 @@ namespace VeraCrypt { try { - CloseSession (slotId); + CloseSession(slotId); } - catch (...) { } - OpenSession (slotId); + catch (...) {} + OpenSession(slotId); } } - SecurityTokenInfo tokenInfo = GetTokenInfo (slotId); + SecurityTokenInfo tokenInfo = GetTokenInfo(slotId); while (!Sessions[slotId].UserLoggedIn && (tokenInfo.Flags & CKF_LOGIN_REQUIRED)) { @@ -470,9 +478,9 @@ namespace VeraCrypt { if (tokenInfo.Flags & CKF_PROTECTED_AUTHENTICATION_PATH) { - status = Pkcs11Functions->C_Login (Sessions[slotId].Handle, CKU_USER, NULL_PTR, 0); + status = Pkcs11Functions->C_Login(Sessions[slotId].Handle, CKU_USER, NULL_PTR, 0); if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); } else { @@ -484,15 +492,15 @@ namespace VeraCrypt pin = s.str(); } - finally_do_arg (string*, &pin, { burn ((void *) finally_arg->c_str(), finally_arg->size()); }); + finally_do_arg(string*, &pin, { burn((void*)finally_arg->c_str(), finally_arg->size()); }); (*PinCallback) (pin); - Login (slotId, pin.c_str()); + Login(slotId, pin.c_str()); } Sessions[slotId].UserLoggedIn = true; } - catch (Pkcs11Exception &e) + catch (Pkcs11Exception& e) { CK_RV error = e.GetErrorCode(); @@ -502,8 +510,8 @@ namespace VeraCrypt } else if (error == CKR_PIN_INCORRECT && !(tokenInfo.Flags & CKF_PROTECTED_AUTHENTICATION_PATH)) { - PinCallback->notifyIncorrectPin (); - (*WarningCallback) (Pkcs11Exception (CKR_PIN_INCORRECT)); + PinCallback->notifyIncorrectPin(); + (*WarningCallback) (Pkcs11Exception(CKR_PIN_INCORRECT)); continue; } @@ -513,40 +521,40 @@ namespace VeraCrypt } #ifdef TC_WINDOWS - void SecurityToken::InitLibrary (const wstring &pkcs11LibraryPath, unique_ptr pinCallback, unique_ptr warningCallback) + void SecurityToken::InitLibrary(const wstring& pkcs11LibraryPath, unique_ptr pinCallback, unique_ptr warningCallback) #else - void SecurityToken::InitLibrary (const string &pkcs11LibraryPath, unique_ptr pinCallback, unique_ptr warningCallback) + void SecurityToken::InitLibrary(const string& pkcs11LibraryPath, unique_ptr pinCallback, unique_ptr warningCallback) #endif { if (Initialized) CloseLibrary(); #ifdef TC_WINDOWS - Pkcs11LibraryHandle = LoadLibraryW (pkcs11LibraryPath.c_str()); - throw_sys_if (!Pkcs11LibraryHandle); + Pkcs11LibraryHandle = LoadLibraryW(pkcs11LibraryPath.c_str()); + throw_sys_if(!Pkcs11LibraryHandle); #else - Pkcs11LibraryHandle = dlopen (pkcs11LibraryPath.c_str(), RTLD_NOW | RTLD_LOCAL); - throw_sys_sub_if (!Pkcs11LibraryHandle, dlerror()); + Pkcs11LibraryHandle = dlopen(pkcs11LibraryPath.c_str(), RTLD_NOW | RTLD_LOCAL); + throw_sys_sub_if(!Pkcs11LibraryHandle, dlerror()); #endif - typedef CK_RV (*C_GetFunctionList_t) (CK_FUNCTION_LIST_PTR_PTR ppFunctionList); + typedef CK_RV(*C_GetFunctionList_t) (CK_FUNCTION_LIST_PTR_PTR ppFunctionList); #ifdef TC_WINDOWS - C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t) GetProcAddress (Pkcs11LibraryHandle, "C_GetFunctionList"); + C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t)GetProcAddress(Pkcs11LibraryHandle, "C_GetFunctionList"); #else - C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t) dlsym (Pkcs11LibraryHandle, "C_GetFunctionList"); + C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t)dlsym(Pkcs11LibraryHandle, "C_GetFunctionList"); #endif if (!C_GetFunctionList) throw SecurityTokenLibraryNotInitialized(); - CK_RV status = C_GetFunctionList (&Pkcs11Functions); + CK_RV status = C_GetFunctionList(&Pkcs11Functions); if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); - status = Pkcs11Functions->C_Initialize (NULL_PTR); + status = Pkcs11Functions->C_Initialize(NULL_PTR); if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); PinCallback = move_ptr(pinCallback); WarningCallback = move_ptr(warningCallback); @@ -554,21 +562,21 @@ namespace VeraCrypt Initialized = true; } - void SecurityToken::OpenSession (CK_SLOT_ID slotId) + void SecurityToken::OpenSession(CK_SLOT_ID slotId) { - if (Sessions.find (slotId) != Sessions.end()) + if (Sessions.find(slotId) != Sessions.end()) return; CK_SESSION_HANDLE session; CK_FLAGS flags = CKF_SERIAL_SESSION; - if (!(GetTokenInfo (slotId).Flags & CKF_WRITE_PROTECTED)) - flags |= CKF_RW_SESSION; + if (!(GetTokenInfo(slotId).Flags & CKF_WRITE_PROTECTED)) + flags |= CKF_RW_SESSION; - CK_RV status = Pkcs11Functions->C_OpenSession (slotId, flags, NULL_PTR, NULL_PTR, &session); + CK_RV status = Pkcs11Functions->C_OpenSession(slotId, flags, NULL_PTR, NULL_PTR, &session); if (status != CKR_OK) - throw Pkcs11Exception (status); + throw Pkcs11Exception(status); Sessions[slotId].Handle = session; } @@ -581,103 +589,103 @@ namespace VeraCrypt static const struct { CK_RV ErrorCode; - const char *ErrorString; + const char* ErrorString; } ErrorStrings[] = { # define TC_TOKEN_ERR(CODE) { CODE, #CODE }, - TC_TOKEN_ERR (CKR_CANCEL) - TC_TOKEN_ERR (CKR_HOST_MEMORY) - TC_TOKEN_ERR (CKR_SLOT_ID_INVALID) - TC_TOKEN_ERR (CKR_GENERAL_ERROR) - TC_TOKEN_ERR (CKR_FUNCTION_FAILED) - TC_TOKEN_ERR (CKR_ARGUMENTS_BAD) - TC_TOKEN_ERR (CKR_NO_EVENT) - TC_TOKEN_ERR (CKR_NEED_TO_CREATE_THREADS) - TC_TOKEN_ERR (CKR_CANT_LOCK) - TC_TOKEN_ERR (CKR_ATTRIBUTE_READ_ONLY) - TC_TOKEN_ERR (CKR_ATTRIBUTE_SENSITIVE) - TC_TOKEN_ERR (CKR_ATTRIBUTE_TYPE_INVALID) - TC_TOKEN_ERR (CKR_ATTRIBUTE_VALUE_INVALID) - TC_TOKEN_ERR (CKR_DATA_INVALID) - TC_TOKEN_ERR (CKR_DATA_LEN_RANGE) - TC_TOKEN_ERR (CKR_DEVICE_ERROR) - TC_TOKEN_ERR (CKR_DEVICE_MEMORY) - TC_TOKEN_ERR (CKR_DEVICE_REMOVED) - TC_TOKEN_ERR (CKR_ENCRYPTED_DATA_INVALID) - TC_TOKEN_ERR (CKR_ENCRYPTED_DATA_LEN_RANGE) - TC_TOKEN_ERR (CKR_FUNCTION_CANCELED) - TC_TOKEN_ERR (CKR_FUNCTION_NOT_PARALLEL) - TC_TOKEN_ERR (CKR_FUNCTION_NOT_SUPPORTED) - TC_TOKEN_ERR (CKR_KEY_HANDLE_INVALID) - TC_TOKEN_ERR (CKR_KEY_SIZE_RANGE) - TC_TOKEN_ERR (CKR_KEY_TYPE_INCONSISTENT) - TC_TOKEN_ERR (CKR_KEY_NOT_NEEDED) - TC_TOKEN_ERR (CKR_KEY_CHANGED) - TC_TOKEN_ERR (CKR_KEY_NEEDED) - TC_TOKEN_ERR (CKR_KEY_INDIGESTIBLE) - TC_TOKEN_ERR (CKR_KEY_FUNCTION_NOT_PERMITTED) - TC_TOKEN_ERR (CKR_KEY_NOT_WRAPPABLE) - TC_TOKEN_ERR (CKR_KEY_UNEXTRACTABLE) - TC_TOKEN_ERR (CKR_MECHANISM_INVALID) - TC_TOKEN_ERR (CKR_MECHANISM_PARAM_INVALID) - TC_TOKEN_ERR (CKR_OBJECT_HANDLE_INVALID) - TC_TOKEN_ERR (CKR_OPERATION_ACTIVE) - TC_TOKEN_ERR (CKR_OPERATION_NOT_INITIALIZED) - TC_TOKEN_ERR (CKR_PIN_INCORRECT) - TC_TOKEN_ERR (CKR_PIN_INVALID) - TC_TOKEN_ERR (CKR_PIN_LEN_RANGE) - TC_TOKEN_ERR (CKR_PIN_EXPIRED) - TC_TOKEN_ERR (CKR_PIN_LOCKED) - TC_TOKEN_ERR (CKR_SESSION_CLOSED) - TC_TOKEN_ERR (CKR_SESSION_COUNT) - TC_TOKEN_ERR (CKR_SESSION_HANDLE_INVALID) - TC_TOKEN_ERR (CKR_SESSION_PARALLEL_NOT_SUPPORTED) - TC_TOKEN_ERR (CKR_SESSION_READ_ONLY) - TC_TOKEN_ERR (CKR_SESSION_EXISTS) - TC_TOKEN_ERR (CKR_SESSION_READ_ONLY_EXISTS) - TC_TOKEN_ERR (CKR_SESSION_READ_WRITE_SO_EXISTS) - TC_TOKEN_ERR (CKR_SIGNATURE_INVALID) - TC_TOKEN_ERR (CKR_SIGNATURE_LEN_RANGE) - TC_TOKEN_ERR (CKR_TEMPLATE_INCOMPLETE) - TC_TOKEN_ERR (CKR_TEMPLATE_INCONSISTENT) - TC_TOKEN_ERR (CKR_TOKEN_NOT_PRESENT) - TC_TOKEN_ERR (CKR_TOKEN_NOT_RECOGNIZED) - TC_TOKEN_ERR (CKR_TOKEN_WRITE_PROTECTED) - TC_TOKEN_ERR (CKR_UNWRAPPING_KEY_HANDLE_INVALID) - TC_TOKEN_ERR (CKR_UNWRAPPING_KEY_SIZE_RANGE) - TC_TOKEN_ERR (CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT) - TC_TOKEN_ERR (CKR_USER_ALREADY_LOGGED_IN) - TC_TOKEN_ERR (CKR_USER_NOT_LOGGED_IN) - TC_TOKEN_ERR (CKR_USER_PIN_NOT_INITIALIZED) - TC_TOKEN_ERR (CKR_USER_TYPE_INVALID) - TC_TOKEN_ERR (CKR_USER_ANOTHER_ALREADY_LOGGED_IN) - TC_TOKEN_ERR (CKR_USER_TOO_MANY_TYPES) - TC_TOKEN_ERR (CKR_WRAPPED_KEY_INVALID) - TC_TOKEN_ERR (CKR_WRAPPED_KEY_LEN_RANGE) - TC_TOKEN_ERR (CKR_WRAPPING_KEY_HANDLE_INVALID) - TC_TOKEN_ERR (CKR_WRAPPING_KEY_SIZE_RANGE) - TC_TOKEN_ERR (CKR_WRAPPING_KEY_TYPE_INCONSISTENT) - TC_TOKEN_ERR (CKR_RANDOM_SEED_NOT_SUPPORTED) - TC_TOKEN_ERR (CKR_RANDOM_NO_RNG) - TC_TOKEN_ERR (CKR_DOMAIN_PARAMS_INVALID) - TC_TOKEN_ERR (CKR_BUFFER_TOO_SMALL) - TC_TOKEN_ERR (CKR_SAVED_STATE_INVALID) - TC_TOKEN_ERR (CKR_INFORMATION_SENSITIVE) - TC_TOKEN_ERR (CKR_STATE_UNSAVEABLE) - TC_TOKEN_ERR (CKR_CRYPTOKI_NOT_INITIALIZED) - TC_TOKEN_ERR (CKR_CRYPTOKI_ALREADY_INITIALIZED) - TC_TOKEN_ERR (CKR_MUTEX_BAD) - TC_TOKEN_ERR (CKR_MUTEX_NOT_LOCKED) - TC_TOKEN_ERR (CKR_NEW_PIN_MODE) - TC_TOKEN_ERR (CKR_NEXT_OTP) - TC_TOKEN_ERR (CKR_FUNCTION_REJECTED) + TC_TOKEN_ERR(CKR_CANCEL) + TC_TOKEN_ERR(CKR_HOST_MEMORY) + TC_TOKEN_ERR(CKR_SLOT_ID_INVALID) + TC_TOKEN_ERR(CKR_GENERAL_ERROR) + TC_TOKEN_ERR(CKR_FUNCTION_FAILED) + TC_TOKEN_ERR(CKR_ARGUMENTS_BAD) + TC_TOKEN_ERR(CKR_NO_EVENT) + TC_TOKEN_ERR(CKR_NEED_TO_CREATE_THREADS) + TC_TOKEN_ERR(CKR_CANT_LOCK) + TC_TOKEN_ERR(CKR_ATTRIBUTE_READ_ONLY) + TC_TOKEN_ERR(CKR_ATTRIBUTE_SENSITIVE) + TC_TOKEN_ERR(CKR_ATTRIBUTE_TYPE_INVALID) + TC_TOKEN_ERR(CKR_ATTRIBUTE_VALUE_INVALID) + TC_TOKEN_ERR(CKR_DATA_INVALID) + TC_TOKEN_ERR(CKR_DATA_LEN_RANGE) + TC_TOKEN_ERR(CKR_DEVICE_ERROR) + TC_TOKEN_ERR(CKR_DEVICE_MEMORY) + TC_TOKEN_ERR(CKR_DEVICE_REMOVED) + TC_TOKEN_ERR(CKR_ENCRYPTED_DATA_INVALID) + TC_TOKEN_ERR(CKR_ENCRYPTED_DATA_LEN_RANGE) + TC_TOKEN_ERR(CKR_FUNCTION_CANCELED) + TC_TOKEN_ERR(CKR_FUNCTION_NOT_PARALLEL) + TC_TOKEN_ERR(CKR_FUNCTION_NOT_SUPPORTED) + TC_TOKEN_ERR(CKR_KEY_HANDLE_INVALID) + TC_TOKEN_ERR(CKR_KEY_SIZE_RANGE) + TC_TOKEN_ERR(CKR_KEY_TYPE_INCONSISTENT) + TC_TOKEN_ERR(CKR_KEY_NOT_NEEDED) + TC_TOKEN_ERR(CKR_KEY_CHANGED) + TC_TOKEN_ERR(CKR_KEY_NEEDED) + TC_TOKEN_ERR(CKR_KEY_INDIGESTIBLE) + TC_TOKEN_ERR(CKR_KEY_FUNCTION_NOT_PERMITTED) + TC_TOKEN_ERR(CKR_KEY_NOT_WRAPPABLE) + TC_TOKEN_ERR(CKR_KEY_UNEXTRACTABLE) + TC_TOKEN_ERR(CKR_MECHANISM_INVALID) + TC_TOKEN_ERR(CKR_MECHANISM_PARAM_INVALID) + TC_TOKEN_ERR(CKR_OBJECT_HANDLE_INVALID) + TC_TOKEN_ERR(CKR_OPERATION_ACTIVE) + TC_TOKEN_ERR(CKR_OPERATION_NOT_INITIALIZED) + TC_TOKEN_ERR(CKR_PIN_INCORRECT) + TC_TOKEN_ERR(CKR_PIN_INVALID) + TC_TOKEN_ERR(CKR_PIN_LEN_RANGE) + TC_TOKEN_ERR(CKR_PIN_EXPIRED) + TC_TOKEN_ERR(CKR_PIN_LOCKED) + TC_TOKEN_ERR(CKR_SESSION_CLOSED) + TC_TOKEN_ERR(CKR_SESSION_COUNT) + TC_TOKEN_ERR(CKR_SESSION_HANDLE_INVALID) + TC_TOKEN_ERR(CKR_SESSION_PARALLEL_NOT_SUPPORTED) + TC_TOKEN_ERR(CKR_SESSION_READ_ONLY) + TC_TOKEN_ERR(CKR_SESSION_EXISTS) + TC_TOKEN_ERR(CKR_SESSION_READ_ONLY_EXISTS) + TC_TOKEN_ERR(CKR_SESSION_READ_WRITE_SO_EXISTS) + TC_TOKEN_ERR(CKR_SIGNATURE_INVALID) + TC_TOKEN_ERR(CKR_SIGNATURE_LEN_RANGE) + TC_TOKEN_ERR(CKR_TEMPLATE_INCOMPLETE) + TC_TOKEN_ERR(CKR_TEMPLATE_INCONSISTENT) + TC_TOKEN_ERR(CKR_TOKEN_NOT_PRESENT) + TC_TOKEN_ERR(CKR_TOKEN_NOT_RECOGNIZED) + TC_TOKEN_ERR(CKR_TOKEN_WRITE_PROTECTED) + TC_TOKEN_ERR(CKR_UNWRAPPING_KEY_HANDLE_INVALID) + TC_TOKEN_ERR(CKR_UNWRAPPING_KEY_SIZE_RANGE) + TC_TOKEN_ERR(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT) + TC_TOKEN_ERR(CKR_USER_ALREADY_LOGGED_IN) + TC_TOKEN_ERR(CKR_USER_NOT_LOGGED_IN) + TC_TOKEN_ERR(CKR_USER_PIN_NOT_INITIALIZED) + TC_TOKEN_ERR(CKR_USER_TYPE_INVALID) + TC_TOKEN_ERR(CKR_USER_ANOTHER_ALREADY_LOGGED_IN) + TC_TOKEN_ERR(CKR_USER_TOO_MANY_TYPES) + TC_TOKEN_ERR(CKR_WRAPPED_KEY_INVALID) + TC_TOKEN_ERR(CKR_WRAPPED_KEY_LEN_RANGE) + TC_TOKEN_ERR(CKR_WRAPPING_KEY_HANDLE_INVALID) + TC_TOKEN_ERR(CKR_WRAPPING_KEY_SIZE_RANGE) + TC_TOKEN_ERR(CKR_WRAPPING_KEY_TYPE_INCONSISTENT) + TC_TOKEN_ERR(CKR_RANDOM_SEED_NOT_SUPPORTED) + TC_TOKEN_ERR(CKR_RANDOM_NO_RNG) + TC_TOKEN_ERR(CKR_DOMAIN_PARAMS_INVALID) + TC_TOKEN_ERR(CKR_BUFFER_TOO_SMALL) + TC_TOKEN_ERR(CKR_SAVED_STATE_INVALID) + TC_TOKEN_ERR(CKR_INFORMATION_SENSITIVE) + TC_TOKEN_ERR(CKR_STATE_UNSAVEABLE) + TC_TOKEN_ERR(CKR_CRYPTOKI_NOT_INITIALIZED) + TC_TOKEN_ERR(CKR_CRYPTOKI_ALREADY_INITIALIZED) + TC_TOKEN_ERR(CKR_MUTEX_BAD) + TC_TOKEN_ERR(CKR_MUTEX_NOT_LOCKED) + TC_TOKEN_ERR(CKR_NEW_PIN_MODE) + TC_TOKEN_ERR(CKR_NEXT_OTP) + TC_TOKEN_ERR(CKR_FUNCTION_REJECTED) #undef TC_TOKEN_ERR }; - for (size_t i = 0; i < array_capacity (ErrorStrings); ++i) + for (size_t i = 0; i < array_capacity(ErrorStrings); ++i) { if (ErrorStrings[i].ErrorCode == ErrorCode) return ErrorStrings[i].ErrorString; @@ -690,9 +698,9 @@ namespace VeraCrypt } #ifdef TC_HEADER_Common_Exception - void Pkcs11Exception::Show (HWND parent) const + void Pkcs11Exception::Show(HWND parent) const { - string errorString = string (*this); + string errorString = string(*this); if (!errorString.empty()) { @@ -700,11 +708,11 @@ namespace VeraCrypt if (SubjectErrorCodeValid) subjectErrorCode << L": " << SubjectErrorCode; - if (!GetDictionaryValue (errorString.c_str())) + if (!GetDictionaryValue(errorString.c_str())) { - if (errorString.find ("CKR_") == 0) + if (errorString.find("CKR_") == 0) { - errorString = errorString.substr (4); + errorString = errorString.substr(4); for (size_t i = 0; i < errorString.size(); ++i) { if (errorString[i] == '_') @@ -712,17 +720,17 @@ namespace VeraCrypt } } wchar_t err[8192]; - StringCbPrintfW (err, sizeof(err),L"%s:\n\n%hs%s", GetString ("SECURITY_TOKEN_ERROR"), errorString.c_str(), subjectErrorCode.str().c_str()); - ErrorDirect (err, parent); + StringCbPrintfW(err, sizeof(err), L"%s:\n\n%hs%s", GetString("SECURITY_TOKEN_ERROR"), errorString.c_str(), subjectErrorCode.str().c_str()); + ErrorDirect(err, parent); } else { - wstring err = GetString (errorString.c_str()); + wstring err = GetString(errorString.c_str()); if (SubjectErrorCodeValid) err += L"\n\nError code" + subjectErrorCode.str(); - ErrorDirect (err.c_str(), parent); + ErrorDirect(err.c_str(), parent); } } } @@ -738,36 +746,36 @@ namespace VeraCrypt #ifdef TC_WINDOWS HMODULE SecurityToken::Pkcs11LibraryHandle; #else - void *SecurityToken::Pkcs11LibraryHandle; + void* SecurityToken::Pkcs11LibraryHandle; #endif #ifdef TC_HEADER_Platform_Exception - void Pkcs11Exception::Deserialize (shared_ptr stream) + void Pkcs11Exception::Deserialize(shared_ptr stream) { - Exception::Deserialize (stream); - Serializer sr (stream); + Exception::Deserialize(stream); + Serializer sr(stream); uint64 code; - sr.Deserialize ("ErrorCode", code); - sr.Deserialize ("SubjectErrorCodeValid", SubjectErrorCodeValid); - sr.Deserialize ("SubjectErrorCode", SubjectErrorCode); - ErrorCode = (CK_RV) code; + sr.Deserialize("ErrorCode", code); + sr.Deserialize("SubjectErrorCodeValid", SubjectErrorCodeValid); + sr.Deserialize("SubjectErrorCode", SubjectErrorCode); + ErrorCode = (CK_RV)code; } - void Pkcs11Exception::Serialize (shared_ptr stream) const + void Pkcs11Exception::Serialize(shared_ptr stream) const { - Exception::Serialize (stream); - Serializer sr (stream); - sr.Serialize ("ErrorCode", (uint64) ErrorCode); - sr.Serialize ("SubjectErrorCodeValid", SubjectErrorCodeValid); - sr.Serialize ("SubjectErrorCode", SubjectErrorCode); + Exception::Serialize(stream); + Serializer sr(stream); + sr.Serialize("ErrorCode", (uint64)ErrorCode); + sr.Serialize("SubjectErrorCodeValid", SubjectErrorCodeValid); + sr.Serialize("SubjectErrorCode", SubjectErrorCode); } # define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) # undef TC_EXCEPTION_NODECL # define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) - TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (SecurityTokenException); + TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET(SecurityTokenException); #endif } diff --git a/src/Common/SecurityToken.h b/src/Common/SecurityToken.h index 6b228895..0d671dcc 100644 --- a/src/Common/SecurityToken.h +++ b/src/Common/SecurityToken.h @@ -53,62 +53,55 @@ #define TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"slot" #define TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"file" +#include "Token.h" + namespace VeraCrypt { - struct SecurityTokenInfo + struct SecurityTokenInfo: TokenInfo { - CK_SLOT_ID SlotId; + virtual BOOL isEditable() const {return true;} + CK_FLAGS Flags; - wstring Label; string LabelUtf8; }; - struct SecurityTokenKeyfilePath + struct SecurityTokenKeyfile: TokenKeyfile { - SecurityTokenKeyfilePath () { } - SecurityTokenKeyfilePath (const wstring &path) : Path (path) { } - operator wstring () const { return Path; } - wstring Path; - }; + SecurityTokenKeyfile(); - 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 TokenKeyfilePath& path); + + operator TokenKeyfilePath () const; - operator SecurityTokenKeyfilePath () const; + void GetKeyfileData(vector& keyfileData) const; CK_OBJECT_HANDLE Handle; - wstring Id; - string IdUtf8; - CK_SLOT_ID SlotId; - SecurityTokenInfo Token; }; - struct Pkcs11Exception : public Exception + struct Pkcs11Exception: public Exception { - Pkcs11Exception (CK_RV errorCode = (CK_RV) -1) - : ErrorCode (errorCode), - SubjectErrorCodeValid (false), - SubjectErrorCode( (uint64) -1) + Pkcs11Exception(CK_RV errorCode = (CK_RV)-1) + : ErrorCode(errorCode), + SubjectErrorCodeValid(false), + SubjectErrorCode((uint64)-1) { } - Pkcs11Exception (CK_RV errorCode, uint64 subjectErrorCode) - : ErrorCode (errorCode), - SubjectErrorCodeValid (true), - SubjectErrorCode (subjectErrorCode) + Pkcs11Exception(CK_RV errorCode, uint64 subjectErrorCode) + : ErrorCode(errorCode), + SubjectErrorCodeValid(true), + SubjectErrorCode(subjectErrorCode) { } #ifdef TC_HEADER_Platform_Exception - virtual ~Pkcs11Exception () throw () { } - TC_SERIALIZABLE_EXCEPTION (Pkcs11Exception); + virtual ~Pkcs11Exception() throw () { } + TC_SERIALIZABLE_EXCEPTION(Pkcs11Exception); #else - void Show (HWND parent) const; + void Show(HWND parent) const; #endif operator string () const; - CK_RV GetErrorCode () const { return ErrorCode; } + CK_RV GetErrorCode() const { return ErrorCode; } protected: CK_RV ErrorCode; @@ -135,24 +128,24 @@ namespace VeraCrypt #else // !TC_HEADER_Platform_Exception - struct SecurityTokenLibraryNotInitialized : public Exception + struct SecurityTokenLibraryNotInitialized: public Exception { - void Show (HWND parent) const { Error (SecurityTokenLibraryPath[0] == 0 ? "NO_PKCS11_MODULE_SPECIFIED" : "PKCS11_MODULE_INIT_FAILED", parent); } + void Show(HWND parent) const { Error(SecurityTokenLibraryPath[0] == 0 ? "NO_PKCS11_MODULE_SPECIFIED" : "PKCS11_MODULE_INIT_FAILED", parent); } }; - struct InvalidSecurityTokenKeyfilePath : public Exception + struct InvalidSecurityTokenKeyfilePath: public Exception { - void Show (HWND parent) const { Error ("INVALID_TOKEN_KEYFILE_PATH", parent); } + void Show(HWND parent) const { Error("INVALID_TOKEN_KEYFILE_PATH", parent); } }; - struct SecurityTokenKeyfileAlreadyExists : public Exception + struct SecurityTokenKeyfileAlreadyExists: public Exception { - void Show (HWND parent) const { Error ("TOKEN_KEYFILE_ALREADY_EXISTS", parent); } + void Show(HWND parent) const { Error("TOKEN_KEYFILE_ALREADY_EXISTS", parent); } }; - struct SecurityTokenKeyfileNotFound : public Exception + struct SecurityTokenKeyfileNotFound: public Exception { - void Show (HWND parent) const { Error ("TOKEN_KEYFILE_NOT_FOUND", parent); } + void Show(HWND parent) const { Error("TOKEN_KEYFILE_NOT_FOUND", parent); } }; #endif // !TC_HEADER_Platform_Exception @@ -160,7 +153,7 @@ namespace VeraCrypt struct Pkcs11Session { - Pkcs11Session () : Handle (CK_UNAVAILABLE_INFORMATION), UserLoggedIn (false) { } + Pkcs11Session(): Handle(CK_UNAVAILABLE_INFORMATION), UserLoggedIn(false) { } CK_SESSION_HANDLE Handle; bool UserLoggedIn; @@ -168,47 +161,46 @@ namespace VeraCrypt struct GetPinFunctor { - virtual ~GetPinFunctor () { } - virtual void operator() (string &str) = 0; - virtual void notifyIncorrectPin () = 0; + virtual ~GetPinFunctor() { } + virtual void operator() (string& str) = 0; + virtual void notifyIncorrectPin() = 0; }; struct SendExceptionFunctor { - virtual ~SendExceptionFunctor () { } - virtual void operator() (const Exception &e) = 0; + virtual ~SendExceptionFunctor() { } + virtual void operator() (const Exception& e) = 0; }; class SecurityToken { public: - static void CloseAllSessions () throw (); - 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()); - static void GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector &keyfileData); - static list GetAvailableTokens (); - static SecurityTokenInfo GetTokenInfo (CK_SLOT_ID slotId); + static void CloseAllSessions() throw (); + 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()); + static list GetAvailableTokens(); + static SecurityTokenInfo GetTokenInfo(CK_SLOT_ID slotId); #ifdef TC_WINDOWS - static void InitLibrary (const wstring &pkcs11LibraryPath, unique_ptr pinCallback, unique_ptr warningCallback); + static void InitLibrary(const wstring& pkcs11LibraryPath, unique_ptr pinCallback, unique_ptr warningCallback); #else - static void InitLibrary (const string &pkcs11LibraryPath, unique_ptr pinCallback, unique_ptr warningCallback); + static void InitLibrary(const string& pkcs11LibraryPath, unique_ptr pinCallback, unique_ptr warningCallback); #endif - static bool IsInitialized () { return Initialized; } - static bool IsKeyfilePathValid (const wstring &securityTokenKeyfilePath); + static bool IsInitialized() { return Initialized; } + static bool IsKeyfilePathValid(const wstring& securityTokenKeyfilePath); static const size_t MaxPasswordLength = 128; protected: - static void CloseSession (CK_SLOT_ID slotId); - static vector 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 &attributeValue); - static list GetTokenSlots (); - static void Login (CK_SLOT_ID slotId, const char* pin); - static void LoginUserIfRequired (CK_SLOT_ID slotId); - static void OpenSession (CK_SLOT_ID slotId); - static void CheckLibraryStatus (); + static void CloseSession(CK_SLOT_ID slotId); + static vector 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 & attributeValue); + static list GetTokenSlots(); + static void Login(CK_SLOT_ID slotId, const char* pin); + static void LoginUserIfRequired(CK_SLOT_ID slotId); + static void OpenSession(CK_SLOT_ID slotId); + static void CheckLibraryStatus(); static bool Initialized; static unique_ptr PinCallback; @@ -216,10 +208,12 @@ namespace VeraCrypt #ifdef TC_WINDOWS static HMODULE Pkcs11LibraryHandle; #else - static void *Pkcs11LibraryHandle; + static void* Pkcs11LibraryHandle; #endif static map Sessions; static unique_ptr WarningCallback; + + friend void SecurityTokenKeyfile::GetKeyfileData(vector & keyfileData) const; }; } diff --git a/src/Common/TLVParser.cpp b/src/Common/TLVParser.cpp new file mode 100644 index 00000000..bda9dec0 --- /dev/null +++ b/src/Common/TLVParser.cpp @@ -0,0 +1,179 @@ +#include "TLVParser.h" +#include + +using namespace std; + +/* TLV node structure creation */ +shared_ptr TLVParser::TLV_CreateNode() +{ + shared_ptr node= shared_ptr(new TLVNode); + memset(node.get(),0,sizeof(*node)); + return node; +} + +/* Check if the bit is correct */ +uint16_t TLVParser::CheckBit(unsigned char value, int bit){ + unsigned char bitvalue[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; + + if((bit >= 1)&&(bit <= 8)){ + if(value & bitvalue[bit-1]) { + return (1); + } + else { + return (0); + } + } + else{ + throw TLVException("FILE:"+string(__FILE__)+"LINE: "+to_string(static_cast((__LINE__)))+" fonction parameter incorrect! bit=["+to_string(static_cast(bit))); + return(2); + } +} + +/* Parsing one TLV node */ +shared_ptr TLVParser::TLV_Parse_One(unsigned char* buf,int size){ + int index = 0; + int i; + unsigned char tag1,tag2,tagsize; + unsigned char len,lensize; + unsigned char* value; + shared_ptr node = TLV_CreateNode(); + + tag1 = tag2 = 0; + tagsize = 1; + tag1 = buf[index++]; + if((tag1 & 0x1f) == 0x1f){ + tagsize++; + tag2 = buf[index++]; + //tag2 b8 must be 0! + } + if(tagsize == 1) { + node->Tag = tag1; + } + else { + node->Tag = (tag1 << 8) + tag2; + } + node->TagSize = tagsize; + + //SubFlag + node->SubFlag = CheckBit(tag1,6); + + //L zone + len = 0; + lensize = 1; + len = buf[index++]; + if(CheckBit(len,8) == 0){ + node->Length = len; + } + else{ + lensize = len & 0x7f; + len = 0; + for(i=0;iLength = len; + node->LengthSize = lensize; + + //V zone + value = new unsigned char[len]; + std::copy(buf+index,buf+index+len,value); + node->Value = value; + index += len; + + if(index < size){ + node->MoreFlag = 1; + } + else if(index == size){ + node->MoreFlag = 0; + } + else{ + throw TLVException("Parse Error! index="+to_string(static_cast(index))+"size="+to_string(static_cast(size))); + } + + return node; +} + +/* Parsing all sub-nodes (in width not in depth) of a given parent node */ +int TLVParser::TLV_Parse_SubNodes(shared_ptr parent){ + int sublen = 0; + int i; + + //No sub-nodes + if(parent->SubFlag == 0) + return 0; + + for(i=0;iSubCount;i++) + { + sublen += (parent->Sub[i]->TagSize + parent->Sub[i]->Length + parent->Sub[i]->LengthSize); + } + + if(sublen < parent->Length) + { + shared_ptr subnode = TLV_Parse_One(parent->Value+sublen,parent->Length-sublen); + parent->Sub[parent->SubCount++] = subnode; + return subnode->MoreFlag; + } + else + { + return 0; + } +} + +/* Recursive function to parse all nodes starting from a root parent node */ +void TLVParser::TLV_Parse_Sub(shared_ptr parent) +{ + int i; + if(parent->SubFlag != 0) + { + //Parse all sub nodes. + while(TLV_Parse_SubNodes(parent) != 0); + + for(i=0;iSubCount;i++) + { + if(parent->Sub[i]->SubFlag != 0) + { + TLV_Parse_Sub(parent->Sub[i]); + } + } + } + return; +} + +/* Parsing TLV from a buffer and constructing TLV structure */ +shared_ptr TLVParser::TLV_Parse(unsigned char* buf,int size) +{ + shared_ptr node = TLV_Parse_One(buf,size); + TLV_Parse_Sub(node); + + return node; +} + +/* Finding a TLV node with a particular tag */ +shared_ptr TLVParser::TLV_Find(shared_ptr node,uint16_t tag){ + int i; + shared_ptr tmpnode; + if(node->Tag == tag) + { + return node; + } + for(i=0;iSubCount;i++) + { + tmpnode = NULL; + tmpnode = TLV_Find(node->Sub[i],tag); + if(tmpnode != NULL){ + return tmpnode; + } + } + if(node->Next) + { + tmpnode = NULL; + tmpnode = TLV_Find(node->Next,tag); + if(tmpnode != NULL){ + return tmpnode; + } + } + + return nullptr; +} + diff --git a/src/Common/TLVParser.h b/src/Common/TLVParser.h new file mode 100644 index 00000000..e25e429f --- /dev/null +++ b/src/Common/TLVParser.h @@ -0,0 +1,80 @@ +// +// Created by bshp on 1/20/23. +// + +#ifndef ICC_EXTRACTOR_TLVPARSER_H +#define ICC_EXTRACTOR_TLVPARSER_H +#include +#include +#include +#include +#include +#include +#include "iostream" +#include "Tcdefs.h" +using namespace std; +struct TLVNode{ + uint16_t Tag; /* T */ + uint16_t Length; /* L */ + unsigned char* Value; /* V */ + unsigned char TagSize; + unsigned char LengthSize; + uint16_t MoreFlag; /* Used In Sub */ + uint16_t SubFlag; /* Does it have sub-nodes? */ + uint16_t SubCount; + shared_ptr Sub[256]; + shared_ptr Next; + + ~TLVNode() { + burn(Value, Length); + delete Value; + } +}; + +class TLVParser{ +private : + + /* TLV node structure creation */ + static shared_ptr TLV_CreateNode(); + + /* Check if the bit is correct */ + static uint16_t CheckBit(unsigned char value, int bit); + + /* Parsing one TLV node */ + static shared_ptr TLV_Parse_One(unsigned char* buf,int size); + + /* Parsing all TLV nodes */ + static int TLV_Parse_SubNodes(shared_ptr parent); + + /* Parsing all sub-nodes (in width not in depth) of a given parent node */ + static int TLV_Parse_All(shared_ptr parent); + + /* Recursive function to parse all nodes starting from a root parent node */ + static void TLV_Parse_Sub(shared_ptr parent); + +public: + + /* Parsing TLV from a buffer and constructing TLV structure */ + static shared_ptr TLV_Parse(unsigned char* buf,int size); + + /* Finding a TLV node with a particular tag */ + static shared_ptr TLV_Find(shared_ptr node,uint16_t tag); +}; + +/* The definition of the exception class related to the TLV parsing */ +class TLVException +{ +public: + TLVException(std::string errormessage): m_errormessage(errormessage){} + + /* Get the error message */ + inline std::string ErrorMessage() const + { + return m_errormessage; + } + +protected: + std::string m_errormessage; +}; + +#endif //ICC_EXTRACTOR_TLVPARSER_H diff --git a/src/Common/Token.cpp b/src/Common/Token.cpp new file mode 100644 index 00000000..5da677de --- /dev/null +++ b/src/Common/Token.cpp @@ -0,0 +1,82 @@ +#include "Token.h" +#include "Platform/Finally.h" +#include "Platform/ForEach.h" + +#if !defined(TC_WINDOWS) || defined(TC_PROTOTYPE) +#include "Platform/SerializerFactory.h" +#include "Platform/StringConverter.h" +#include "Platform/SystemException.h" +#else +#include "Dictionary.h" +#include "Language.h" +#endif + +#include +#include +#include + +#include "SecurityToken.h" +#include "EMVToken.h" +#include "iostream" + +using namespace std; + +namespace VeraCrypt +{ + vector> Token::GetAvailableKeyfiles(bool EMVOption) { + vector> availableKeyfiles; + bool securityTokenLibraryInitialized = true; + + try{ + foreach (SecurityTokenKeyfile k, SecurityToken::GetAvailableKeyfiles()) { + availableKeyfiles.push_back(shared_ptr(new SecurityTokenKeyfile(k))); + } + } catch (SecurityTokenLibraryNotInitialized){ + securityTokenLibraryInitialized = false; + } + + if(EMVOption){ + foreach (EMVTokenKeyfile k, EMVToken::GetAvailableKeyfiles()) { + availableKeyfiles.push_back(shared_ptr(new EMVTokenKeyfile(k))); + } + } + + if(availableKeyfiles.size() == 0 && ! securityTokenLibraryInitialized){ + throw SecurityTokenLibraryNotInitialized(); + } + + return availableKeyfiles; + } + + bool Token::IsKeyfilePathValid(const wstring& tokenKeyfilePath, bool EMVOption) + { + if(EMVOption){ + return SecurityToken::IsKeyfilePathValid(tokenKeyfilePath) || EMVToken::IsKeyfilePathValid(tokenKeyfilePath); + } + return SecurityToken::IsKeyfilePathValid(tokenKeyfilePath); + } + + list > Token::GetAvailableTokens() + { + list > availableTokens; + foreach(SecurityTokenInfo securityToken, SecurityToken::GetAvailableTokens()){ + availableTokens.push_back(shared_ptr(new SecurityTokenInfo(std::move(securityToken)))); + } + + return availableTokens ; + } + + shared_ptr Token::getTokenKeyfile(const TokenKeyfilePath path){ + shared_ptr tokenKeyfile; + + if(SecurityToken::IsKeyfilePathValid(path)){ + tokenKeyfile = shared_ptr(new SecurityTokenKeyfile(path)); + } else { + if(EMVToken::IsKeyfilePathValid(path)){ + tokenKeyfile = shared_ptr(new EMVTokenKeyfile(path)); + } + } + + return tokenKeyfile; + } +} \ No newline at end of file diff --git a/src/Common/Token.h b/src/Common/Token.h new file mode 100644 index 00000000..28c6a489 --- /dev/null +++ b/src/Common/Token.h @@ -0,0 +1,57 @@ +#ifndef TC_HEADER_Common_Token +#define TC_HEADER_Common_Token + +#include "Platform/PlatformBase.h" + +#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE) +# include "Exception.h" +#else + +# include "Platform/Exception.h" + +#endif + +#include + +#define UNAVAILABLE_SLOT ~0UL + +namespace VeraCrypt { + + struct TokenKeyfilePath { + TokenKeyfilePath(const wstring& path): Path(path) { } + operator wstring () const { return Path; } + + wstring Path; //Complete path + + }; + struct TokenInfo { + TokenInfo() {} + virtual ~TokenInfo() {} + + virtual BOOL isEditable() const=0; + + unsigned long int SlotId; + wstring Label; //Card name + }; + + struct TokenKeyfile { + virtual operator TokenKeyfilePath () const = 0; + virtual void GetKeyfileData(vector & keyfileData) const = 0; + + string IdUtf8; // Was used in SecurityToken to compare with the file name from a PKCS11 card, remove from token ? + shared_ptr Token; + wstring Id; + }; + + class Token { + public: + static vector> GetAvailableKeyfiles(bool EMVOption); + static bool IsKeyfilePathValid(const wstring& tokenKeyfilePath, bool EMVOption); + static list > GetAvailableTokens(); // List available token to write + static shared_ptr getTokenKeyfile(const TokenKeyfilePath path); + }; + +}; + + +#endif //TC_HEADER_Common_Token diff --git a/src/Core/Core.h b/src/Core/Core.h index 3a2235a5..d2a4c593 100644 --- a/src/Core/Core.h +++ b/src/Core/Core.h @@ -82,9 +82,10 @@ namespace VeraCrypt shared_ptr m_newKeyfiles; shared_ptr m_newPkcs5Kdf; int m_wipeCount; - ChangePasswordThreadRoutine(shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, shared_ptr newPassword, int newPim, shared_ptr newKeyfiles, shared_ptr newPkcs5Kdf, int wipeCount) : m_volumePath(volumePath), m_preserveTimestamps(preserveTimestamps), m_password(password), m_pim(pim), m_kdf(kdf), m_truecryptMode(truecryptMode), m_keyfiles(keyfiles), m_newPassword(newPassword), m_newPim(newPim), m_newKeyfiles(newKeyfiles), m_newPkcs5Kdf(newPkcs5Kdf), m_wipeCount(wipeCount) {} + bool m_emvoption; + ChangePasswordThreadRoutine(shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, shared_ptr newPassword, int newPim, shared_ptr newKeyfiles, shared_ptr newPkcs5Kdf, int wipeCount, bool EMVOption) : m_volumePath(volumePath), m_preserveTimestamps(preserveTimestamps), m_password(password), m_pim(pim), m_kdf(kdf), m_truecryptMode(truecryptMode), m_keyfiles(keyfiles), m_newPassword(newPassword), m_newPim(newPim), m_newKeyfiles(newKeyfiles), m_newPkcs5Kdf(newPkcs5Kdf), m_wipeCount(wipeCount), m_emvoption(EMVOption) {} virtual ~ChangePasswordThreadRoutine() { } - virtual void ExecutionCode(void) { Core->ChangePassword(m_volumePath, m_preserveTimestamps, m_password, m_pim, m_kdf, m_truecryptMode, m_keyfiles, m_newPassword, m_newPim, m_newKeyfiles, m_newPkcs5Kdf, m_wipeCount); } + virtual void ExecutionCode(void) { Core->ChangePassword(m_volumePath, m_preserveTimestamps, m_password, m_pim, m_kdf, m_truecryptMode, m_keyfiles, m_newPassword, m_newPim, m_newKeyfiles, m_emvoption, m_newPkcs5Kdf, m_wipeCount); } }; class OpenVolumeThreadRoutine : public WaitThreadRoutine @@ -107,15 +108,16 @@ namespace VeraCrypt bool m_useBackupHeaders; bool m_partitionInSystemEncryptionScope; shared_ptr m_pVolume; + bool m_emvoption; - OpenVolumeThreadRoutine(shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr Kdf, bool truecryptMode, shared_ptr keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr protectionPassword = shared_ptr (), int protectionPim = 0, shared_ptr protectionKdf = shared_ptr (), shared_ptr protectionKeyfiles = shared_ptr (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false): + OpenVolumeThreadRoutine(shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr Kdf, bool truecryptMode, shared_ptr keyfiles, bool EMVOption, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr protectionPassword = shared_ptr (), int protectionPim = 0, shared_ptr protectionKdf = shared_ptr (), shared_ptr protectionKeyfiles = shared_ptr (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false): m_volumePath(volumePath), m_preserveTimestamps(preserveTimestamps), m_password(password), m_pim(pim), m_Kdf(Kdf), m_truecryptMode(truecryptMode), m_keyfiles(keyfiles), m_protection(protection), m_protectionPassword(protectionPassword), m_protectionPim(protectionPim), m_protectionKdf(protectionKdf), m_protectionKeyfiles(protectionKeyfiles), m_sharedAccessAllowed(sharedAccessAllowed), m_volumeType(volumeType),m_useBackupHeaders(useBackupHeaders), - m_partitionInSystemEncryptionScope(partitionInSystemEncryptionScope) {} + m_partitionInSystemEncryptionScope(partitionInSystemEncryptionScope), m_emvoption(EMVOption) {} ~OpenVolumeThreadRoutine() {} - virtual void ExecutionCode(void) { m_pVolume = Core->OpenVolume(m_volumePath,m_preserveTimestamps,m_password,m_pim,m_Kdf,m_truecryptMode,m_keyfiles, m_protection,m_protectionPassword,m_protectionPim,m_protectionKdf, m_protectionKeyfiles,m_sharedAccessAllowed,m_volumeType,m_useBackupHeaders, m_partitionInSystemEncryptionScope); } + virtual void ExecutionCode(void) { m_pVolume = Core->OpenVolume(m_volumePath,m_preserveTimestamps,m_password,m_pim,m_Kdf,m_truecryptMode,m_keyfiles, m_emvoption, m_protection,m_protectionPassword,m_protectionPim,m_protectionKdf, m_protectionKeyfiles,m_sharedAccessAllowed,m_volumeType,m_useBackupHeaders, m_partitionInSystemEncryptionScope); } }; @@ -127,10 +129,11 @@ namespace VeraCrypt shared_ptr m_password; int m_pim; shared_ptr m_keyfiles; - ReEncryptHeaderThreadRoutine(const BufferPtr &newHeaderBuffer, shared_ptr header, shared_ptr password, int pim, shared_ptr keyfiles) - : m_newHeaderBuffer(newHeaderBuffer), m_header(header), m_password(password), m_pim(pim), m_keyfiles(keyfiles) {} + bool m_emvoption; + ReEncryptHeaderThreadRoutine(const BufferPtr &newHeaderBuffer, shared_ptr header, shared_ptr password, int pim, shared_ptr keyfiles, bool EMVOption) + : m_newHeaderBuffer(newHeaderBuffer), m_header(header), m_password(password), m_pim(pim), m_keyfiles(keyfiles), m_emvoption(EMVOption) {} virtual ~ReEncryptHeaderThreadRoutine() { } - virtual void ExecutionCode(void) { Core->ReEncryptVolumeHeaderWithNewSalt (m_newHeaderBuffer, m_header, m_password, m_pim, m_keyfiles); } + virtual void ExecutionCode(void) { Core->ReEncryptVolumeHeaderWithNewSalt (m_newHeaderBuffer, m_header, m_password, m_pim, m_keyfiles, m_emvoption); } }; class DecryptThreadRoutine : public WaitThreadRoutine diff --git a/src/Core/CoreBase.cpp b/src/Core/CoreBase.cpp index 29bfb74d..ce6e0c20 100644 --- a/src/Core/CoreBase.cpp +++ b/src/Core/CoreBase.cpp @@ -30,7 +30,7 @@ namespace VeraCrypt { } - void CoreBase::ChangePassword (shared_ptr openVolume, shared_ptr newPassword, int newPim, shared_ptr newKeyfiles, shared_ptr newPkcs5Kdf, int wipeCount) const + void CoreBase::ChangePassword (shared_ptr openVolume, shared_ptr newPassword, int newPim, shared_ptr newKeyfiles, bool EMVOption, shared_ptr newPkcs5Kdf, int wipeCount) const { if ((!newPassword || newPassword->Size() < 1) && (!newKeyfiles || newKeyfiles->empty())) throw PasswordEmpty (SRC_POS); @@ -58,7 +58,7 @@ namespace VeraCrypt SecureBuffer newSalt (openVolume->GetSaltSize()); SecureBuffer newHeaderKey (VolumeHeader::GetLargestSerializedKeySize()); - shared_ptr password (Keyfile::ApplyListToPassword (newKeyfiles, newPassword)); + shared_ptr password (Keyfile::ApplyListToPassword (newKeyfiles, newPassword, EMVOption)); bool backupHeader = false; while (true) @@ -83,10 +83,10 @@ namespace VeraCrypt } } - void CoreBase::ChangePassword (shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, shared_ptr newPassword, int newPim, shared_ptr newKeyfiles, shared_ptr newPkcs5Kdf, int wipeCount) const + void CoreBase::ChangePassword (shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, shared_ptr newPassword, int newPim, shared_ptr newKeyfiles, bool EMVOption, shared_ptr newPkcs5Kdf, int wipeCount) const { - shared_ptr volume = OpenVolume (volumePath, preserveTimestamps, password, pim, kdf, truecryptMode, keyfiles); - ChangePassword (volume, newPassword, newPim, newKeyfiles, newPkcs5Kdf, wipeCount); + shared_ptr volume = OpenVolume (volumePath, preserveTimestamps, password, pim, kdf, truecryptMode, keyfiles, EMVOption); + ChangePassword (volume, newPassword, newPim, newKeyfiles, EMVOption, newPkcs5Kdf, wipeCount); } void CoreBase::CoalesceSlotNumberAndMountPoint (MountOptions &options) const @@ -261,10 +261,10 @@ namespace VeraCrypt return false; } - shared_ptr CoreBase::OpenVolume (shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, VolumeProtection::Enum protection, shared_ptr protectionPassword, int protectionPim, shared_ptr protectionKdf, shared_ptr protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) const + shared_ptr CoreBase::OpenVolume (shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, bool EMVOption, VolumeProtection::Enum protection, shared_ptr protectionPassword, int protectionPim, shared_ptr protectionKdf, shared_ptr protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) const { make_shared_auto (Volume, volume); - volume->Open (*volumePath, preserveTimestamps, password, pim, kdf, truecryptMode, keyfiles, protection, protectionPassword, protectionPim, protectionKdf, protectionKeyfiles, sharedAccessAllowed, volumeType, useBackupHeaders, partitionInSystemEncryptionScope); + volume->Open (*volumePath, preserveTimestamps, password, pim, kdf, truecryptMode, keyfiles, EMVOption, protection, protectionPassword, protectionPim, protectionKdf, protectionKeyfiles, sharedAccessAllowed, volumeType, useBackupHeaders, partitionInSystemEncryptionScope); return volume; } @@ -279,7 +279,7 @@ namespace VeraCrypt encryptionAlgorithm->GetMode()->SetKey (modeKey); } - void CoreBase::ReEncryptVolumeHeaderWithNewSalt (const BufferPtr &newHeaderBuffer, shared_ptr header, shared_ptr password, int pim, shared_ptr keyfiles) const + void CoreBase::ReEncryptVolumeHeaderWithNewSalt (const BufferPtr &newHeaderBuffer, shared_ptr header, shared_ptr password, int pim, shared_ptr keyfiles, bool EMVOption) const { shared_ptr pkcs5Kdf = header->GetPkcs5Kdf(); @@ -288,7 +288,7 @@ namespace VeraCrypt SecureBuffer newSalt (header->GetSaltSize()); SecureBuffer newHeaderKey (VolumeHeader::GetLargestSerializedKeySize()); - shared_ptr passwordKey (Keyfile::ApplyListToPassword (keyfiles, password)); + shared_ptr passwordKey (Keyfile::ApplyListToPassword (keyfiles, password, EMVOption)); RandomNumberGenerator::GetData (newSalt); pkcs5Kdf->DeriveKey (newHeaderKey, *passwordKey, pim, newSalt); diff --git a/src/Core/CoreBase.h b/src/Core/CoreBase.h index 8f41ddd8..8df644c3 100644 --- a/src/Core/CoreBase.h +++ b/src/Core/CoreBase.h @@ -33,8 +33,8 @@ namespace VeraCrypt public: virtual ~CoreBase (); - virtual void ChangePassword (shared_ptr openVolume, shared_ptr newPassword, int newPim, shared_ptr newKeyfiles, shared_ptr newPkcs5Kdf = shared_ptr (), int wipeCount = PRAND_HEADER_WIPE_PASSES) const; - virtual void ChangePassword (shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, shared_ptr newPassword, int newPim, shared_ptr newKeyfiles, shared_ptr newPkcs5Kdf = shared_ptr (), int wipeCount = PRAND_HEADER_WIPE_PASSES) const; + virtual void ChangePassword (shared_ptr openVolume, shared_ptr newPassword, int newPim, shared_ptr newKeyfiles, bool EMVOption, shared_ptr newPkcs5Kdf = shared_ptr (), int wipeCount = PRAND_HEADER_WIPE_PASSES) const; + virtual void ChangePassword (shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, shared_ptr newPassword, int newPim, shared_ptr newKeyfiles, bool EMVOption, shared_ptr newPkcs5Kdf = shared_ptr (), int wipeCount = PRAND_HEADER_WIPE_PASSES) const; virtual void CheckFilesystem (shared_ptr mountedVolume, bool repair = false) const = 0; virtual void CoalesceSlotNumberAndMountPoint (MountOptions &options) const; virtual void CreateKeyfile (const FilePath &keyfilePath) const; @@ -69,9 +69,9 @@ namespace VeraCrypt virtual bool IsVolumeMounted (const VolumePath &volumePath) const; virtual VolumeSlotNumber MountPointToSlotNumber (const DirectoryPath &mountPoint) const = 0; virtual shared_ptr MountVolume (MountOptions &options) = 0; - virtual shared_ptr OpenVolume (shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr Kdf, bool truecryptMode, shared_ptr keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr protectionPassword = shared_ptr (), int protectionPim = 0, shared_ptr protectionKdf = shared_ptr (), shared_ptr protectionKeyfiles = shared_ptr (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false) const; + virtual shared_ptr OpenVolume (shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr Kdf, bool truecryptMode, shared_ptr keyfiles, bool EMVOption, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr protectionPassword = shared_ptr (), int protectionPim = 0, shared_ptr protectionKdf = shared_ptr (), shared_ptr protectionKeyfiles = shared_ptr (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false) const; virtual void RandomizeEncryptionAlgorithmKey (shared_ptr encryptionAlgorithm) const; - virtual void ReEncryptVolumeHeaderWithNewSalt (const BufferPtr &newHeaderBuffer, shared_ptr header, shared_ptr password, int pim, shared_ptr keyfiles) const; + virtual void ReEncryptVolumeHeaderWithNewSalt (const BufferPtr &newHeaderBuffer, shared_ptr header, shared_ptr password, int pim, shared_ptr keyfiles, bool EMVOption) const; virtual void SetAdminPasswordCallback (shared_ptr functor) { } virtual void SetApplicationExecutablePath (const FilePath &path) { ApplicationExecutablePath = path; } virtual void SetFileOwner (const FilesystemPath &path, const UserId &owner) const = 0; diff --git a/src/Core/MountOptions.h b/src/Core/MountOptions.h index 83a8bffc..6daecadd 100644 --- a/src/Core/MountOptions.h +++ b/src/Core/MountOptions.h @@ -73,6 +73,7 @@ namespace VeraCrypt VolumeSlotNumber SlotNumber; bool UseBackupHeaders; bool TrueCryptMode; + bool EMVOption; protected: void CopyFrom (const MountOptions &other); diff --git a/src/Core/Unix/CoreServiceProxy.h b/src/Core/Unix/CoreServiceProxy.h index f5bbae3d..63b208a8 100644 --- a/src/Core/Unix/CoreServiceProxy.h +++ b/src/Core/Unix/CoreServiceProxy.h @@ -98,11 +98,11 @@ namespace VeraCrypt { MountOptions newOptions = options; - newOptions.Password = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password); + newOptions.Password = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password, options.EMVOption); if (newOptions.Keyfiles) newOptions.Keyfiles->clear(); - newOptions.ProtectionPassword = Keyfile::ApplyListToPassword (options.ProtectionKeyfiles, options.ProtectionPassword); + newOptions.ProtectionPassword = Keyfile::ApplyListToPassword (options.ProtectionKeyfiles, options.ProtectionPassword, options.EMVOption); if (newOptions.ProtectionKeyfiles) newOptions.ProtectionKeyfiles->clear(); @@ -126,7 +126,7 @@ namespace VeraCrypt if (options.CachePassword && ((options.Password && !options.Password->IsEmpty()) || (options.Keyfiles && !options.Keyfiles->empty()))) { - VolumePasswordCache::Store (*Keyfile::ApplyListToPassword (options.Keyfiles, options.Password)); + VolumePasswordCache::Store (*Keyfile::ApplyListToPassword (options.Keyfiles, options.Password, options.EMVOption)); } } diff --git a/src/Core/Unix/CoreUnix.cpp b/src/Core/Unix/CoreUnix.cpp index 56382c18..3b495e5f 100644 --- a/src/Core/Unix/CoreUnix.cpp +++ b/src/Core/Unix/CoreUnix.cpp @@ -548,6 +548,7 @@ namespace VeraCrypt options.Kdf, options.TrueCryptMode, options.Keyfiles, + options.EMVOption, options.Protection, options.ProtectionPassword, options.ProtectionPim, diff --git a/src/Core/VolumeCreator.cpp b/src/Core/VolumeCreator.cpp index 1cc45b27..8a4baeed 100644 --- a/src/Core/VolumeCreator.cpp +++ b/src/Core/VolumeCreator.cpp @@ -307,7 +307,7 @@ namespace VeraCrypt // Header key HeaderKey.Allocate (VolumeHeader::GetLargestSerializedKeySize()); - PasswordKey = Keyfile::ApplyListToPassword (options->Keyfiles, options->Password); + PasswordKey = Keyfile::ApplyListToPassword (options->Keyfiles, options->Password, options->EMVOption); options->VolumeHeaderKdf->DeriveKey (HeaderKey, *PasswordKey, options->Pim, salt); headerOptions.HeaderKey = HeaderKey; diff --git a/src/Core/VolumeCreator.h b/src/Core/VolumeCreator.h index 3e051bc7..dc742911 100644 --- a/src/Core/VolumeCreator.h +++ b/src/Core/VolumeCreator.h @@ -38,6 +38,7 @@ namespace VeraCrypt shared_ptr VolumeHeaderKdf; shared_ptr EA; bool Quick; + bool EMVOption; struct FilesystemType { diff --git a/src/ExpandVolume/ExpandVolume.vcxproj b/src/ExpandVolume/ExpandVolume.vcxproj index c4f8ce09..c182afe5 100644 --- a/src/ExpandVolume/ExpandVolume.vcxproj +++ b/src/ExpandVolume/ExpandVolume.vcxproj @@ -245,7 +245,7 @@ copy Debug\VeraCryptExpander.exe "..\Debug\Setup Files" >NUL: 4311;4131;%(DisableSpecificWarnings) - ..\Crypto\x64\Debug\crypto.lib;..\Common\x64\Debug\Zip.lib;..\Common\x64\Debug\lzma.lib;mpr.lib;%(AdditionalDependencies) + ..\Crypto\x64\Debug\crypto.lib;..\Common\x64\Debug\Zip.lib;..\Common\x64\Debug\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies) $(OutDir)VeraCryptExpander.exe false mpr.dll;%(DelayLoadDLLs) @@ -336,7 +336,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCryptExpander-x64.exe" >NUL: 4311;4131;%(DisableSpecificWarnings) - ..\Crypto\Release\crypto.lib;..\Common\Release\Zip.lib;..\Common\Release\lzma.lib;mpr.lib;%(AdditionalDependencies) + ..\Crypto\Release\crypto.lib;..\Common\Release\Zip.lib;..\Common\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies) $(OutDir)VeraCryptExpander.exe false mpr.dll;%(DelayLoadDLLs) @@ -428,7 +428,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCryptExpander-x64.exe" >NUL: 4311;4131;%(DisableSpecificWarnings) - ..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;%(AdditionalDependencies) + ..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies) $(OutDir)VeraCryptExpander.exe false mpr.dll;%(DelayLoadDLLs) @@ -476,7 +476,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCryptExpander-x64.exe" >NUL: 4311;4131;%(DisableSpecificWarnings) - ..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;%(AdditionalDependencies) + ..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies) $(OutDir)VeraCryptExpander.exe false mpr.dll;%(DelayLoadDLLs) @@ -575,6 +575,10 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCryptExpander-x64.exe" >NUL: + + + + @@ -655,6 +659,10 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCryptExpander-x64.exe" >NUL: + + + + diff --git a/src/ExpandVolume/ExpandVolume.vcxproj.filters b/src/ExpandVolume/ExpandVolume.vcxproj.filters index 007757ff..3997d07f 100644 --- a/src/ExpandVolume/ExpandVolume.vcxproj.filters +++ b/src/ExpandVolume/ExpandVolume.vcxproj.filters @@ -126,6 +126,18 @@ Source Files\Setup + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + @@ -230,6 +242,18 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + diff --git a/src/ExpandVolume/WinMain.cpp b/src/ExpandVolume/WinMain.cpp index 42f1c28d..57e58b4f 100644 --- a/src/ExpandVolume/WinMain.cpp +++ b/src/ExpandVolume/WinMain.cpp @@ -321,6 +321,7 @@ void LoadSettings (HWND hwndDlg) mountOptions = defaultMountOptions; CloseSecurityTokenSessionsAfterMount = ConfigReadInt ("CloseSecurityTokenSessionsAfterMount", 0); + ActivateEMVOption = ConfigReadInt ("ActivateEMVOption", 0); { char szTmp[TC_MAX_PATH] = {0}; diff --git a/src/Format/Format.vcxproj b/src/Format/Format.vcxproj index e377c1e0..9f5abbc0 100644 --- a/src/Format/Format.vcxproj +++ b/src/Format/Format.vcxproj @@ -218,7 +218,7 @@ copy Debug\VeraCryptFormat.exe "..\Debug\Setup Files\VeraCrypt Format.exe" >N 4057;4100;4127;4201;4204;4701;4706;4131;%(DisableSpecificWarnings) - ..\Crypto\x64\Debug\crypto.lib;..\Common\x64\Debug\Zip.lib;..\Common\x64\Debug\lzma.lib;mpr.lib;%(AdditionalDependencies) + ..\Crypto\x64\Debug\crypto.lib;..\Common\x64\Debug\Zip.lib;..\Common\x64\Debug\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies) $(OutDir)VeraCryptFormat.exe false mpr.dll;%(DelayLoadDLLs) @@ -301,7 +301,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-x64.exe" >NUL: 4057;4100;4127;4201;4204;4701;4706;4131;%(DisableSpecificWarnings) - ..\Crypto\Release\crypto.lib;..\Common\Release\Zip.lib;..\Common\Release\lzma.lib;mpr.lib;%(AdditionalDependencies) + ..\Crypto\Release\crypto.lib;..\Common\Release\Zip.lib;..\Common\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies) $(OutDir)VeraCryptFormat.exe false mpr.dll;%(DelayLoadDLLs) @@ -385,7 +385,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-x64.exe" >NUL: 4057;4100;4127;4201;4204;4701;4706;4131;%(DisableSpecificWarnings) - ..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;%(AdditionalDependencies) + ..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies) $(OutDir)VeraCryptFormat.exe false mpr.dll;%(DelayLoadDLLs) @@ -429,7 +429,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-x64.exe" >NUL: 4057;4100;4127;4201;4204;4701;4706;4131;%(DisableSpecificWarnings) - ..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;%(AdditionalDependencies) + ..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies) $(OutDir)VeraCryptFormat.exe false mpr.dll;%(DelayLoadDLLs) @@ -497,6 +497,10 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-x64.exe" >NUL: + + + + CompileAsCpp @@ -582,11 +586,15 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-x64.exe" >NUL: + + + + @@ -644,7 +652,9 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt Format-x64.exe" >NUL: - + + Designer + diff --git a/src/Format/Format.vcxproj.filters b/src/Format/Format.vcxproj.filters index 4f0e81eb..e6615982 100644 --- a/src/Format/Format.vcxproj.filters +++ b/src/Format/Format.vcxproj.filters @@ -108,6 +108,18 @@ Source Files\Common + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + @@ -208,6 +220,18 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + diff --git a/src/Format/Tcformat.c b/src/Format/Tcformat.c index 9c8648a8..1e605c4d 100644 --- a/src/Format/Tcformat.c +++ b/src/Format/Tcformat.c @@ -802,6 +802,8 @@ static void LoadSettingsAndCheckModified (HWND hwndDlg, BOOL bOnlyCheckModified, ConfigReadCompareInt ("UseLegacyMaxPasswordLength", FALSE, &bUseLegacyMaxPasswordLength, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("ActivateEMVOption", 0, &ActivateEMVOption, bOnlyCheckModified, pbSettingsModified); + { char szTmp[MAX_PATH] = {0}; WideCharToMultiByte (CP_UTF8, 0, SecurityTokenLibraryPath, -1, szTmp, MAX_PATH, NULL, NULL); @@ -9589,7 +9591,7 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine) case OptionTokenPin: { - wchar_t szTmp[SecurityToken::MaxPasswordLength + 1] = {0}; + wchar_t szTmp[SecurityToken::MaxPasswordLength + 1] = {0}; // TODO Use Token if (GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp)) == HAS_ARGUMENT) { if (0 == WideCharToMultiByte (CP_UTF8, 0, szTmp, -1, CmdTokenPin, TC_MAX_PATH, nullptr, nullptr)) diff --git a/src/Main/CommandLineInterface.cpp b/src/Main/CommandLineInterface.cpp index 865f69dd..dabfcad6 100644 --- a/src/Main/CommandLineInterface.cpp +++ b/src/Main/CommandLineInterface.cpp @@ -67,7 +67,9 @@ namespace VeraCrypt parser.AddSwitch (L"", L"import-token-keyfiles", _("Import keyfiles to security token")); parser.AddOption (L"k", L"keyfiles", _("Keyfiles")); parser.AddSwitch (L"l", L"list", _("List mounted volumes")); - parser.AddSwitch (L"", L"list-token-keyfiles", _("List security token keyfiles")); + parser.AddSwitch (L"", L"list-token-keyfiles", _("List token keyfiles")); + parser.AddSwitch (L"", L"list-securitytoken-keyfiles", _("List security token keyfiles")); + parser.AddSwitch (L"", L"list-emvtoken-keyfiles", _("List emv token keyfiles")); parser.AddSwitch (L"", L"load-preferences", _("Load user preferences")); parser.AddSwitch (L"", L"mount", _("Mount volume interactively")); parser.AddOption (L"m", L"mount-options", _("VeraCrypt volume mount options")); @@ -238,8 +240,18 @@ namespace VeraCrypt if (parser.Found (L"list-token-keyfiles")) { CheckCommandSingle(); - ArgCommand = CommandId::ListSecurityTokenKeyfiles; + ArgCommand = CommandId::ListTokenKeyfiles; } + if (parser.Found (L"list-securitytoken-keyfiles")) + { + CheckCommandSingle(); + ArgCommand = CommandId::ListSecurityTokenKeyfiles; + } + if (parser.Found (L"list-emvtoken-keyfiles")) + { + CheckCommandSingle(); + ArgCommand = CommandId::ListEMVTokenKeyfiles; + } if (parser.Found (L"mount")) { diff --git a/src/Main/CommandLineInterface.h b/src/Main/CommandLineInterface.h index 23693330..21fb5c89 100644 --- a/src/Main/CommandLineInterface.h +++ b/src/Main/CommandLineInterface.h @@ -42,7 +42,9 @@ namespace VeraCrypt ExportSecurityTokenKeyfile, Help, ImportSecurityTokenKeyfiles, - ListSecurityTokenKeyfiles, + ListTokenKeyfiles, + ListSecurityTokenKeyfiles, + ListEMVTokenKeyfiles, ListVolumes, MountVolume, RestoreHeaders, diff --git a/src/Main/Forms/ChangePasswordDialog.cpp b/src/Main/Forms/ChangePasswordDialog.cpp index 585d14a5..0992cf3b 100644 --- a/src/Main/Forms/ChangePasswordDialog.cpp +++ b/src/Main/Forms/ChangePasswordDialog.cpp @@ -204,7 +204,7 @@ namespace VeraCrypt wxBusyCursor busy; ChangePasswordThreadRoutine routine(Path, Gui->GetPreferences().DefaultMountOptions.PreserveTimestamps, CurrentPasswordPanel->GetPassword(), CurrentPasswordPanel->GetVolumePim(), CurrentPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf), CurrentPasswordPanel->GetTrueCryptMode(),CurrentPasswordPanel->GetKeyfiles(), - newPassword, newPim, newKeyfiles, NewPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf), NewPasswordPanel->GetHeaderWipeCount()); + newPassword, newPim, newKeyfiles, NewPasswordPanel->GetPkcs5Kdf(bUnsupportedKdf), NewPasswordPanel->GetHeaderWipeCount(), Gui->GetPreferences().ActivateEMVOption); Gui->ExecuteWaitThreadRoutine (this, &routine); } diff --git a/src/Main/Forms/Forms.cpp b/src/Main/Forms/Forms.cpp index b601839e..8667a741 100644 --- a/src/Main/Forms/Forms.cpp +++ b/src/Main/Forms/Forms.cpp @@ -2204,11 +2204,18 @@ PreferencesDialogBase::PreferencesDialogBase( wxWindow* parent, wxWindowID id, c CloseSecurityTokenSessionsAfterMountCheckBox = new wxCheckBox( sbSizer37->GetStaticBox(), wxID_ANY, _("IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT"), wxDefaultPosition, wxDefaultSize, 0 ); sbSizer37->Add( CloseSecurityTokenSessionsAfterMountCheckBox, 0, wxALL, 5 ); - + bSizer128->Add( sbSizer37, 0, wxEXPAND|wxALL, 5 ); - - + + wxStaticBoxSizer* sbSizer38; + sbSizer38 = new wxStaticBoxSizer( new wxStaticBox( SecurityTokensPage, wxID_ANY, _("IDT_EMV_OPTIONS") ), wxVERTICAL ); + + ActivateEMVOptionCheckBox = new wxCheckBox( sbSizer38->GetStaticBox(), wxID_ANY, _("IDC_ACTIVATE_EMV_OPTION"), wxDefaultPosition, wxDefaultSize, 0 ); + sbSizer38->Add( ActivateEMVOptionCheckBox, 0, wxALL, 5 ); + + bSizer128->Add( sbSizer38, 0, wxEXPAND|wxALL, 5 ); + bSizer127->Add( bSizer128, 1, wxEXPAND|wxALL, 5 ); diff --git a/src/Main/Forms/Forms.h b/src/Main/Forms/Forms.h index 245087de..904e96dd 100644 --- a/src/Main/Forms/Forms.h +++ b/src/Main/Forms/Forms.h @@ -593,6 +593,7 @@ namespace VeraCrypt wxTextCtrl* Pkcs11ModulePathTextCtrl; wxButton* SelectPkcs11ModuleButton; wxCheckBox* CloseSecurityTokenSessionsAfterMountCheckBox; + wxCheckBox* ActivateEMVOptionCheckBox; wxListCtrl* HotkeyListCtrl; wxTextCtrl* HotkeyTextCtrl; wxButton* AssignHotkeyButton; diff --git a/src/Main/Forms/KeyfilesPanel.cpp b/src/Main/Forms/KeyfilesPanel.cpp index c1f26d86..e3d086fc 100644 --- a/src/Main/Forms/KeyfilesPanel.cpp +++ b/src/Main/Forms/KeyfilesPanel.cpp @@ -115,7 +115,7 @@ namespace VeraCrypt SecurityTokenKeyfilesDialog dialog (this); if (dialog.ShowModal() == wxID_OK) { - foreach (const SecurityTokenKeyfilePath &path, dialog.GetSelectedSecurityTokenKeyfilePaths()) + foreach (const TokenKeyfilePath &path, dialog.GetSelectedSecurityTokenKeyfilePaths()) { vector fields; fields.push_back (path); diff --git a/src/Main/Forms/MainFrame.cpp b/src/Main/Forms/MainFrame.cpp index ab42ac06..b52682ce 100644 --- a/src/Main/Forms/MainFrame.cpp +++ b/src/Main/Forms/MainFrame.cpp @@ -683,7 +683,7 @@ namespace VeraCrypt { mountOptions.Pim = CmdLine->ArgPim; } - + mountOptions.EMVOption = GetPreferences().ActivateEMVOption; Gui->MountAllFavoriteVolumes (mountOptions); } catch (exception &e) @@ -718,6 +718,7 @@ namespace VeraCrypt { mountOptions.Pim = CmdLine->ArgPim; } + mountOptions.EMVOption = GetPreferences().ActivateEMVOption; try { diff --git a/src/Main/Forms/MountOptionsDialog.cpp b/src/Main/Forms/MountOptionsDialog.cpp index 04410922..28a9919c 100644 --- a/src/Main/Forms/MountOptionsDialog.cpp +++ b/src/Main/Forms/MountOptionsDialog.cpp @@ -193,6 +193,7 @@ namespace VeraCrypt Options.MountPoint = make_shared (mountPoint); Options.FilesystemOptions = FilesystemOptionsTextCtrl->GetValue(); + Options.EMVOption = Gui->GetPreferences().ActivateEMVOption; EndModal (wxID_OK); } diff --git a/src/Main/Forms/PreferencesDialog.cpp b/src/Main/Forms/PreferencesDialog.cpp index 2815c9b5..6caae325 100644 --- a/src/Main/Forms/PreferencesDialog.cpp +++ b/src/Main/Forms/PreferencesDialog.cpp @@ -96,6 +96,7 @@ namespace VeraCrypt // Security tokens Pkcs11ModulePathTextCtrl->SetValue (wstring (Preferences.SecurityTokenModule)); TC_CHECK_BOX_VALIDATOR (CloseSecurityTokenSessionsAfterMount); + TC_CHECK_BOX_VALIDATOR (ActivateEMVOption); // System integration TC_CHECK_BOX_VALIDATOR (StartOnLogon); diff --git a/src/Main/Forms/SecurityTokenKeyfilesDialog.cpp b/src/Main/Forms/SecurityTokenKeyfilesDialog.cpp index c4492599..2c5896a7 100644 --- a/src/Main/Forms/SecurityTokenKeyfilesDialog.cpp +++ b/src/Main/Forms/SecurityTokenKeyfilesDialog.cpp @@ -12,7 +12,6 @@ #include "System.h" #include "Main/GraphicUserInterface.h" -#include "Common/SecurityToken.h" #include "NewSecurityTokenKeyfileDialog.h" #include "SecurityTokenKeyfilesDialog.h" @@ -54,18 +53,18 @@ namespace VeraCrypt wxBusyCursor busy; SecurityTokenKeyfileListCtrl->DeleteAllItems(); - SecurityTokenKeyfileList = SecurityToken::GetAvailableKeyfiles(); + SecurityTokenKeyfileList = Token::GetAvailableKeyfiles(Gui->GetPreferences().ActivateEMVOption); size_t i = 0; - foreach (const SecurityTokenKeyfile &key, SecurityTokenKeyfileList) + foreach (const shared_ptr key, SecurityTokenKeyfileList) { vector fields (SecurityTokenKeyfileListCtrl->GetColumnCount()); - fields[ColumnSecurityTokenSlotId] = StringConverter::ToWide ((uint64) key.SlotId); - fields[ColumnSecurityTokenLabel] = key.Token.Label; - fields[ColumnSecurityTokenKeyfileLabel] = key.Id; + fields[ColumnSecurityTokenSlotId] = StringConverter::ToWide ((uint64) key->Token->SlotId); + fields[ColumnSecurityTokenLabel] = key->Token->Label; + fields[ColumnSecurityTokenKeyfileLabel] = key->Id; - Gui->AppendToListCtrl (SecurityTokenKeyfileListCtrl, fields, 0, &SecurityTokenKeyfileList[i++]); + Gui->AppendToListCtrl (SecurityTokenKeyfileListCtrl, fields, 0, key.get()); } } @@ -97,7 +96,7 @@ namespace VeraCrypt { foreach (long item, Gui->GetListCtrlSelectedItems (SecurityTokenKeyfileListCtrl)) { - SecurityTokenKeyfile *keyfile = reinterpret_cast (SecurityTokenKeyfileListCtrl->GetItemData (item)); + TokenKeyfile *keyfile = reinterpret_cast (SecurityTokenKeyfileListCtrl->GetItemData (item)); FilePathList files = Gui->SelectFiles (this, wxEmptyString, true); @@ -106,7 +105,7 @@ namespace VeraCrypt wxBusyCursor busy; vector keyfileData; - SecurityToken::GetKeyfileData (*keyfile, keyfileData); + keyfile->GetKeyfileData (keyfileData); BufferPtr keyfileDataBuf (&keyfileData.front(), keyfileData.size()); finally_do_arg (BufferPtr, keyfileDataBuf, { finally_arg.Erase(); }); @@ -178,24 +177,34 @@ namespace VeraCrypt } } - void SecurityTokenKeyfilesDialog::OnListItemSelected (wxListEvent& event) - { - if (event.GetItem().GetData() != (wxUIntPtr) nullptr) - { - DeleteButton->Enable(); - ExportButton->Enable(); - OKButton->Enable(); - } - } + void SecurityTokenKeyfilesDialog::OnListItemSelected(wxListEvent &event) { + if (event.GetItem().GetData() != (wxUIntPtr) nullptr) { + BOOL deletable = true; + foreach(long + item, Gui->GetListCtrlSelectedItems(SecurityTokenKeyfileListCtrl)) + { + TokenKeyfile *keyfile = reinterpret_cast (SecurityTokenKeyfileListCtrl->GetItemData( + item)); + if (!keyfile->Token->isEditable()) { + deletable = false; + } + } + if (deletable) { + DeleteButton->Enable(); + } + ExportButton->Enable(); + OKButton->Enable(); + } + } void SecurityTokenKeyfilesDialog::OnOKButtonClick () { foreach (long item, Gui->GetListCtrlSelectedItems (SecurityTokenKeyfileListCtrl)) - { - SecurityTokenKeyfile *key = reinterpret_cast (SecurityTokenKeyfileListCtrl->GetItemData (item)); - SelectedSecurityTokenKeyfilePaths.push_back (*key); - } + { + TokenKeyfile *key = reinterpret_cast (SecurityTokenKeyfileListCtrl->GetItemData(item)); + SelectedSecurityTokenKeyfilePaths.push_back(*key); + } EndModal (wxID_OK); } } diff --git a/src/Main/Forms/SecurityTokenKeyfilesDialog.h b/src/Main/Forms/SecurityTokenKeyfilesDialog.h index 8ba7fa9d..92119e1e 100644 --- a/src/Main/Forms/SecurityTokenKeyfilesDialog.h +++ b/src/Main/Forms/SecurityTokenKeyfilesDialog.h @@ -14,7 +14,9 @@ #define TC_HEADER_Main_Forms_SecurityTokenKeyfilesDialog #include "Forms.h" +#include "Common/Token.h" #include "Common/SecurityToken.h" +#include "Common/EMVToken.h" #include "Main/Main.h" namespace VeraCrypt @@ -23,7 +25,7 @@ namespace VeraCrypt { public: SecurityTokenKeyfilesDialog (wxWindow* parent, bool selectionMode = true); - list GetSelectedSecurityTokenKeyfilePaths() const { return SelectedSecurityTokenKeyfilePaths; } + list GetSelectedSecurityTokenKeyfilePaths() const { return SelectedSecurityTokenKeyfilePaths; } protected: enum @@ -43,8 +45,8 @@ namespace VeraCrypt void OnOKButtonClick (); void OnOKButtonClick (wxCommandEvent& event) { OnOKButtonClick(); } - vector SecurityTokenKeyfileList; - list SelectedSecurityTokenKeyfilePaths; + vector > SecurityTokenKeyfileList; + list SelectedSecurityTokenKeyfilePaths; }; } diff --git a/src/Main/Forms/VolumeCreationWizard.cpp b/src/Main/Forms/VolumeCreationWizard.cpp index dbb01974..0487455f 100644 --- a/src/Main/Forms/VolumeCreationWizard.cpp +++ b/src/Main/Forms/VolumeCreationWizard.cpp @@ -795,7 +795,7 @@ namespace VeraCrypt shared_ptr hiddenPassword; try { - hiddenPassword = Keyfile::ApplyListToPassword (Keyfiles, Password); + hiddenPassword = Keyfile::ApplyListToPassword (Keyfiles, Password, Gui->GetPreferences().ActivateEMVOption); } catch (...) { @@ -846,7 +846,7 @@ namespace VeraCrypt shared_ptr hiddenPassword; try { - hiddenPassword = Keyfile::ApplyListToPassword (Keyfiles, Password); + hiddenPassword = Keyfile::ApplyListToPassword (Keyfiles, Password, Gui->GetPreferences().ActivateEMVOption); } catch (...) { @@ -1032,6 +1032,8 @@ namespace VeraCrypt options->Size = VolumeSize; options->Type = OuterVolume ? VolumeType::Normal : SelectedVolumeType; options->VolumeHeaderKdf = Pkcs5Kdf::GetAlgorithm (*SelectedHash, false); + options->EMVOption = Gui->GetPreferences().ActivateEMVOption; + Creator.reset (new VolumeCreator); VolumeCreatorThreadRoutine routine(options, Creator); @@ -1160,7 +1162,7 @@ namespace VeraCrypt // remember Outer password and keyfiles in order to be able to compare it with those of Hidden volume try { - OuterPassword = Keyfile::ApplyListToPassword (Keyfiles, Password); + OuterPassword = Keyfile::ApplyListToPassword (Keyfiles, Password, Gui->GetPreferences().ActivateEMVOption); } catch (...) { diff --git a/src/Main/Forms/VolumePasswordPanel.cpp b/src/Main/Forms/VolumePasswordPanel.cpp index 3b624340..5bd98daa 100644 --- a/src/Main/Forms/VolumePasswordPanel.cpp +++ b/src/Main/Forms/VolumePasswordPanel.cpp @@ -383,7 +383,7 @@ namespace VeraCrypt SecurityTokenKeyfilesDialog dialog (this); if (dialog.ShowModal() == wxID_OK) { - foreach (const SecurityTokenKeyfilePath &path, dialog.GetSelectedSecurityTokenKeyfilePaths()) + foreach (const TokenKeyfilePath &path, dialog.GetSelectedSecurityTokenKeyfilePaths()) { Keyfiles->push_back (make_shared (wstring (path))); } diff --git a/src/Main/Forms/WaitDialog.cpp b/src/Main/Forms/WaitDialog.cpp index 795d7763..c2e0be96 100644 --- a/src/Main/Forms/WaitDialog.cpp +++ b/src/Main/Forms/WaitDialog.cpp @@ -10,6 +10,7 @@ #include "Volume/EncryptionModeXTS.h" #include "Main/GraphicUserInterface.h" #include "Common/SecurityToken.h" +#include "Common/IccDataExtractor.h" #include "WaitDialog.h" namespace VeraCrypt @@ -101,6 +102,14 @@ namespace VeraCrypt VC_CONVERT_EXCEPTION (CipherException); VC_CONVERT_EXCEPTION (VolumeException); VC_CONVERT_EXCEPTION (PasswordException); + + VC_CONVERT_EXCEPTION (PCSCException); + VC_CONVERT_EXCEPTION (WinscardLibraryNotInitialized); + VC_CONVERT_EXCEPTION (InvalidEMVPath); + VC_CONVERT_EXCEPTION (EMVKeyfileDataNotFound); + VC_CONVERT_EXCEPTION (EMVPANNotFound); + VC_CONVERT_EXCEPTION (EMVUnknownCardType); + throw *ex; } } diff --git a/src/Main/GraphicUserInterface.cpp b/src/Main/GraphicUserInterface.cpp index ba5c4e50..c76f1886 100644 --- a/src/Main/GraphicUserInterface.cpp +++ b/src/Main/GraphicUserInterface.cpp @@ -193,6 +193,7 @@ namespace VeraCrypt options->Kdf, false, options->Keyfiles, + options->EMVOption, options->Protection, options->ProtectionPassword, options->ProtectionPim, @@ -221,6 +222,7 @@ namespace VeraCrypt options->Kdf, false, options->Keyfiles, + options->EMVOption, options->Protection, options->ProtectionPassword, options->ProtectionPim, @@ -315,7 +317,7 @@ namespace VeraCrypt // Re-encrypt volume header SecureBuffer newHeaderBuffer (normalVolume->GetLayout()->GetHeaderSize()); - ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, normalVolume->GetHeader(), normalVolumeMountOptions.Password, normalVolumeMountOptions.Pim, normalVolumeMountOptions.Keyfiles); + ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, normalVolume->GetHeader(), normalVolumeMountOptions.Password, normalVolumeMountOptions.Pim, normalVolumeMountOptions.Keyfiles, normalVolumeMountOptions.EMVOption); ExecuteWaitThreadRoutine (parent, &routine); @@ -324,7 +326,7 @@ namespace VeraCrypt if (hiddenVolume) { // Re-encrypt hidden volume header - ReEncryptHeaderThreadRoutine hiddenRoutine(newHeaderBuffer, hiddenVolume->GetHeader(), hiddenVolumeMountOptions.Password, hiddenVolumeMountOptions.Pim, hiddenVolumeMountOptions.Keyfiles); + ReEncryptHeaderThreadRoutine hiddenRoutine(newHeaderBuffer, hiddenVolume->GetHeader(), hiddenVolumeMountOptions.Password, hiddenVolumeMountOptions.Pim, hiddenVolumeMountOptions.Keyfiles, hiddenVolumeMountOptions.EMVOption); ExecuteWaitThreadRoutine (parent, &hiddenRoutine); } @@ -677,11 +679,21 @@ namespace VeraCrypt return true; } - void GraphicUserInterface::ListSecurityTokenKeyfiles () const + void GraphicUserInterface::ListTokenKeyfiles () const { SecurityTokenKeyfilesDialog dialog (nullptr); dialog.ShowModal(); } + void GraphicUserInterface::ListSecurityTokenKeyfiles () const + { + SecurityTokenKeyfilesDialog dialog (nullptr); + dialog.ShowModal(); + } + void GraphicUserInterface::ListEMVTokenKeyfiles () const + { + SecurityTokenKeyfilesDialog dialog (nullptr); + dialog.ShowModal(); + } #ifdef TC_MACOSX void GraphicUserInterface::MacOpenFiles (const wxArrayString &fileNames) @@ -1456,6 +1468,7 @@ namespace VeraCrypt options.Kdf, options.TrueCryptMode, options.Keyfiles, + options.EMVOption, options.Protection, options.ProtectionPassword, options.ProtectionPim, @@ -1488,7 +1501,7 @@ namespace VeraCrypt // Re-encrypt volume header wxBusyCursor busy; SecureBuffer newHeaderBuffer (volume->GetLayout()->GetHeaderSize()); - ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, volume->GetHeader(), options.Password, options.Pim, options.Keyfiles); + ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, volume->GetHeader(), options.Password, options.Pim, options.Keyfiles, options.EMVOption); ExecuteWaitThreadRoutine (parent, &routine); @@ -1569,7 +1582,7 @@ namespace VeraCrypt backupFile.ReadAt (headerBuffer, layout->GetType() == VolumeType::Hidden ? layout->GetHeaderSize() : 0); // Decrypt header - shared_ptr passwordKey = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password); + shared_ptr passwordKey = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password, options.EMVOption); Pkcs5KdfList keyDerivationFunctions = layout->GetSupportedKeyDerivationFunctions(options.TrueCryptMode); EncryptionAlgorithmList encryptionAlgorithms = layout->GetSupportedEncryptionAlgorithms(); EncryptionModeList encryptionModes = layout->GetSupportedEncryptionModes(); @@ -1603,7 +1616,7 @@ namespace VeraCrypt // Re-encrypt volume header wxBusyCursor busy; SecureBuffer newHeaderBuffer (decryptedLayout->GetHeaderSize()); - ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles); + ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles, options.EMVOption); ExecuteWaitThreadRoutine (parent, &routine); @@ -1619,7 +1632,7 @@ namespace VeraCrypt if (decryptedLayout->HasBackupHeader()) { // Re-encrypt backup volume header - ReEncryptHeaderThreadRoutine backupRoutine(newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles); + ReEncryptHeaderThreadRoutine backupRoutine(newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles, options.EMVOption); ExecuteWaitThreadRoutine (parent, &backupRoutine); diff --git a/src/Main/GraphicUserInterface.h b/src/Main/GraphicUserInterface.h index 06ea6772..e50c6386 100644 --- a/src/Main/GraphicUserInterface.h +++ b/src/Main/GraphicUserInterface.h @@ -63,7 +63,9 @@ namespace VeraCrypt virtual void InsertToListCtrl (wxListCtrl *listCtrl, long itemIndex, const vector &itemFields, int imageIndex = -1, void *itemDataPtr = nullptr) const; virtual bool IsInBackgroundMode () const { return BackgroundMode; } virtual bool IsTheOnlyTopLevelWindow (const wxWindow *window) const; - virtual void ListSecurityTokenKeyfiles () const; + virtual void ListTokenKeyfiles () const; + virtual void ListSecurityTokenKeyfiles () const; + virtual void ListEMVTokenKeyfiles () const; virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const; virtual shared_ptr MountVolume (MountOptions &options) const; virtual void MoveListCtrlItem (wxListCtrl *listCtrl, long itemIndex, long newItemIndex) const; diff --git a/src/Main/TextUserInterface.cpp b/src/Main/TextUserInterface.cpp index ec3ed531..f4f73d7f 100644 --- a/src/Main/TextUserInterface.cpp +++ b/src/Main/TextUserInterface.cpp @@ -21,7 +21,9 @@ #endif #include +#include "Common/Token.h" #include "Common/SecurityToken.h" +#include "Common/EMVToken.h" #include "Core/RandomNumberGenerator.h" #include "Application.h" #include "TextUserInterface.h" @@ -312,6 +314,7 @@ namespace VeraCrypt kdf, false, options->Keyfiles, + true, options->Protection, options->ProtectionPassword, options->ProtectionPim, @@ -337,6 +340,7 @@ namespace VeraCrypt kdf, false, options->Keyfiles, + true, options->Protection, options->ProtectionPassword, options->ProtectionPim, @@ -407,14 +411,14 @@ namespace VeraCrypt // Re-encrypt volume header SecureBuffer newHeaderBuffer (normalVolume->GetLayout()->GetHeaderSize()); - Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, normalVolume->GetHeader(), normalVolumeMountOptions.Password, normalVolumeMountOptions.Pim, normalVolumeMountOptions.Keyfiles); + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, normalVolume->GetHeader(), normalVolumeMountOptions.Password, normalVolumeMountOptions.Pim, normalVolumeMountOptions.Keyfiles, true); backupFile.Write (newHeaderBuffer); if (hiddenVolume) { // Re-encrypt hidden volume header - Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, hiddenVolume->GetHeader(), hiddenVolumeMountOptions.Password, hiddenVolumeMountOptions.Pim, hiddenVolumeMountOptions.Keyfiles); + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, hiddenVolume->GetHeader(), hiddenVolumeMountOptions.Password, hiddenVolumeMountOptions.Pim, hiddenVolumeMountOptions.Keyfiles, true); } else { @@ -482,7 +486,7 @@ namespace VeraCrypt try { keyfiles.reset (new KeyfileList); - volume = Core->OpenVolume (volumePath, Preferences.DefaultMountOptions.PreserveTimestamps, password, pim, kdf, truecryptMode, keyfiles); + volume = Core->OpenVolume (volumePath, Preferences.DefaultMountOptions.PreserveTimestamps, password, pim, kdf, truecryptMode, keyfiles, true); } catch (PasswordException&) { @@ -492,7 +496,7 @@ namespace VeraCrypt } if (!volume.get()) - volume = Core->OpenVolume (volumePath, Preferences.DefaultMountOptions.PreserveTimestamps, password, pim, kdf, truecryptMode, keyfiles); + volume = Core->OpenVolume (volumePath, Preferences.DefaultMountOptions.PreserveTimestamps, password, pim, kdf, truecryptMode, keyfiles, true); } catch (PasswordException &e) { @@ -527,7 +531,7 @@ namespace VeraCrypt RandomNumberGenerator::SetEnrichedByUserStatus (false); UserEnrichRandomPool(); - Core->ChangePassword (volume, newPassword, newPim, newKeyfiles, + Core->ChangePassword (volume, newPassword, newPim, newKeyfiles, true, newHash ? Pkcs5Kdf::GetAlgorithm (*newHash, false) : shared_ptr ()); ShowInfo ("PASSWORD_CHANGED"); @@ -911,6 +915,7 @@ namespace VeraCrypt wxLongLong startTime = wxGetLocalTimeMillis(); VolumeCreator creator; + options->EMVOption = true; creator.CreateVolume (options); bool volumeCreated = false; @@ -1024,7 +1029,7 @@ namespace VeraCrypt foreach_ref (const Keyfile &keyfile, *keyfiles) { - SecurityToken::DeleteKeyfile (SecurityTokenKeyfilePath (FilePath (keyfile))); + SecurityToken::DeleteKeyfile (TokenKeyfilePath (FilePath (keyfile))); } } @@ -1055,10 +1060,10 @@ namespace VeraCrypt if (keyfilePath.empty()) throw UserAbort (SRC_POS); - SecurityTokenKeyfile tokenKeyfile (keyfilePath); + shared_ptr tokenKeyfile = Token::getTokenKeyfile(keyfilePath); vector keyfileData; - SecurityToken::GetKeyfileData (tokenKeyfile, keyfileData); + tokenKeyfile->GetKeyfileData (keyfileData); BufferPtr keyfileDataBuf (&keyfileData.front(), keyfileData.size()); finally_do_arg (BufferPtr, keyfileDataBuf, { finally_arg.Erase(); }); @@ -1100,7 +1105,7 @@ namespace VeraCrypt void TextUserInterface::ImportSecurityTokenKeyfiles () const { - list tokens = SecurityToken::GetAvailableTokens(); + list > tokens = Token::GetAvailableTokens(); if (tokens.empty()) throw_err (LangString ["NO_TOKENS_FOUND"]); @@ -1109,19 +1114,19 @@ namespace VeraCrypt if (tokens.size() == 1) { - slotId = tokens.front().SlotId; + slotId = tokens.front()->SlotId; } else { - foreach (const SecurityTokenInfo &token, tokens) + foreach (const shared_ptr &token, tokens) { wstringstream tokenLabel; - tokenLabel << L"[" << token.SlotId << L"] " << LangString["TOKEN_SLOT_ID"].c_str() << L" " << token.SlotId << L" " << token.Label; + tokenLabel << L"[" << token->SlotId << L"] " << LangString["TOKEN_SLOT_ID"].c_str() << L" " << token->SlotId << L" " << token->Label; ShowInfo (tokenLabel.str()); } - slotId = (CK_SLOT_ID) AskSelection (tokens.back().SlotId, tokens.front().SlotId); + slotId = (CK_SLOT_ID) AskSelection (tokens.back()->SlotId, tokens.front()->SlotId); } shared_ptr keyfiles; @@ -1225,14 +1230,30 @@ namespace VeraCrypt } } - void TextUserInterface::ListSecurityTokenKeyfiles () const + void TextUserInterface::ListTokenKeyfiles () const { - foreach (const SecurityTokenKeyfile &keyfile, SecurityToken::GetAvailableKeyfiles()) + foreach (const shared_ptr keyfile, Token::GetAvailableKeyfiles(true)) { - ShowString (wstring (SecurityTokenKeyfilePath (keyfile))); + ShowString (wstring (TokenKeyfilePath (*keyfile))); ShowString (L"\n"); } } + void TextUserInterface::ListSecurityTokenKeyfiles () const + { + foreach (const TokenKeyfile &keyfile, SecurityToken::GetAvailableKeyfiles()) + { + ShowString (wstring (TokenKeyfilePath (keyfile))); + ShowString (L"\n"); + } + } + void TextUserInterface::ListEMVTokenKeyfiles () const + { + foreach (const TokenKeyfile &keyfile, EMVToken::GetAvailableKeyfiles()) + { + ShowString (wstring (TokenKeyfilePath (keyfile))); + ShowString (L"\n"); + } + } VolumeInfoList TextUserInterface::MountAllDeviceHostedVolumes (MountOptions &options) const { @@ -1523,6 +1544,7 @@ namespace VeraCrypt kdf, false, options.Keyfiles, + true, options.Protection, options.ProtectionPassword, options.ProtectionPim, @@ -1550,7 +1572,7 @@ namespace VeraCrypt // Re-encrypt volume header SecureBuffer newHeaderBuffer (volume->GetLayout()->GetHeaderSize()); - Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, volume->GetHeader(), options.Password, options.Pim, options.Keyfiles); + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, volume->GetHeader(), options.Password, options.Pim, options.Keyfiles, true); // Write volume header int headerOffset = volume->GetLayout()->GetHeaderOffset(); @@ -1627,7 +1649,7 @@ namespace VeraCrypt backupFile.ReadAt (headerBuffer, layout->GetType() == VolumeType::Hidden ? layout->GetHeaderSize() : 0); // Decrypt header - shared_ptr passwordKey = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password); + shared_ptr passwordKey = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password, true); if (layout->GetHeader()->Decrypt (headerBuffer, *passwordKey, options.Pim, kdf, false, layout->GetSupportedKeyDerivationFunctions(false), layout->GetSupportedEncryptionAlgorithms(), layout->GetSupportedEncryptionModes())) { decryptedLayout = layout; @@ -1652,7 +1674,7 @@ namespace VeraCrypt // Re-encrypt volume header SecureBuffer newHeaderBuffer (decryptedLayout->GetHeaderSize()); - Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles); + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles, true); // Write volume header int headerOffset = decryptedLayout->GetHeaderOffset(); @@ -1666,7 +1688,7 @@ namespace VeraCrypt if (decryptedLayout->HasBackupHeader()) { // Re-encrypt backup volume header - Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles); + Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Pim, options.Keyfiles, true); // Write backup volume header headerOffset = decryptedLayout->GetBackupHeaderOffset(); diff --git a/src/Main/TextUserInterface.h b/src/Main/TextUserInterface.h index 14eb2c0e..5e64aac7 100644 --- a/src/Main/TextUserInterface.h +++ b/src/Main/TextUserInterface.h @@ -51,7 +51,9 @@ namespace VeraCrypt virtual bool Initialize (int &argc, wxChar **argv) { return wxAppBase::Initialize(argc, argv); } #endif virtual void InitSecurityTokenLibrary () const; - virtual void ListSecurityTokenKeyfiles () const; + virtual void ListTokenKeyfiles () const; + virtual void ListSecurityTokenKeyfiles () const; + virtual void ListEMVTokenKeyfiles () const; virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const; virtual shared_ptr MountVolume (MountOptions &options) const; virtual bool OnInit (); diff --git a/src/Main/UserInterface.cpp b/src/Main/UserInterface.cpp index 1a237bbe..132ad0e0 100644 --- a/src/Main/UserInterface.cpp +++ b/src/Main/UserInterface.cpp @@ -24,6 +24,7 @@ #include "Platform/SystemInfo.h" #include "Platform/SystemException.h" #include "Common/SecurityToken.h" +#include "Common/IccDataExtractor.h" #include "Volume/EncryptionTest.h" #include "Application.h" #include "FavoriteVolume.h" @@ -436,6 +437,27 @@ namespace VeraCrypt return LangString["SECURITY_TOKEN_ERROR"] + L":\n\n" + StringConverter::ToWide (errorString); } + + // PCSC Exception + if (dynamic_cast (&ex)) + { + string errorString = string (dynamic_cast (ex)); + + if (LangString.Exists (errorString)) + return LangString[errorString]; + + if (errorString.find("SCARD_E_") == 0 || errorString.find("SCARD_F_") == 0 || errorString.find("SCARD_W_") == 0) + { + errorString = errorString.substr(8); + for (size_t i = 0; i < errorString.size(); ++i) + { + if (errorString[i] == '_') + errorString[i] = ' '; + } + } + return LangString["PCSC_ERROR"] + L":\n\n" + StringConverter::ToWide (errorString); + } + // Other library exceptions return ExceptionTypeToString (typeid (ex)); } @@ -479,6 +501,12 @@ namespace VeraCrypt EX2MSG (StringFormatterException, LangString["LINUX_EX2MSG_STRINGFORMATTEREXCEPTION"]); EX2MSG (TemporaryDirectoryFailure, LangString["LINUX_EX2MSG_TEMPORARYDIRECTORYFAILURE"]); EX2MSG (UnportablePassword, LangString["UNSUPPORTED_CHARS_IN_PWD"]); + + EX2MSG (WinscardLibraryNotInitialized, LangString["WINSCARD_MODULE_INIT_FAILED"]); + EX2MSG (InvalidEMVPath, LangString["INVALID_EMV_PATH"]); + EX2MSG (EMVKeyfileDataNotFound, LangString["EMV_KEYFILE_DATA_NOT_FOUND"]); + EX2MSG (EMVPANNotFound, LangString["EMV_PAN_NOT_FOUND"]); + EX2MSG (EMVUnknownCardType, LangString["EMV_UNKNOWN_CARD_TYPE"]); #if defined (TC_LINUX) EX2MSG (TerminalNotFound, LangString["LINUX_EX2MSG_TERMINALNOTFOUND"]); @@ -1122,7 +1150,7 @@ namespace VeraCrypt " Delete keyfiles from security tokens. See also command --list-token-keyfiles.\n" "\n" "--export-token-keyfile\n" - " Export a keyfile from a security token. See also command --list-token-keyfiles.\n" + " Export a keyfile from a token keyfile. See also command --list-token-keyfiles.\n" "\n" "--import-token-keyfiles\n" " Import keyfiles to a security token. See also option --token-lib.\n" @@ -1134,9 +1162,15 @@ namespace VeraCrypt " output option (-v). See below for description of MOUNTED_VOLUME.\n" "\n" "--list-token-keyfiles\n" - " Display a list of all available security token keyfiles. See also command\n" + " Display a list of all available token keyfiles. See also command\n" " --import-token-keyfiles.\n" - "\n" + "\n""--list-securitytoken-keyfiles\n" + " Display a list of all available security token keyfiles. See also command\n" + " --import-token-keyfiles.\n" + "\n" + "\n""--list-emvtoken-keyfiles\n" + " Display a list of all available emv token keyfiles. See also command\n" + "\n" "--mount[=VOLUME_PATH]\n" " Mount a volume. Volume path and other options are requested from the user\n" " if not specified on command line.\n" @@ -1199,9 +1233,12 @@ namespace VeraCrypt " used (non-recursively). Multiple keyfiles must be separated by comma.\n" " Use double comma (,,) to specify a comma contained in keyfile's name.\n" " Keyfile stored on a security token must be specified as\n" - " token://slot/SLOT_NUMBER/file/FILENAME. An empty keyfile (-k \"\") disables\n" + " token://slot/SLOT_NUMBER/file/FILENAME for a security token keyfile\n" + " and emv://slot/SLOT_NUMBER for an EMV token keyfile.\n" + " An empty keyfile (-k \"\") disables\n" " interactive requests for keyfiles. See also options --import-token-keyfiles,\n" - " --list-token-keyfiles, --new-keyfiles, --protection-keyfiles.\n" + " --list-token-keyfiles, --list-securitytoken-keyfiles, --list-emvtoken-keyfiles,\n" + " --new-keyfiles, --protection-keyfiles.\n" "\n" "--load-preferences\n" " Load user preferences.\n" @@ -1364,10 +1401,18 @@ namespace VeraCrypt ImportSecurityTokenKeyfiles(); return true; - case CommandId::ListSecurityTokenKeyfiles: - ListSecurityTokenKeyfiles(); + case CommandId::ListTokenKeyfiles: + ListTokenKeyfiles(); return true; + case CommandId::ListSecurityTokenKeyfiles: + ListSecurityTokenKeyfiles(); + return true; + + case CommandId::ListEMVTokenKeyfiles: + ListEMVTokenKeyfiles(); + return true; + case CommandId::ListVolumes: if (Preferences.Verbose) DisplayVolumeProperties (cmdLine.ArgVolumes); @@ -1648,6 +1693,14 @@ namespace VeraCrypt VC_CONVERT_EXCEPTION (CipherException); VC_CONVERT_EXCEPTION (VolumeException); VC_CONVERT_EXCEPTION (PasswordException); + + VC_CONVERT_EXCEPTION (PCSCException); + VC_CONVERT_EXCEPTION (WinscardLibraryNotInitialized); + VC_CONVERT_EXCEPTION (InvalidEMVPath); + VC_CONVERT_EXCEPTION (EMVKeyfileDataNotFound); + VC_CONVERT_EXCEPTION (EMVPANNotFound); + VC_CONVERT_EXCEPTION (EMVUnknownCardType); + throw *ex; } } diff --git a/src/Main/UserInterface.h b/src/Main/UserInterface.h index 8c8cca7b..4b628235 100644 --- a/src/Main/UserInterface.h +++ b/src/Main/UserInterface.h @@ -56,7 +56,9 @@ namespace VeraCrypt virtual void Init (); virtual void InitSecurityTokenLibrary () const = 0; virtual void ListMountedVolumes (const VolumeInfoList &volumes) const; + virtual void ListTokenKeyfiles () const = 0; virtual void ListSecurityTokenKeyfiles () const = 0; + virtual void ListEMVTokenKeyfiles () const = 0; virtual shared_ptr MountVolume (MountOptions &options) const; virtual shared_ptr MountVolumeThread (MountOptions &options) const { return Core->MountVolume (options);} virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const; diff --git a/src/Main/UserPreferences.cpp b/src/Main/UserPreferences.cpp index db54b4a4..d5b37bab 100644 --- a/src/Main/UserPreferences.cpp +++ b/src/Main/UserPreferences.cpp @@ -79,6 +79,7 @@ namespace VeraCrypt TC_CONFIG_SET (CloseBackgroundTaskOnNoVolumes); TC_CONFIG_SET (CloseExplorerWindowsOnDismount); TC_CONFIG_SET (CloseSecurityTokenSessionsAfterMount); + TC_CONFIG_SET (ActivateEMVOption); TC_CONFIG_SET (DisableKernelEncryptionModeWarning); TC_CONFIG_SET (DismountOnInactivity); TC_CONFIG_SET (DismountOnLogOff); @@ -197,6 +198,7 @@ namespace VeraCrypt TC_CONFIG_ADD (CloseBackgroundTaskOnNoVolumes); TC_CONFIG_ADD (CloseExplorerWindowsOnDismount); TC_CONFIG_ADD (CloseSecurityTokenSessionsAfterMount); + TC_CONFIG_ADD (ActivateEMVOption); TC_CONFIG_ADD (DisableKernelEncryptionModeWarning); TC_CONFIG_ADD (DismountOnInactivity); TC_CONFIG_ADD (DismountOnLogOff); diff --git a/src/Main/UserPreferences.h b/src/Main/UserPreferences.h index 96faf8a2..bc9cc0c7 100644 --- a/src/Main/UserPreferences.h +++ b/src/Main/UserPreferences.h @@ -31,6 +31,7 @@ namespace VeraCrypt CloseBackgroundTaskOnNoVolumes (true), CloseExplorerWindowsOnDismount (true), CloseSecurityTokenSessionsAfterMount (false), + ActivateEMVOption (false), DisableKernelEncryptionModeWarning (false), DismountOnInactivity (false), DismountOnLogOff (true), @@ -72,6 +73,7 @@ namespace VeraCrypt bool CloseBackgroundTaskOnNoVolumes; bool CloseExplorerWindowsOnDismount; bool CloseSecurityTokenSessionsAfterMount; + bool ActivateEMVOption; bool DisableKernelEncryptionModeWarning; bool DismountOnInactivity; bool DismountOnLogOff; diff --git a/src/Makefile b/src/Makefile index 98b3dd1a..53e460b6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -190,6 +190,10 @@ ifeq "$(shell uname -s)" "Linux" PLATFORM := Linux C_CXX_FLAGS += -DTC_UNIX -DTC_LINUX + # TODO: Prpoper implementation in the makefile + C_CXX_FLAGS += -I/usr/include/PCSC/ -lpcsclite + LFLAGS += -I/usr/include/PCSC/ -lpcsclite + # GNU GCC version 11 and higher compile with -std=gnu++17 by default # which breaks "byte" definitions in Crypto++ library. So set diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 5a7e40fe..a7552411 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -954,6 +954,7 @@ void LoadSettingsAndCheckModified (HWND hwndDlg, BOOL bOnlyCheckModified, BOOL* } ConfigReadCompareInt ("CloseSecurityTokenSessionsAfterMount", 0, &CloseSecurityTokenSessionsAfterMount, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("ActivateEMVOption", 0, &ActivateEMVOption, bOnlyCheckModified, pbSettingsModified); if (IsHiddenOSRunning()) ConfigReadCompareInt ("HiddenSystemLeakProtNotifStatus", TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE, &HiddenSysLeakProtectionNotificationStatus, bOnlyCheckModified, pbSettingsModified); @@ -1126,6 +1127,7 @@ void SaveSettings (HWND hwndDlg) } ConfigWriteInt ("CloseSecurityTokenSessionsAfterMount", CloseSecurityTokenSessionsAfterMount); + ConfigWriteInt ("ActivateEMVOption", ActivateEMVOption); // Hotkeys ConfigWriteInt ("HotkeyModAutoMountDevices", Hotkeys[HK_AUTOMOUNT_DEVICES].vKeyModifiers); @@ -5401,7 +5403,7 @@ ret: bCacheInDriver = bCacheInDriverDefault; if (status && CloseSecurityTokenSessionsAfterMount && !MultipleMountOperationInProgress) - SecurityToken::CloseAllSessions(); + SecurityToken::CloseAllSessions(); // TODO Use Token return status; } @@ -5903,7 +5905,7 @@ static BOOL MountAllDevicesThreadCode (HWND hwndDlg, BOOL bPasswordPrompt) } if (status && CloseSecurityTokenSessionsAfterMount) - SecurityToken::CloseAllSessions(); + SecurityToken::CloseAllSessions(); // TODO Use Token ret: MultipleMountOperationInProgress = FALSE; @@ -7653,7 +7655,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa if (bWipeCacheOnAutoDismount) { DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); - SecurityToken::CloseAllSessions(); + SecurityToken::CloseAllSessions(); // TODO Use Token } DismountAll (hwndDlg, bForceAutoDismount, TRUE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); @@ -7692,7 +7694,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa if (bWipeCacheOnAutoDismount) { DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); - SecurityToken::CloseAllSessions(); + SecurityToken::CloseAllSessions(); // TODO Use Token } DismountAll (hwndDlg, bForceAutoDismount, TRUE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); @@ -7749,7 +7751,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa if (bWipeCacheOnAutoDismount) { DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); - SecurityToken::CloseAllSessions(); + SecurityToken::CloseAllSessions(); // TODO Use Token } DismountAll (hwndDlg, bForceAutoDismount, FALSE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); @@ -8648,7 +8650,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa WaitCursor(); finally_do ({ NormalCursor(); }); - SecurityToken::CloseAllSessions(); + SecurityToken::CloseAllSessions(); // TODO Use Token } InfoBalloon (NULL, "ALL_TOKEN_SESSIONS_CLOSED", hwndDlg); @@ -9637,7 +9639,7 @@ void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine) case OptionTokenPin: { - wchar_t szTmp[SecurityToken::MaxPasswordLength + 1] = {0}; + wchar_t szTmp[SecurityToken::MaxPasswordLength + 1] = {0}; // TODO Use Token if (GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp)) == HAS_ARGUMENT) { if (0 == WideCharToMultiByte (CP_UTF8, 0, szTmp, -1, CmdTokenPin, TC_MAX_PATH, nullptr, nullptr)) @@ -10303,7 +10305,7 @@ void DismountIdleVolumes () if (bWipeCacheOnAutoDismount) { DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); - SecurityToken::CloseAllSessions(); + SecurityToken::CloseAllSessions(); // TODO Use Token } } } @@ -10632,7 +10634,7 @@ BOOL MountFavoriteVolumes (HWND hwnd, BOOL systemFavorites, BOOL logOnMount, BOO burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); if (bRet && CloseSecurityTokenSessionsAfterMount) - SecurityToken::CloseAllSessions(); + SecurityToken::CloseAllSessions(); // TODO Use Token return bRet; } @@ -10810,7 +10812,7 @@ static void HandleHotKey (HWND hwndDlg, WPARAM wParam) break; case HK_CLOSE_SECURITY_TOKEN_SESSIONS: - SecurityToken::CloseAllSessions(); + SecurityToken::CloseAllSessions(); // TODO Use Token InfoBalloon (NULL, "ALL_TOKEN_SESSIONS_CLOSED", hwndDlg); @@ -11879,6 +11881,7 @@ static BOOL CALLBACK SecurityTokenPreferencesDlgProc (HWND hwndDlg, UINT msg, WP LocalizeDialog (hwndDlg, "IDD_TOKEN_PREFERENCES"); SetDlgItemText (hwndDlg, IDC_PKCS11_MODULE, SecurityTokenLibraryPath); CheckDlgButton (hwndDlg, IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT, CloseSecurityTokenSessionsAfterMount ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton (hwndDlg, IDC_ACTIVATE_EMV_OPTION, ActivateEMVOption ? BST_CHECKED : BST_UNCHECKED); SetWindowTextW (GetDlgItem (hwndDlg, IDT_PKCS11_LIB_HELP), GetString("PKCS11_LIB_LOCATION_HELP")); @@ -11901,7 +11904,7 @@ static BOOL CALLBACK SecurityTokenPreferencesDlgProc (HWND hwndDlg, UINT msg, WP { try { - SecurityToken::CloseLibrary(); + SecurityToken::CloseLibrary(); // TODO Use Token } catch (...) { } @@ -11921,7 +11924,7 @@ static BOOL CALLBACK SecurityTokenPreferencesDlgProc (HWND hwndDlg, UINT msg, WP } CloseSecurityTokenSessionsAfterMount = (IsDlgButtonChecked (hwndDlg, IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT) == BST_CHECKED); - + ActivateEMVOption = (IsDlgButtonChecked (hwndDlg, IDC_ACTIVATE_EMV_OPTION) == BST_CHECKED); WaitCursor (); SaveSettings (hwndDlg); NormalCursor (); diff --git a/src/Mount/Mount.rc b/src/Mount/Mount.rc index a524d9f0..d6d766c5 100644 --- a/src/Mount/Mount.rc +++ b/src/Mount/Mount.rc @@ -270,7 +270,7 @@ BEGIN GROUPBOX "Shortcut",IDT_ASSIGN_HOTKEY,7,127,375,53 END -IDD_TOKEN_PREFERENCES DIALOGEX 0, 0, 316, 199 +IDD_TOKEN_PREFERENCES DIALOGEX 0, 0, 316, 229 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "VeraCrypt - Security Token Preferences" FONT 8, "MS Shell Dlg", 400, 0, 0x1 @@ -280,10 +280,12 @@ BEGIN PUSHBUTTON "Auto-&Detect Library",IDC_AUTO_DETECT_PKCS11_MODULE,16,41,112,14 CONTROL "&Close token session (log out) after a volume is successfully mounted",IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT, "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,154,284,9 - DEFPUSHBUTTON "OK",IDOK,205,178,50,14 - PUSHBUTTON "Cancel",IDCANCEL,259,178,50,14 + CONTROL "&Activate EMV Option",IDC_ACTIVATE_EMV_OPTION,"Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,185,284,9 + DEFPUSHBUTTON "OK",IDOK,205,208,50,14 + PUSHBUTTON "Cancel",IDCANCEL,259,208,50,14 GROUPBOX "PKCS #11 Library Path",IDT_PKCS11_LIB_PATH,7,7,302,129 GROUPBOX "Security Options",IDT_SECURITY_OPTIONS,7,140,302,30 + GROUPBOX "EMV Options",IDT_EMV_OPTIONS,7,172,302,30 LTEXT "",IDT_PKCS11_LIB_HELP,16,63,286,65 END diff --git a/src/Mount/Mount.vcxproj b/src/Mount/Mount.vcxproj index 1c55193a..5aeb6722 100644 --- a/src/Mount/Mount.vcxproj +++ b/src/Mount/Mount.vcxproj @@ -236,7 +236,7 @@ copy Debug\VeraCrypt.exe "..\Debug\Setup Files" >NUL: 4057;4100;4127;4201;4701;4706;4131;%(DisableSpecificWarnings) - ..\Crypto\x64\Debug\crypto.lib;..\Common\x64\Debug\Zip.lib;..\Common\x64\Debug\lzma.lib;mpr.lib;%(AdditionalDependencies) + ..\Crypto\x64\Debug\crypto.lib;..\Common\x64\Debug\Zip.lib;..\Common\x64\Debug\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies) $(OutDir)VeraCrypt.exe false mpr.dll;%(DelayLoadDLLs) @@ -325,7 +325,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-x64.exe" >NUL: 4057;4100;4127;4201;4701;4706;4131;%(DisableSpecificWarnings) - ..\Crypto\Release\crypto.lib;..\Common\Release\Zip.lib;..\Common\Release\lzma.lib;mpr.lib;%(AdditionalDependencies) + ..\Crypto\Release\crypto.lib;..\Common\Release\Zip.lib;..\Common\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies) $(OutDir)VeraCrypt.exe false mpr.dll;%(DelayLoadDLLs) @@ -415,7 +415,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-x64.exe" >NUL: 4057;4100;4127;4201;4701;4706;4131;%(DisableSpecificWarnings) - ..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;%(AdditionalDependencies) + ..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies) $(OutDir)VeraCrypt.exe false mpr.dll;%(DelayLoadDLLs) @@ -462,7 +462,7 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-x64.exe" >NUL: 4057;4100;4127;4201;4701;4706;4131;%(DisableSpecificWarnings) - ..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;%(AdditionalDependencies) + ..\Crypto\x64\Release\crypto.lib;..\Common\x64\Release\Zip.lib;..\Common\x64\Release\lzma.lib;mpr.lib;winscard.lib;%(AdditionalDependencies) $(OutDir)VeraCrypt.exe false mpr.dll;%(DelayLoadDLLs) @@ -533,6 +533,10 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-x64.exe" >NUL: + + + + @@ -602,6 +606,10 @@ copy $(TargetPath) "..\Debug\Setup Files\VeraCrypt-x64.exe" >NUL: + + + + diff --git a/src/Mount/Mount.vcxproj.filters b/src/Mount/Mount.vcxproj.filters index e1dfd652..033a76ff 100644 --- a/src/Mount/Mount.vcxproj.filters +++ b/src/Mount/Mount.vcxproj.filters @@ -108,6 +108,18 @@ Source Files\Setup + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + @@ -211,6 +223,18 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + diff --git a/src/Mount/Resource.h b/src/Mount/Resource.h index f7b3ff05..69f99080 100644 --- a/src/Mount/Resource.h +++ b/src/Mount/Resource.h @@ -199,6 +199,8 @@ #define IDC_FORCE_NEXT_BOOT_VERACRYPT 1176 #define IDC_FORCE_VERACRYPT_BOOT_ENTRY 1177 #define IDC_FORCE_VERACRYPT_FIRST_BOOT_ENTRY 1178 +#define IDC_ACTIVATE_EMV_OPTION 1179 +#define IDT_EMV_OPTIONS 1180 #define IDM_HELP 40001 #define IDM_ABOUT 40002 #define IDM_UNMOUNT_VOLUME 40003 diff --git a/src/Volume/Keyfile.cpp b/src/Volume/Keyfile.cpp index d171458c..9527fd11 100644 --- a/src/Volume/Keyfile.cpp +++ b/src/Volume/Keyfile.cpp @@ -12,13 +12,13 @@ #include "Platform/Serializer.h" #include "Common/SecurityToken.h" +#include "Common/EMVToken.h" #include "Crc32.h" #include "Keyfile.h" #include "VolumeException.h" - namespace VeraCrypt { - void Keyfile::Apply (const BufferPtr &pool) const + void Keyfile::Apply (const BufferPtr &pool, bool EMVOption) const { if (Path.IsDirectory()) throw ParameterIncorrect (SRC_POS); @@ -32,61 +32,57 @@ namespace VeraCrypt SecureBuffer keyfileBuf (File::GetOptimalReadSize()); - if (SecurityToken::IsKeyfilePathValid (Path)) - { - // Apply keyfile generated by a security token - vector keyfileData; - SecurityToken::GetKeyfileData (SecurityTokenKeyfile (wstring (Path)), keyfileData); + std::wcout << wstring (Path) << std::endl; + if (Token::IsKeyfilePathValid (Path, EMVOption)) { + // Apply keyfile generated by a security token + vector keyfileData; + Token::getTokenKeyfile(wstring(Path))->GetKeyfileData(keyfileData); - if (keyfileData.size() < MinProcessedLength) - throw InsufficientData (SRC_POS, Path); + if (keyfileData.size() < MinProcessedLength) + throw InsufficientData(SRC_POS, Path); - for (size_t i = 0; i < keyfileData.size(); i++) - { - uint32 crc = crc32.Process (keyfileData[i]); + for (size_t i = 0; i < keyfileData.size(); i++) { + uint32 crc = crc32.Process(keyfileData[i]); - pool[poolPos++] += (byte) (crc >> 24); - pool[poolPos++] += (byte) (crc >> 16); - pool[poolPos++] += (byte) (crc >> 8); - pool[poolPos++] += (byte) crc; + pool[poolPos++] += (byte)(crc >> 24); + pool[poolPos++] += (byte)(crc >> 16); + pool[poolPos++] += (byte)(crc >> 8); + pool[poolPos++] += (byte) crc; - if (poolPos >= pool.Size()) - poolPos = 0; - - if (++totalLength >= MaxProcessedLength) - break; - } + if (poolPos >= pool.Size()) + poolPos = 0; - burn (&keyfileData.front(), keyfileData.size()); - goto done; - } + if (++totalLength >= MaxProcessedLength) + break; + } - file.Open (Path, File::OpenRead, File::ShareRead); - while ((readLength = file.Read (keyfileBuf)) > 0) - { - for (size_t i = 0; i < readLength; i++) - { - uint32 crc = crc32.Process (keyfileBuf[i]); + burn(&keyfileData.front(), keyfileData.size()); + goto done; + } - pool[poolPos++] += (byte) (crc >> 24); - pool[poolPos++] += (byte) (crc >> 16); - pool[poolPos++] += (byte) (crc >> 8); - pool[poolPos++] += (byte) crc; + file.Open (Path, File::OpenRead, File::ShareRead); - if (poolPos >= pool.Size()) - poolPos = 0; + while ((readLength = file.Read (keyfileBuf)) > 0) { + for (size_t i = 0; i < readLength; i++) { + uint32 crc = crc32.Process(keyfileBuf[i]); + pool[poolPos++] += (byte)(crc >> 24); + pool[poolPos++] += (byte)(crc >> 16); + pool[poolPos++] += (byte)(crc >> 8); + pool[poolPos++] += (byte) crc; + if (poolPos >= pool.Size()) + poolPos = 0; + if (++totalLength >= MaxProcessedLength) + goto done; + } + } + done: - if (++totalLength >= MaxProcessedLength) - goto done; - } - } -done: if (totalLength < MinProcessedLength) throw InsufficientData (SRC_POS, Path); } - shared_ptr Keyfile::ApplyListToPassword (shared_ptr keyfiles, shared_ptr password) + shared_ptr Keyfile::ApplyListToPassword (shared_ptr keyfiles, shared_ptr password, bool EMVOption) { if (!password) password.reset (new VolumePassword); @@ -143,7 +139,7 @@ done: // Apply all keyfiles foreach_ref (const Keyfile &k, keyfilesExp) { - k.Apply (keyfilePool); + k.Apply (keyfilePool, EMVOption); } newPassword->Set (keyfilePool); diff --git a/src/Volume/Keyfile.h b/src/Volume/Keyfile.h index 04674178..bf0a524b 100644 --- a/src/Volume/Keyfile.h +++ b/src/Volume/Keyfile.h @@ -29,7 +29,7 @@ namespace VeraCrypt virtual ~Keyfile () { }; operator FilesystemPath () const { return Path; } - static shared_ptr ApplyListToPassword (shared_ptr keyfiles, shared_ptr password); + static shared_ptr ApplyListToPassword (shared_ptr keyfiles, shared_ptr password, bool EMVOption = false); static shared_ptr DeserializeList (shared_ptr stream, const string &name); static void SerializeList (shared_ptr stream, const string &name, shared_ptr keyfiles); static bool WasHiddenFilePresentInKeyfilePath() { bool r = HiddenFileWasPresentInKeyfilePath; HiddenFileWasPresentInKeyfilePath = false; return r; } @@ -38,7 +38,7 @@ namespace VeraCrypt static const size_t MaxProcessedLength = 1024 * 1024; protected: - void Apply (const BufferPtr &pool) const; + void Apply (const BufferPtr &pool, bool EMVOption) const; static bool HiddenFileWasPresentInKeyfilePath; diff --git a/src/Volume/Volume.cpp b/src/Volume/Volume.cpp index c4a21b3e..6fb906b6 100644 --- a/src/Volume/Volume.cpp +++ b/src/Volume/Volume.cpp @@ -71,7 +71,7 @@ namespace VeraCrypt return EA->GetMode(); } - void Volume::Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, VolumeProtection::Enum protection, shared_ptr protectionPassword, int protectionPim, shared_ptr protectionKdf, shared_ptr protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) + void Volume::Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, bool EMVOption, VolumeProtection::Enum protection, shared_ptr protectionPassword, int protectionPim, shared_ptr protectionKdf, shared_ptr protectionKeyfiles, bool sharedAccessAllowed, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) { make_shared_auto (File, file); @@ -102,10 +102,10 @@ namespace VeraCrypt throw; } - return Open (file, password, pim, kdf, truecryptMode, keyfiles, protection, protectionPassword, protectionPim, protectionKdf,protectionKeyfiles, volumeType, useBackupHeaders, partitionInSystemEncryptionScope); + return Open (file, password, pim, kdf, truecryptMode, keyfiles, EMVOption, protection, protectionPassword, protectionPim, protectionKdf,protectionKeyfiles, volumeType, useBackupHeaders, partitionInSystemEncryptionScope); } - void Volume::Open (shared_ptr volumeFile, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, VolumeProtection::Enum protection, shared_ptr protectionPassword, int protectionPim, shared_ptr protectionKdf,shared_ptr protectionKeyfiles, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) + void Volume::Open (shared_ptr volumeFile, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, bool EMVOption, VolumeProtection::Enum protection, shared_ptr protectionPassword, int protectionPim, shared_ptr protectionKdf,shared_ptr protectionKeyfiles, VolumeType::Enum volumeType, bool useBackupHeaders, bool partitionInSystemEncryptionScope) { if (!volumeFile) throw ParameterIncorrect (SRC_POS); @@ -121,7 +121,7 @@ namespace VeraCrypt try { VolumeHostSize = VolumeFile->Length(); - shared_ptr passwordKey = Keyfile::ApplyListToPassword (keyfiles, password); + shared_ptr passwordKey = Keyfile::ApplyListToPassword (keyfiles, password, EMVOption); bool skipLayoutV1Normal = false; @@ -249,6 +249,7 @@ namespace VeraCrypt protectedVolume.Open (VolumeFile, protectionPassword, protectionPim, protectionKdf, truecryptMode, protectionKeyfiles, + EMVOption, VolumeProtection::ReadOnly, shared_ptr (), 0, shared_ptr (),shared_ptr (), VolumeType::Hidden, diff --git a/src/Volume/Volume.h b/src/Volume/Volume.h index a743a161..85fdbe41 100644 --- a/src/Volume/Volume.h +++ b/src/Volume/Volume.h @@ -123,8 +123,8 @@ namespace VeraCrypt uint64 GetVolumeCreationTime () const { return Header->GetVolumeCreationTime(); } bool IsHiddenVolumeProtectionTriggered () const { return HiddenVolumeProtectionTriggered; } bool IsInSystemEncryptionScope () const { return SystemEncryption; } - void Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr protectionPassword = shared_ptr (), int protectionPim = 0, shared_ptr protectionKdf = shared_ptr (),shared_ptr protectionKeyfiles = shared_ptr (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false); - void Open (shared_ptr volumeFile, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr protectionPassword = shared_ptr (), int protectionPim = 0, shared_ptr protectionKdf = shared_ptr (), shared_ptr protectionKeyfiles = shared_ptr (), VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false); + void Open (const VolumePath &volumePath, bool preserveTimestamps, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, bool EMVOption, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr protectionPassword = shared_ptr (), int protectionPim = 0, shared_ptr protectionKdf = shared_ptr (),shared_ptr protectionKeyfiles = shared_ptr (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false); + void Open (shared_ptr volumeFile, shared_ptr password, int pim, shared_ptr kdf, bool truecryptMode, shared_ptr keyfiles, bool EMVOption, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr protectionPassword = shared_ptr (), int protectionPim = 0, shared_ptr protectionKdf = shared_ptr (), shared_ptr protectionKeyfiles = shared_ptr (), VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false); void ReadSectors (const BufferPtr &buffer, uint64 byteOffset); void ReEncryptHeader (bool backupHeader, const ConstBufferPtr &newSalt, const ConstBufferPtr &newHeaderKey, shared_ptr newPkcs5Kdf); void WriteSectors (const ConstBufferPtr &buffer, uint64 byteOffset); diff --git a/src/Volume/Volume.make b/src/Volume/Volume.make index 91f40fb7..03e06eaa 100644 --- a/src/Volume/Volume.make +++ b/src/Volume/Volume.make @@ -96,11 +96,15 @@ OBJS += ../Crypto/kuznyechik_simd.o OBJSNOOPT += ../Crypto/jitterentropy-base.o0 +OBJS += ../Common/Token.o OBJS += ../Common/Crc.o +OBJS += ../Common/TLVParser.o +OBJS += ../Common/EMVToken.o OBJS += ../Common/Endian.o OBJS += ../Common/GfMul.o OBJS += ../Common/Pkcs5.o OBJS += ../Common/SecurityToken.o +OBJS += ../Common/IccDataExtractor.o VolumeLibrary: Volume.a -- cgit v1.2.3