1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-11 19:08:26 -06:00

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 <d45.poubelle@gmail.com>
Co-authored-by: red4game <redemgaiming@gmail.com>
Co-authored-by: Brice.Namy <brice.namy@insa-rennes.fr>
Co-authored-by: vocthor <pieceo108@gmail.com>
Co-authored-by: vocthor <67202139+vocthor@users.noreply.github.com>
Co-authored-by: Andrei COCAN <andrei.cocan@insa-rennes.fr>
Co-authored-by: AndreiCocan <95496161+AndreiCocan@users.noreply.github.com>
Co-authored-by: francoisLEROUX <francois3443@gmail.com>
This commit is contained in:
mmauv
2023-06-28 22:51:43 +02:00
committed by GitHub
parent f4e109afcf
commit 502ab9112a
65 changed files with 2721 additions and 612 deletions

View File

@@ -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 SecurityTokenKeyfilePath () const;
operator TokenKeyfilePath () const;
void GetKeyfileData(vector<byte>& 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 <byte> &keyfileData, const string &name);
static void DeleteKeyfile (const SecurityTokenKeyfile &keyfile);
static vector <SecurityTokenKeyfile> GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter = nullptr, const wstring keyfileIdFilter = wstring());
static void GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector <byte> &keyfileData);
static list <SecurityTokenInfo> GetAvailableTokens ();
static SecurityTokenInfo GetTokenInfo (CK_SLOT_ID slotId);
static void CloseAllSessions() throw ();
static void CloseLibrary();
static void CreateKeyfile(CK_SLOT_ID slotId, vector <byte>& keyfileData, const string& name);
static void DeleteKeyfile(const SecurityTokenKeyfile& keyfile);
static vector <SecurityTokenKeyfile> GetAvailableKeyfiles(CK_SLOT_ID* slotIdFilter = nullptr, const wstring keyfileIdFilter = wstring());
static list <SecurityTokenInfo> GetAvailableTokens();
static SecurityTokenInfo GetTokenInfo(CK_SLOT_ID slotId);
#ifdef TC_WINDOWS
static void InitLibrary (const wstring &pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback);
static void InitLibrary(const wstring& pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback);
#else
static void InitLibrary (const string &pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> warningCallback);
static void InitLibrary(const string& pkcs11LibraryPath, unique_ptr <GetPinFunctor> pinCallback, unique_ptr <SendExceptionFunctor> 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 <CK_OBJECT_HANDLE> GetObjects (CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass);
static void GetObjectAttribute (CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector <byte> &attributeValue);
static list <CK_SLOT_ID> GetTokenSlots ();
static void Login (CK_SLOT_ID slotId, const 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 <CK_OBJECT_HANDLE> GetObjects(CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass);
static void GetObjectAttribute(CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector <byte>& attributeValue);
static list <CK_SLOT_ID> GetTokenSlots();
static void Login(CK_SLOT_ID slotId, const 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 <GetPinFunctor> PinCallback;
@@ -216,10 +208,12 @@ namespace VeraCrypt
#ifdef TC_WINDOWS
static HMODULE Pkcs11LibraryHandle;
#else
static void *Pkcs11LibraryHandle;
static void* Pkcs11LibraryHandle;
#endif
static map <CK_SLOT_ID, Pkcs11Session> Sessions;
static unique_ptr <SendExceptionFunctor> WarningCallback;
friend void SecurityTokenKeyfile::GetKeyfileData(vector <byte>& keyfileData) const;
};
}