better error messages

master
Marc Wäckerlin 15 years ago
parent 481ae4ed8d
commit 695ad4fa87
  1. 14
      doc/examples/cryptoki-demo.cxx
  2. 51
      src/cryptoki.hxx
  3. 168
      src/pcsc.hxx

@ -2,20 +2,16 @@
#include <cryptoki.hxx> #include <cryptoki.hxx>
#include <iostream> #include <iostream>
template <int NUM, typename TYPE> std::vector<TYPE> toVector(TYPE in[NUM]) {
return std::vector<TYPE>(in, in+NUM);
}
#define VECTOR(ARRAY) toVector<sizeof(ARRAY)/sizeof(ARRAY[0])>(ARRAY)
template <typename Array> void print(const std::vector<Array>& v) { template <typename Array> void print(const std::vector<Array>& v) {
for (typename std::vector<Array>::const_iterator it(v.begin()); it!=v.end(); ++it) for (typename std::vector<Array>::const_iterator it(v.begin());
it!=v.end(); ++it)
std::cout<<"Item: "<<*it<<std::endl; std::cout<<"Item: "<<*it<<std::endl;
} }
int main(int argc, char const*const*const argv) try { int main(int argc, char const*const*const argv) try {
//std::vector<int> v(toVector<4>((int[]){1,2,3,4})); // //std::vector<int> v(toVector<4>((int[]){1,2,3,4}));
std::vector<int> v(VECTOR(((int[]){1,2,3,4}))); // std::vector<int> v(VECTOR(((int[]){1,2,3,4})));
print(v); // print(v);
cryptoki::Init init(argc==2?argv[1]:"onepin-opensc-pkcs11.so"); cryptoki::Init init(argc==2?argv[1]:"onepin-opensc-pkcs11.so");
cryptoki::Info inf(init.info()); cryptoki::Info inf(init.info());
std::cout<<"##################### INFO #####################"<<std::endl std::cout<<"##################### INFO #####################"<<std::endl

@ -11,10 +11,12 @@
#include <opencryptoki/apiclient.h> #include <opencryptoki/apiclient.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <map>
#include <set> #include <set>
// for inline implementations only // for inline implementations only
#include <sstream> #include <sstream>
#include <cstdlib> // malloc/free
//! C++ Wrapper around Cryptoki API //! C++ Wrapper around Cryptoki API
namespace cryptoki { namespace cryptoki {
@ -30,6 +32,13 @@ namespace cryptoki {
#define UNDEF_CRYPTOKI_FN_LOG #define UNDEF_CRYPTOKI_FN_LOG
#endif #endif
template <int NUM, typename TYPE> std::vector<TYPE> toVector(TYPE in[NUM]) {
return std::vector<TYPE>(in, in+NUM);
}
#define CRYPTOKI_TO_VECTOR(ARRAY) \
toVector<sizeof(ARRAY)/sizeof(ARRAY[0])>(ARRAY)
//============================================================================ //============================================================================
class exception: public std::exception { class exception: public std::exception {
public: public:
@ -64,7 +73,17 @@ namespace cryptoki {
typedef std::set<CK_MECHANISM_TYPE> MechanismList; typedef std::set<CK_MECHANISM_TYPE> MechanismList;
typedef std::vector<CK_ATTRIBUTE_TYPE> AttributeTypeList; typedef std::vector<CK_ATTRIBUTE_TYPE> AttributeTypeList;
typedef std::vector<CK_ATTRIBUTE> AttributeList;
struct Attribute {
Attribute(CK_ATTRIBUTE& attr):
type(attr.type), value((char*)attr.pValue, attr.ulValueLen) {
free(attr.pValue);
attr.pValue = 0;
}
CK_ATTRIBUTE_TYPE type;
std::string value;
};
typedef std::map<CK_ATTRIBUTE_TYPE, Attribute> AttributeList;
// //! Map Attribute Class to type // //! Map Attribute Class to type
// /*! @todo to be completed ... */ // /*! @todo to be completed ... */
@ -1216,14 +1235,32 @@ namespace cryptoki {
AttributeList getattributevalue(const AttributeTypeList& attributes) { AttributeList getattributevalue(const AttributeTypeList& attributes) {
AttributeList res; AttributeList res;
for (AttributeTypeList::const_iterator it(attributes.begin()); CK_ATTRIBUTE* attrs(new CK_ATTRIBUTE[attributes.size()]);
it!=attributes.end(); ++it) AttributeTypeList::const_iterator it(attributes.begin());
res.push_back((CK_ATTRIBUTE){*it, 0, 0}); for (AttributeTypeList::size_type i(0); it!=attributes.end(); ++it, ++i)
attrs[i] = (CK_ATTRIBUTE){*it, 0, 0};
try {
//! calls @c C_GetAttributeValue //! calls @c C_GetAttributeValue
// return check(_session._slot._init->_fn->C_GetAttributeValue(_session, _object, if (check(_session._slot._init->_fn->C_GetAttributeValue
// CK_ATTRIBUTE_PTR, CK_ULONG), (_session, _object, attrs, attributes.size()),
// CRYPTOKI_FN_LOG("C_GetAttributeValue")); CRYPTOKI_FN_LOG("C_GetAttributeValue"))) {
for (AttributeTypeList::size_type i(0); i<attributes.size(); ++i)
if (attrs[i].ulValueLen>0)
attrs[i].pValue = malloc(attrs[i].ulValueLen);
check(_session._slot._init->_fn->C_GetAttributeValue
(_session, _object, attrs, attributes.size()),
CRYPTOKI_FN_LOG("C_GetAttributeValue"));
}
for (AttributeTypeList::size_type i(0); i<attributes.size(); ++i)
if (attrs[i].ulValueLen>0)
res.insert(std::make_pair(attrs[i].type, Attribute(attrs[i])));
return res; return res;
} catch (...) {
for (AttributeTypeList::size_type i(0); i<attributes.size(); ++i)
free(attrs[i].pValue);
delete[] attrs;
throw;
}
} }
/*! @todo Not implemented: /*! @todo Not implemented:

@ -404,19 +404,8 @@ namespace pcsc {
//! Get the describing text of the last error //! Get the describing text of the last error
std::string error() const { std::string error() const {
#ifdef WIN32
std::stringstream ss; std::stringstream ss;
switch (_state) { switch (_state) {
case ERROR_BROKEN_PIPE:
ss<<"The client attempted a smart card operation in a"
<<" remote session, such as a client session running"
<<" on a terminal server, and the operating system in"
<<" use does not support smart card redirection.";
break;
case SCARD_E_BAD_SEEK:
ss<<"There was an error trying to set the smart card file"
<<" object pointer.";
break;
case SCARD_E_CANCELLED: case SCARD_E_CANCELLED:
ss<<"The action was canceled by an SCardCancel request."; ss<<"The action was canceled by an SCardCancel request.";
break; break;
@ -428,27 +417,9 @@ namespace pcsc {
ss<<"The smart card does not meet minimal requirements for" ss<<"The smart card does not meet minimal requirements for"
<<" support."; <<" support.";
break; break;
case SCARD_E_CERTIFICATE_UNAVAILABLE:
ss<<"The requested certificate could not be obtained.";
break;
case SCARD_E_COMM_DATA_LOST:
ss<<"A communications error with the smart card has been detected.";
break;
case SCARD_E_DIR_NOT_FOUND:
ss<<"The specified directory does not exist in the smart card.";
break;
case SCARD_E_DUPLICATE_READER: case SCARD_E_DUPLICATE_READER:
ss<<"The reader driver did not produce a unique reader name."; ss<<"The reader driver did not produce a unique reader name.";
break; break;
case SCARD_E_FILE_NOT_FOUND:
ss<<"The specified file does not exist in the smart card.";
break;
case SCARD_E_ICC_CREATEORDER:
ss<<"The requested order of object creation is not supported.";
break;
case SCARD_E_ICC_INSTALLATION:
ss<<"No primary provider can be found for the smart card.";
break;
case SCARD_E_INSUFFICIENT_BUFFER: case SCARD_E_INSUFFICIENT_BUFFER:
ss<<"The data buffer for returned data is too small for the" ss<<"The data buffer for returned data is too small for the"
<<" returned data."; <<" returned data.";
@ -457,9 +428,6 @@ namespace pcsc {
ss<<"An ATR string obtained from the registry is not a valid" ss<<"An ATR string obtained from the registry is not a valid"
<<" ATR string."; <<" ATR string.";
break; break;
case SCARD_E_INVALID_CHV:
ss<<"The supplied PIN is incorrect.";
break;
case SCARD_E_INVALID_HANDLE: case SCARD_E_INVALID_HANDLE:
ss<<"The supplied handle was not valid."; ss<<"The supplied handle was not valid.";
break; break;
@ -480,18 +448,6 @@ namespace pcsc {
case SCARD_E_NOT_TRANSACTED: case SCARD_E_NOT_TRANSACTED:
ss<<"An attempt was made to end a nonexistent transaction."; ss<<"An attempt was made to end a nonexistent transaction.";
break; break;
case SCARD_E_NO_ACCESS:
ss<<"Access is denied to this file.";
break;
case SCARD_E_NO_DIR:
ss<<"The supplied path does not represent a smart card directory.";
break;
case SCARD_E_NO_FILE:
ss<<"The supplied path does not represent a smart card file.";
break;
case SCARD_E_NO_KEY_CONTAINER:
ss<<"The requested key container does not exist on the smart card.";
break;
case SCARD_E_NO_MEMORY: case SCARD_E_NO_MEMORY:
ss<<"Not enough memory available to complete this command."; ss<<"Not enough memory available to complete this command.";
break; break;
@ -505,9 +461,6 @@ namespace pcsc {
ss<<"The operation requires a smart card, but no smart card" ss<<"The operation requires a smart card, but no smart card"
<<" is currently in the device."; <<" is currently in the device.";
break; break;
case SCARD_E_NO_SUCH_CERTIFICATE:
ss<<"The requested certificate does not exist.";
break;
case SCARD_E_PCI_TOO_SMALL: case SCARD_E_PCI_TOO_SMALL:
ss<<"The PCI receive buffer was too small."; ss<<"The PCI receive buffer was too small.";
break; break;
@ -522,10 +475,6 @@ namespace pcsc {
ss<<"The reader driver does not meet minimal requirements for" ss<<"The reader driver does not meet minimal requirements for"
<<" support."; <<" support.";
break; break;
case SCARD_E_SERVER_TOO_BUSY:
ss<<"The Smart card resource manager is too busy to complete this"
<<" operation.";
break;
case SCARD_E_SERVICE_STOPPED: case SCARD_E_SERVICE_STOPPED:
ss<<"The smart card resource manager has shut down."; ss<<"The smart card resource manager has shut down.";
break; break;
@ -540,26 +489,15 @@ namespace pcsc {
case SCARD_E_TIMEOUT: case SCARD_E_TIMEOUT:
ss<<"The user-specified time-out value has expired."; ss<<"The user-specified time-out value has expired.";
break; break;
case SCARD_E_UNEXPECTED:
ss<<"An unexpected card error has occurred.";
break;
case SCARD_E_UNKNOWN_CARD: case SCARD_E_UNKNOWN_CARD:
ss<<"The specified smart card name is not recognized."; ss<<"The specified smart card name is not recognized.";
break; break;
case SCARD_E_UNKNOWN_READER: case SCARD_E_UNKNOWN_READER:
ss<<"The specified reader name is not recognized."; ss<<"The specified reader name is not recognized.";
break; break;
case SCARD_E_UNKNOWN_RES_MNG:
ss<<"An unrecognized error code was returned from a layered"
<<" component.";
break;
case SCARD_E_UNSUPPORTED_FEATURE: case SCARD_E_UNSUPPORTED_FEATURE:
ss<<"This smart card does not support the requested feature."; ss<<"This smart card does not support the requested feature.";
break; break;
case SCARD_E_WRITE_TOO_MANY:
ss<<"The smartcard does not have enough memory to store the"
<<" information.";
break;
case SCARD_F_COMM_ERROR: case SCARD_F_COMM_ERROR:
ss<<"An internal communications error has been detected."; ss<<"An internal communications error has been detected.";
break; break;
@ -573,26 +511,9 @@ namespace pcsc {
case SCARD_F_WAITED_TOO_LONG: case SCARD_F_WAITED_TOO_LONG:
ss<<"An internal consistency timer has expired."; ss<<"An internal consistency timer has expired.";
break; break;
case SCARD_P_SHUTDOWN:
ss<<"The operation has been aborted to allow the server application"
<<" to exit.";
break;
case SCARD_S_SUCCESS: case SCARD_S_SUCCESS:
ss<<"No error was encountered."; ss<<"No error was encountered.";
break; break;
case SCARD_W_CANCELLED_BY_USER:
ss<<"The action was cancelled by the user.";
break;
case SCARD_W_CARD_NOT_AUTHENTICATED:
ss<<"No PIN was presented to the smart card.";
break;
case SCARD_W_CHV_BLOCKED:
ss<<"The card cannot be accessed because the maximum number"
<<" of PIN entry attempts has been reached.";
break;
case SCARD_W_EOF:
ss<<"The end of the smart card file has been reached.";
break;
case SCARD_W_REMOVED_CARD: case SCARD_W_REMOVED_CARD:
ss<<"The smart card has been removed, so that further communication" ss<<"The smart card has been removed, so that further communication"
<<" is not possible."; <<" is not possible.";
@ -600,9 +521,6 @@ namespace pcsc {
case SCARD_W_RESET_CARD: case SCARD_W_RESET_CARD:
ss<<"The smart card was reset."; ss<<"The smart card was reset.";
break; break;
case SCARD_W_SECURITY_VIOLATION:
ss<<"Access was denied because of a security violation.";
break;
case SCARD_W_UNPOWERED_CARD: case SCARD_W_UNPOWERED_CARD:
ss<<"Power has been removed from the smart card, so that" ss<<"Power has been removed from the smart card, so that"
<<" further communication is not possible."; <<" further communication is not possible.";
@ -614,10 +532,93 @@ namespace pcsc {
ss<<"The reader cannot communicate with the smart card," ss<<"The reader cannot communicate with the smart card,"
<<" due to ATR configuration conflicts."; <<" due to ATR configuration conflicts.";
break; break;
#ifdef WIN32
case ERROR_BROKEN_PIPE:
ss<<"The client attempted a smart card operation in a"
<<" remote session, such as a client session running"
<<" on a terminal server, and the operating system in"
<<" use does not support smart card redirection.";
break;
case SCARD_E_BAD_SEEK:
ss<<"There was an error trying to set the smart card file"
<<" object pointer.";
break;
case SCARD_E_CERTIFICATE_UNAVAILABLE:
ss<<"The requested certificate could not be obtained.";
break;
case SCARD_E_COMM_DATA_LOST:
ss<<"A communications error with the smart card has been detected.";
break;
case SCARD_E_DIR_NOT_FOUND:
ss<<"The specified directory does not exist in the smart card.";
break;
case SCARD_E_FILE_NOT_FOUND:
ss<<"The specified file does not exist in the smart card.";
break;
case SCARD_E_ICC_CREATEORDER:
ss<<"The requested order of object creation is not supported.";
break;
case SCARD_E_ICC_INSTALLATION:
ss<<"No primary provider can be found for the smart card.";
break;
case SCARD_E_INVALID_CHV:
ss<<"The supplied PIN is incorrect.";
break;
case SCARD_E_NO_ACCESS:
ss<<"Access is denied to this file.";
break;
case SCARD_E_NO_DIR:
ss<<"The supplied path does not represent a smart card directory.";
break;
case SCARD_E_NO_FILE:
ss<<"The supplied path does not represent a smart card file.";
break;
case SCARD_E_NO_KEY_CONTAINER:
ss<<"The requested key container does not exist on the smart card.";
break;
case SCARD_E_NO_SUCH_CERTIFICATE:
ss<<"The requested certificate does not exist.";
break;
case SCARD_E_SERVER_TOO_BUSY:
ss<<"The Smart card resource manager is too busy to complete this"
<<" operation.";
break;
case SCARD_E_UNEXPECTED:
ss<<"An unexpected card error has occurred.";
break;
case SCARD_E_UNKNOWN_RES_MNG:
ss<<"An unrecognized error code was returned from a layered"
<<" component.";
break;
case SCARD_E_WRITE_TOO_MANY:
ss<<"The smartcard does not have enough memory to store the"
<<" information.";
break;
case SCARD_P_SHUTDOWN:
ss<<"The operation has been aborted to allow the server application"
<<" to exit.";
break;
case SCARD_W_CANCELLED_BY_USER:
ss<<"The action was cancelled by the user.";
break;
case SCARD_W_CARD_NOT_AUTHENTICATED:
ss<<"No PIN was presented to the smart card.";
break;
case SCARD_W_CHV_BLOCKED:
ss<<"The card cannot be accessed because the maximum number"
<<" of PIN entry attempts has been reached.";
break;
case SCARD_W_EOF:
ss<<"The end of the smart card file has been reached.";
break;
case SCARD_W_SECURITY_VIOLATION:
ss<<"Access was denied because of a security violation.";
break;
case SCARD_W_WRONG_CHV: case SCARD_W_WRONG_CHV:
ss<<"The card cannot be accessed because the wrong PIN was" ss<<"The card cannot be accessed because the wrong PIN was"
<<" presented."; <<" presented.";
break; break;
#endif
default: default:
ss<<"unknown PCSC state=0x" ss<<"unknown PCSC state=0x"
<<std::hex<<std::setfill('0')<<std::setw(8)<<_state; <<std::hex<<std::setfill('0')<<std::setw(8)<<_state;
@ -636,9 +637,6 @@ namespace pcsc {
<<(_state&0xffff); <<(_state&0xffff);
} }
return ss.str(); return ss.str();
#else
return pcsc_stringify_error(_state);
#endif
} }
//................................................................methods //................................................................methods

Loading…
Cancel
Save