From 034b64f4153550cbe5849bcbfc27e187377cc512 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Thu, 29 Jun 2023 00:06:20 +0200 Subject: EMV keyfile support: Overall code improvements and bug fixes --- src/Common/PCSCException.cpp | 199 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 src/Common/PCSCException.cpp (limited to 'src/Common/PCSCException.cpp') diff --git a/src/Common/PCSCException.cpp b/src/Common/PCSCException.cpp new file mode 100644 index 00000000..93fff181 --- /dev/null +++ b/src/Common/PCSCException.cpp @@ -0,0 +1,199 @@ +#include "PCSCException.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 + +namespace VeraCrypt +{ + PCSCException::operator string() const + { + if (ErrorCode == SCARD_S_SUCCESS) + return string(); + + static const struct{ + LONG_PCSC ErrorCode; + const char* ErrorString; + } ErrorStrings[] = { +#define SC_ERR(CODE) { CODE, #CODE }, +#ifdef TC_WINDOWS + SC_ERR(ERROR_BROKEN_PIPE) + SC_ERR(SCARD_E_NO_PIN_CACHE) + SC_ERR(SCARD_E_PIN_CACHE_EXPIRED) + SC_ERR(SCARD_E_READ_ONLY_CARD) + SC_ERR(SCARD_W_CACHE_ITEM_NOT_FOUND) + SC_ERR(SCARD_W_CACHE_ITEM_STALE) + SC_ERR(SCARD_W_CACHE_ITEM_TOO_BIG) +#endif + SC_ERR(SCARD_E_BAD_SEEK) + SC_ERR(SCARD_E_CANCELLED) + SC_ERR(SCARD_E_CANT_DISPOSE) + SC_ERR(SCARD_E_CARD_UNSUPPORTED) + SC_ERR(SCARD_E_CERTIFICATE_UNAVAILABLE) + SC_ERR(SCARD_E_COMM_DATA_LOST) + SC_ERR(SCARD_E_COMM_DATA_LOST) + SC_ERR(SCARD_E_DIR_NOT_FOUND) + SC_ERR(SCARD_E_DUPLICATE_READER) + SC_ERR(SCARD_E_FILE_NOT_FOUND) + SC_ERR(SCARD_E_ICC_CREATEORDER) + SC_ERR(SCARD_E_ICC_INSTALLATION) + SC_ERR(SCARD_E_INSUFFICIENT_BUFFER) + SC_ERR(SCARD_E_INVALID_ATR) + SC_ERR(SCARD_E_INVALID_CHV) + SC_ERR(SCARD_E_INVALID_HANDLE) + SC_ERR(SCARD_E_INVALID_PARAMETER) + SC_ERR(SCARD_E_INVALID_TARGET) + SC_ERR(SCARD_E_INVALID_VALUE) + SC_ERR(SCARD_E_NO_ACCESS) + SC_ERR(SCARD_E_NO_DIR) + SC_ERR(SCARD_E_NO_FILE) + SC_ERR(SCARD_E_NO_KEY_CONTAINER) + SC_ERR(SCARD_E_NO_MEMORY) + SC_ERR(SCARD_E_NO_READERS_AVAILABLE) + SC_ERR(SCARD_E_NO_SERVICE) + SC_ERR(SCARD_E_NO_SMARTCARD) + SC_ERR(SCARD_E_NO_SUCH_CERTIFICATE) + SC_ERR(SCARD_E_NOT_READY) + SC_ERR(SCARD_E_NOT_TRANSACTED) + SC_ERR(SCARD_E_PCI_TOO_SMALL) + SC_ERR(SCARD_E_PROTO_MISMATCH) + SC_ERR(SCARD_E_READER_UNAVAILABLE) + SC_ERR(SCARD_E_READER_UNSUPPORTED) + SC_ERR(SCARD_E_SERVER_TOO_BUSY) + SC_ERR(SCARD_E_SERVICE_STOPPED) + SC_ERR(SCARD_E_SHARING_VIOLATION) + SC_ERR(SCARD_E_SYSTEM_CANCELLED) + SC_ERR(SCARD_E_TIMEOUT) + SC_ERR(SCARD_E_UNEXPECTED) + SC_ERR(SCARD_E_UNKNOWN_CARD) + SC_ERR(SCARD_E_UNKNOWN_READER) + SC_ERR(SCARD_E_UNKNOWN_RES_MNG) + SC_ERR(SCARD_E_UNSUPPORTED_FEATURE) + SC_ERR(SCARD_E_WRITE_TOO_MANY) + SC_ERR(SCARD_F_COMM_ERROR) + SC_ERR(SCARD_F_INTERNAL_ERROR) + SC_ERR(SCARD_F_UNKNOWN_ERROR) + SC_ERR(SCARD_W_CANCELLED_BY_USER) + SC_ERR(SCARD_W_CARD_NOT_AUTHENTICATED) + SC_ERR(SCARD_W_CHV_BLOCKED) + SC_ERR(SCARD_W_EOF) + SC_ERR(SCARD_W_REMOVED_CARD) + SC_ERR(SCARD_W_RESET_CARD) + SC_ERR(SCARD_W_SECURITY_VIOLATION) + SC_ERR(SCARD_W_UNPOWERED_CARD) + SC_ERR(SCARD_W_UNRESPONSIVE_CARD) + SC_ERR(SCARD_W_UNSUPPORTED_CARD) + SC_ERR(SCARD_W_WRONG_CHV) +#undef SC_ERR + }; + + for (size_t i = 0; i < array_capacity(ErrorStrings); ++i) + { + if (ErrorStrings[i].ErrorCode == ErrorCode) + return ErrorStrings[i].ErrorString; + } + + stringstream s; + s << "0x" << ErrorCode; + return s.str(); + } + +#ifdef TC_HEADER_Common_Exception + void PCSCException::Show(HWND parent) const + { + string errorString = string(*this); + + if (!errorString.empty()) + { + if (!GetDictionaryValue(errorString.c_str())) + { + 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] = ' '; + } + } + wchar_t err[8192]; + StringCbPrintfW(err, sizeof(err), L"%s:\n\n%hs%s", GetString("PCSC_ERROR"), errorString.c_str()); + ErrorDirect(err, parent); + } + else + { + wstring err = GetString(errorString.c_str()); + ErrorDirect(err.c_str(), parent); + } + } + } +#endif // TC_HEADER_Common_Exception + +#ifdef TC_HEADER_Platform_Exception + + void PCSCException::Deserialize(shared_ptr stream) + { + Exception::Deserialize(stream); + Serializer sr(stream); + sr.Deserialize("ErrorCode", ErrorCode); + } + + void PCSCException::Serialize(shared_ptr stream) const + { + Exception::Serialize(stream); + Serializer sr(stream); + sr.Serialize("ErrorCode", ErrorCode); + } + +# 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(PCSCException); + +#endif + + CommandAPDUNotValid::operator string() const + { + return string(ErrorStr); + } + +#ifdef TC_HEADER_Common_Exception + void CommandAPDUNotValid::Show(HWND parent) const + { + string msgBody = "Command APDU invalid.\n\n\n(If you report a bug in connection with this, please include the following technical information in the bug report:\n" + SrcPos + "\nLast Error = " + ErrorStr + ")"; + MessageBoxA (parent, msgBody.c_str(), "VeraCrypt", MB_ICONERROR | MB_SETFOREGROUND); + } +#endif // TC_HEADER_Common_Exception + +#ifdef TC_HEADER_Platform_Exception + + void CommandAPDUNotValid::Deserialize(shared_ptr stream) + { + Exception::Deserialize(stream); + Serializer sr(stream); + sr.Deserialize("SrcPos", SrcPos); + sr.Deserialize("ErrorStr", ErrorStr); + } + + void CommandAPDUNotValid::Serialize(shared_ptr stream) const + { + Exception::Serialize(stream); + Serializer sr(stream); + sr.Serialize("SrcPos", SrcPos); + sr.Serialize("ErrorStr", ErrorStr); + } + +# 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(CommandAPDUNotValid); + +#endif +} \ No newline at end of file -- cgit v1.2.3