more documentation; refs #28
This commit is contained in:
@@ -375,7 +375,7 @@ EXTRACT_PACKAGE = NO
|
||||
# If the EXTRACT_STATIC tag is set to YES all static members of a file
|
||||
# will be included in the documentation.
|
||||
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_STATIC = YES
|
||||
|
||||
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
|
||||
# defined locally in source files will be included in the documentation.
|
||||
@@ -1634,7 +1634,7 @@ DOT_FONTPATH =
|
||||
# indirect inheritance relations. Setting this tag to YES will force the
|
||||
# CLASS_DIAGRAMS tag to NO.
|
||||
|
||||
CLASS_GRAPH = YES
|
||||
CLASS_GRAPH = NO
|
||||
|
||||
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
||||
# will generate a graph for each documented class showing the direct and
|
||||
@@ -1688,7 +1688,7 @@ INCLUDED_BY_GRAPH = YES
|
||||
# the time of a run. So in most cases it will be better to enable call graphs
|
||||
# for selected functions only using the \callgraph command.
|
||||
|
||||
CALL_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
|
||||
# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
|
||||
# doxygen will generate a caller dependency graph for every global function
|
||||
@@ -1696,7 +1696,7 @@ CALL_GRAPH = YES
|
||||
# the time of a run. So in most cases it will be better to enable caller
|
||||
# graphs for selected functions only using the \callergraph command.
|
||||
|
||||
CALLER_GRAPH = YES
|
||||
CALLER_GRAPH = NO
|
||||
|
||||
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
|
||||
# will generate a graphical hierarchy of all classes instead of a textual one.
|
||||
|
@@ -9,9 +9,11 @@ template <typename Array> void print(const std::vector<Array>& v) {
|
||||
}
|
||||
|
||||
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(VECTOR(((int[]){1,2,3,4})));
|
||||
// print(v);
|
||||
std::cout<<"Example for buffer to vector conversion:"<<std::endl;
|
||||
int buff[] = {1, 2, 3, 4};
|
||||
std::vector<int> vec(cryptoki::toVector(buff));
|
||||
print(vec);
|
||||
std::cout<<std::endl;
|
||||
cryptoki::Library cryptoki(argc==2?argv[1]:"onepin-opensc-pkcs11.so");
|
||||
cryptoki::Info inf(cryptoki.info());
|
||||
std::cout<<"Library-Version: "<<pcsc::version()<<std::endl;
|
||||
@@ -61,15 +63,14 @@ int main(int argc, char const*const*const argv) try {
|
||||
<<"utcTime: \""<<crypto::readable(info.utcTime)
|
||||
<<'"'<<std::endl;
|
||||
cryptoki::MechanismList mechs(it->mechanismlist());
|
||||
for (cryptoki::MechanismList::iterator it2(mechs.begin());
|
||||
it2!=mechs.end(); ++it2) {
|
||||
cryptoki::MechanismInfo mechinfo(it->mechanisminfo(*it2));
|
||||
for (cryptoki::MechanismList::iterator mechinfo(mechs.begin());
|
||||
mechinfo!=mechs.end(); ++mechinfo) {
|
||||
std::cout<<"-------------------- Mechanism -----------------"<<std::endl
|
||||
<<"id: \""<<mechinfo.id<<'"'<<std::endl
|
||||
<<"name: \""<<mechinfo.name<<'"'<<std::endl
|
||||
<<"minKeySize: \""<<mechinfo.minKeySize<<'"'<<std::endl
|
||||
<<"maxKeySize: \""<<mechinfo.maxKeySize<<'"'<<std::endl
|
||||
<<"flags: \""<<mechinfo.flags<<'"'<<std::endl;
|
||||
<<"id: \""<<mechinfo->id<<'"'<<std::endl
|
||||
<<"name: \""<<mechinfo->name<<'"'<<std::endl
|
||||
<<"minKeySize: \""<<mechinfo->minKeySize<<'"'<<std::endl
|
||||
<<"maxKeySize: \""<<mechinfo->maxKeySize<<'"'<<std::endl
|
||||
<<"flags: \""<<mechinfo->flags<<'"'<<std::endl;
|
||||
}
|
||||
cryptoki::Session session(*it);
|
||||
cryptoki::ObjectList objs(session.find());
|
||||
@@ -80,8 +81,8 @@ int main(int argc, char const*const*const argv) try {
|
||||
cryptoki::AttributeMap attrs(it->attributes());
|
||||
for (cryptoki::AttributeMap::iterator it(attrs.begin());
|
||||
it!=attrs.end(); ++it) {
|
||||
std::cout<<" - attribute: "<<it->second.name()<<"=\""
|
||||
<<crypto::readable(it->second.value)<<'"'<<std::endl;
|
||||
std::cout<<" - attribute: "<<it->second.name()<<" = "<<std::endl
|
||||
<<crypto::readable(it->second.value, 15, 5)<<std::endl;
|
||||
}
|
||||
}
|
||||
std::cout<<"**** Success"<<std::endl;
|
||||
|
@@ -99,7 +99,11 @@ int main(int argc, char** argv) try {
|
||||
auto start = std::chrono::system_clock::now();
|
||||
#endif
|
||||
for (int i(0); i<r; ++i)
|
||||
keys[0].sign(txt, CKM_RSA_PKCS);
|
||||
std::cout<<"Text:"<<std::endl
|
||||
<<crypto::readable(txt)<<std::endl
|
||||
<<"Signature:"<<std::endl
|
||||
<<crypto::readable(keys[0].sign(txt, CKM_RSA_PKCS))
|
||||
<<std::endl;
|
||||
#ifndef MRW__OLD_PRE11_COMPILER
|
||||
auto end = std::chrono::system_clock::now();
|
||||
auto elapsed(std::chrono::duration_cast<std::chrono::milliseconds>
|
||||
|
@@ -11,15 +11,18 @@
|
||||
#include <QtNetwork/QSslCertificate>
|
||||
#include <QtCore/QDateTime>
|
||||
|
||||
void show(const QStringList& sl, const std::string& p="item: ") {
|
||||
for (QStringList::const_iterator s(sl.begin()); s!=sl.end(); ++s)
|
||||
std::cout<<p<<QString(s->toUtf8()).toStdString()<<std::endl;
|
||||
}
|
||||
|
||||
// show certificate information
|
||||
void show(const suisseid::Certificate& cert) {
|
||||
// makes use of qt library's certificate class
|
||||
QSslCertificate c(QByteArray(cert.data(), cert.size()), QSsl::Der);
|
||||
std::cout<<"Certificate info: CN="
|
||||
<<QString(c.subjectInfo(QSslCertificate::CommonName)
|
||||
.toUtf8()).toStdString()
|
||||
<<std::endl
|
||||
<<" Valid until: "
|
||||
std::cout<<"Certificate info:";
|
||||
show(c.subjectInfo(QSslCertificate::CommonName), " CN=");
|
||||
std::cout<<" Valid until: "
|
||||
<<QString(c.expiryDate().toString().toUtf8()).toStdString()
|
||||
<<std::endl;
|
||||
}
|
||||
|
@@ -96,10 +96,12 @@ namespace crypto {
|
||||
}
|
||||
|
||||
inline std::string hexTxt(const std::string& data,
|
||||
std::string::size_type len=20) {
|
||||
std::string::size_type len=20,
|
||||
std::string::size_type indent=0) {
|
||||
std::stringstream res;
|
||||
std::string::size_type pos(0);
|
||||
for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it) {
|
||||
if (pos%len==0) res<<std::string(indent, ' ');
|
||||
res<<std::hex<<std::setfill('0')<<std::setw(2)
|
||||
<<(unsigned int)(unsigned char)*it;
|
||||
++pos;
|
||||
@@ -114,13 +116,14 @@ namespace crypto {
|
||||
}
|
||||
|
||||
inline std::string readable(const std::string& data,
|
||||
std::string::size_type len=20) {
|
||||
std::string::size_type len=20,
|
||||
std::string::size_type indent=0) {
|
||||
if (!data.size())
|
||||
return "<empty>";
|
||||
return std::string(indent, ' ')+"<empty>";
|
||||
else if (data.find_first_not_of(VALID_CHARS)<data.size())
|
||||
return hexTxt(data, len);
|
||||
return hexTxt(data, len, indent);
|
||||
else
|
||||
return "\""+data+"\"";
|
||||
return std::string(indent, ' ')+"\""+data+"\"";
|
||||
}
|
||||
|
||||
//! Convert binary to readable hexadecimal
|
||||
|
466
src/cryptoki.hxx
466
src/cryptoki.hxx
@@ -29,13 +29,26 @@
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
|
||||
/*! @defgroup gcryptoki C++ Wrapper around Cryptoki API */
|
||||
/*! @defgroup gcryptoki C++ Wrapper around Cryptoki API
|
||||
|
||||
Wrapper to abstract the ugly PKCS#11 C-API with nice C++ features,
|
||||
such as exception handling, memory management, etc.
|
||||
|
||||
The cryptoky library loads a dynamic library that is responsible
|
||||
for translating the card specific commands. The library is passed
|
||||
in the constructor of cryptoki::Library. Then method
|
||||
cryptoki::Library::slotList returns all slots found on the
|
||||
computer. */
|
||||
//@{
|
||||
/*! @defgroup cryptokilib Cryptoki C++ Library */
|
||||
/*! @defgroup globaloperator Global Operator */
|
||||
/*! @defgroup cryptokitypes Cryptoki C++ Types and Auxiliary */
|
||||
/*! @defgroup cryptokiexceptions Cryptoki Exceptions */
|
||||
/** @example cryptoki-demo.cxx */
|
||||
/** @example cryptoki-sign-demo.cxx */
|
||||
//@}
|
||||
|
||||
/// @addtogroup cryptokitypes
|
||||
//@{
|
||||
#ifndef CRYPTOKI_FN_LOG
|
||||
#include <iostream>
|
||||
#if __GNUC__ >= 2
|
||||
@@ -58,6 +71,7 @@
|
||||
" __FILE__ ":" CRYPTOKI_QUOTE(__LINE__)
|
||||
#endif
|
||||
#endif
|
||||
//@}
|
||||
|
||||
namespace pcsc {
|
||||
std::string version();
|
||||
@@ -69,6 +83,11 @@ namespace cryptoki {
|
||||
//! @addtogroup cryptokitypes
|
||||
//@{
|
||||
|
||||
/// Map cryptoki number to a string, care about unavailable and infinite
|
||||
/** Cryptoky knows illegal values (unavailable information), which
|
||||
is mapped to @c - and infinite values which are mapped to @c ∞
|
||||
when converted to string. All other numbers just show the number
|
||||
as numeric string. */
|
||||
inline std::string string(CK_ULONG num) {
|
||||
switch (num) {
|
||||
case CK_UNAVAILABLE_INFORMATION: return "-";
|
||||
@@ -81,11 +100,10 @@ namespace cryptoki {
|
||||
}
|
||||
}
|
||||
|
||||
template <int NUM, typename TYPE> std::vector<TYPE> toVector(TYPE in[NUM]) {
|
||||
return std::vector<TYPE>(in, in+NUM);
|
||||
/// Convert any kind of array (buffer) to an std::vector.
|
||||
template <typename TYPE> std::vector<TYPE> toVector(TYPE in[]) {
|
||||
return std::vector<TYPE>(in, in+sizeof(in)/sizeof(in[0]));
|
||||
}
|
||||
#define CRYPTOKI_TO_VECTOR(ARRAY) \
|
||||
toVector<sizeof(ARRAY)/sizeof(ARRAY[0])>(ARRAY)
|
||||
|
||||
//@}
|
||||
|
||||
@@ -136,10 +154,9 @@ namespace cryptoki {
|
||||
class Object;
|
||||
typedef std::vector<Object> ObjectList;
|
||||
|
||||
typedef std::set<CK_MECHANISM_TYPE> MechanismList;
|
||||
|
||||
typedef std::vector<CK_ATTRIBUTE_TYPE> AttributeTypeList;
|
||||
|
||||
/// Represents a cryproki attribute and maps to C++ types.
|
||||
class Attribute {
|
||||
public:
|
||||
Attribute(CK_ATTRIBUTE_TYPE t = -1): type(t) {}
|
||||
@@ -171,6 +188,7 @@ namespace cryptoki {
|
||||
a.ulValueLen = value.size();
|
||||
return a;
|
||||
}
|
||||
/// Textual name of the attribute.
|
||||
std::string name() const {
|
||||
switch (type) {
|
||||
case CKA_CLASS: return "CLASS";
|
||||
@@ -234,30 +252,39 @@ namespace cryptoki {
|
||||
case CKA_HAS_RESET: return "HAS_RESET";
|
||||
case CKA_VENDOR_DEFINED: return "VENDOR_DEFINED";
|
||||
//case CKA_IBM_OPAQUE: return "IBM_OPAQUE";
|
||||
default: return "unknown";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
std::string readableValue() const {
|
||||
/// Textual representation of the value.
|
||||
std::string readableValue(std::string::size_type len=20,
|
||||
std::string::size_type indent=0) const {
|
||||
std::string res(indent, ' ');
|
||||
switch (type) {
|
||||
case CKA_CLASS:
|
||||
switch (*((CK_OBJECT_CLASS*)&value[0])) {
|
||||
case CKO_DATA: return "DATA";
|
||||
case CKO_CERTIFICATE: return "CERTIFICATE";
|
||||
case CKO_PUBLIC_KEY: return "PUBLIC_KEY";
|
||||
case CKO_PRIVATE_KEY: return "PRIVATE_KEY";
|
||||
case CKO_SECRET_KEY: return "SECRET_KEY";
|
||||
case CKO_HW_FEATURE: return "HW_FEATURE";
|
||||
case CKO_DOMAIN_PARAMETERS: return "DOMAIN_PARAMETERS";
|
||||
case CKO_VENDOR_DEFINED: return "VENDOR_DEFINED";
|
||||
default: return "unknown";
|
||||
case CKO_DATA: return res+"DATA";
|
||||
case CKO_CERTIFICATE: return res+"CERTIFICATE";
|
||||
case CKO_PUBLIC_KEY: return res+"PUBLIC_KEY";
|
||||
case CKO_PRIVATE_KEY: return res+"PRIVATE_KEY";
|
||||
case CKO_SECRET_KEY: return res+"SECRET_KEY";
|
||||
case CKO_HW_FEATURE: return res+"HW_FEATURE";
|
||||
case CKO_DOMAIN_PARAMETERS: return res+"DOMAIN_PARAMETERS";
|
||||
case CKO_VENDOR_DEFINED: return res+"VENDOR_DEFINED";
|
||||
default: return res+"UNKNOWN";
|
||||
}
|
||||
default: return crypto::readable(value);
|
||||
default: return crypto::readable(value, len, indent);
|
||||
}
|
||||
}
|
||||
/// Initialize from a given type.
|
||||
/** To use this method, you must know what type the attribute
|
||||
represents. */
|
||||
template<typename TYPE> Attribute& from(const TYPE& v) {
|
||||
value = std::string((char*)&v, sizeof(TYPE));
|
||||
return *this;
|
||||
}
|
||||
/// Convert to a given type.
|
||||
/** To use this method, you must know what type the attribute
|
||||
represents. */
|
||||
template<typename TYPE> TYPE to() const {
|
||||
assert(sizeof(TYPE)==value.size());
|
||||
return *reinterpret_cast<const TYPE*>(&value[0]);
|
||||
@@ -268,91 +295,70 @@ namespace cryptoki {
|
||||
typedef std::map<CK_ATTRIBUTE_TYPE, Attribute> AttributeMap;
|
||||
typedef std::vector<Attribute> AttributeList;
|
||||
|
||||
// class Class {
|
||||
// public:
|
||||
// CK_OBJECT_CLASS class;
|
||||
// };
|
||||
|
||||
//class
|
||||
|
||||
// //! Map Attribute Class to type
|
||||
// /*! @todo to be completed ... */
|
||||
// #define CRYPTOKI_DECLARE_ATTR(ATTR_ID, TYPE) \//
|
||||
// template<> class AttributeType<ATTR_ID> { \//
|
||||
// public: typedef TYPE Type; \//
|
||||
// }
|
||||
// template<CK_ATTRIBUTE_TYPE Attribute> class AttributeType {};
|
||||
// CRYPTOKI_DECLARE_ATTR(CKA_CLASS, CK_OBJECT_CLASS);
|
||||
// CRYPTOKI_DECLARE_ATTR(CKA_HW_FEATURE_TYPE, CK_HW_FEATURE);
|
||||
// CRYPTOKI_DECLARE_ATTR(CKA_VALUE, FixString<16>);
|
||||
// CRYPTOKI_DECLARE_ATTR(CKA_RESET_ON_INIT, CK_BBOOL);
|
||||
// CRYPTOKI_DECLARE_ATTR(CKA_HAS_RESET, CK_BBOOL);
|
||||
// // CRYPTOKI_DECLARE_ATTR(CKA_VALUE, ); - byte array
|
||||
// // CRYPTOKI_DECLARE_ATTR(, );
|
||||
// // CRYPTOKI_DECLARE_ATTR(, );
|
||||
// // CRYPTOKI_DECLARE_ATTR(, );
|
||||
// // CRYPTOKI_DECLARE_ATTR(, );
|
||||
// template<> class AttributeType<CKA_KEY_TYPE> {
|
||||
// public: typedef CK_KEY_TYPE Type;
|
||||
// public: typedef Type Param;
|
||||
// };
|
||||
// template<> class AttributeType<CKA_APPLICATION> {
|
||||
// public: typedef CK_CHAR Type;
|
||||
// public: typedef std::string Param;
|
||||
// };
|
||||
// template<> class AttributeType<CKA_VALUE> {
|
||||
// public: typedef CKA_BYTE Type;
|
||||
// public: typedef std::string Param;
|
||||
// };
|
||||
// #undef CRYPTOKI_DECLARE_ATTR
|
||||
|
||||
/// String with fixed length.
|
||||
/** FixString represents a string with a fix with spaces and can be
|
||||
converted from and to a std::string by adding and removing the
|
||||
fill-spaces. */
|
||||
template<std::string::size_type SIZE>
|
||||
class FixString: public std::string {
|
||||
public:
|
||||
FixString() {}
|
||||
FixString(const char* const cStr) {
|
||||
*this = std::string(cStr, SIZE);
|
||||
size_type pos(find_last_not_of(" "));
|
||||
if (pos!=npos) resize(pos+1); else resize(0);
|
||||
}
|
||||
FixString(const unsigned char* const cStr) {
|
||||
*this = std::string((const char*)cStr, SIZE);
|
||||
size_type pos(find_last_not_of(" "));
|
||||
if (pos!=npos) resize(pos+1); else resize(0);
|
||||
}
|
||||
FixString& operator=(const std::string& other) {
|
||||
std::string::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
FixString& operator=(const char* const cStr) {
|
||||
*this = std::string(cStr, SIZE);
|
||||
size_type pos(find_last_not_of(" "));
|
||||
if (pos!=npos) resize(pos+1); else resize(0);
|
||||
return *this;
|
||||
}
|
||||
FixString& operator=(const unsigned char* const cStr) {
|
||||
*this = std::string((const char*)cStr, SIZE);
|
||||
size_type pos(find_last_not_of(" "));
|
||||
if (pos!=npos) resize(pos+1); else resize(0);
|
||||
return *this;
|
||||
}
|
||||
operator unsigned char*() {
|
||||
return (unsigned char*)begin().operator->();
|
||||
}
|
||||
FixString fix() {
|
||||
FixString cpy(*this);
|
||||
cpy.resize(SIZE, ' ');
|
||||
return cpy;
|
||||
}
|
||||
};
|
||||
public:
|
||||
FixString() {}
|
||||
FixString(const char* const cStr) {
|
||||
*this = std::string(cStr, SIZE);
|
||||
size_type pos(find_last_not_of(" "));
|
||||
if (pos!=npos) resize(pos+1); else resize(0);
|
||||
}
|
||||
FixString(const unsigned char* const cStr) {
|
||||
*this = std::string((const char*)cStr, SIZE);
|
||||
size_type pos(find_last_not_of(" "));
|
||||
if (pos!=npos) resize(pos+1); else resize(0);
|
||||
}
|
||||
FixString& operator=(const std::string& other) {
|
||||
std::string::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
FixString& operator=(const char* const cStr) {
|
||||
*this = std::string(cStr, SIZE);
|
||||
size_type pos(find_last_not_of(" "));
|
||||
if (pos!=npos) resize(pos+1); else resize(0);
|
||||
return *this;
|
||||
}
|
||||
FixString& operator=(const unsigned char* const cStr) {
|
||||
*this = std::string((const char*)cStr, SIZE);
|
||||
size_type pos(find_last_not_of(" "));
|
||||
if (pos!=npos) resize(pos+1); else resize(0);
|
||||
return *this;
|
||||
}
|
||||
operator unsigned char*() {
|
||||
return (unsigned char*)begin().operator->();
|
||||
}
|
||||
FixString fix() {
|
||||
FixString cpy(*this);
|
||||
cpy.resize(SIZE, ' ');
|
||||
return cpy;
|
||||
}
|
||||
};
|
||||
|
||||
/// C++ representation of mechanism information.
|
||||
struct MechanismInfo {
|
||||
CK_MECHANISM_TYPE id;
|
||||
std::string name;
|
||||
CK_ULONG minKeySize;
|
||||
CK_ULONG maxKeySize;
|
||||
CK_FLAGS flags;
|
||||
MechanismInfo(CK_MECHANISM_TYPE type): id(type) {
|
||||
/// Construct from type with undefined infos. Use assigment later.
|
||||
MechanismInfo(CK_MECHANISM_TYPE type):
|
||||
minKeySize(0), maxKeySize(0), flags(0) {
|
||||
*this=type;
|
||||
}
|
||||
/// Fully construct from type and infos.
|
||||
MechanismInfo(CK_MECHANISM_TYPE type, const CK_MECHANISM_INFO& info) {
|
||||
*this=type;
|
||||
*this=info;
|
||||
}
|
||||
/// Set name and id from CK_MECHANISM_TYPE.
|
||||
MechanismInfo& operator=(CK_MECHANISM_TYPE type) {
|
||||
id=type;
|
||||
switch (id) {
|
||||
case CKM_RSA_PKCS_KEY_PAIR_GEN: name="RSA_PKCS_KEY_PAIR_GEN"; break;
|
||||
case CKM_RSA_PKCS: name="RSA_PKCS"; break;
|
||||
@@ -378,7 +384,7 @@ namespace cryptoki {
|
||||
case CKM_X9_42_DH_DERIVE: name="X9_42_DH_DERIVE"; break;
|
||||
case CKM_X9_42_DH_HYBRID_DERIVE: name="X9_42_DH_HYBRID_DERIVE"; break;
|
||||
case CKM_X9_42_MQV_DERIVE: name="X9_42_MQV_DERIVE"; break;
|
||||
//case CKM_SHA256_RSA_PKCS: name="SHA256_RSA_PKCS"; break;
|
||||
case CKM_SHA256_RSA_PKCS: name="SHA256_RSA_PKCS"; break;
|
||||
case CKM_RC2_KEY_GEN: name="RC2_KEY_GEN"; break;
|
||||
case CKM_RC2_ECB: name="RC2_ECB"; break;
|
||||
case CKM_RC2_CBC: name="RC2_CBC"; break;
|
||||
@@ -421,15 +427,15 @@ namespace cryptoki {
|
||||
case CKM_RIPEMD160: name="RIPEMD160"; break;
|
||||
case CKM_RIPEMD160_HMAC: name="RIPEMD160_HMAC"; break;
|
||||
case CKM_RIPEMD160_HMAC_GENERAL: name="RIPEMD160_HMAC_GENERAL"; break;
|
||||
//case CKM_SHA256: name="SHA256"; break;
|
||||
//case CKM_SHA256_HMAC: name="SHA256_HMAC"; break;
|
||||
//case CKM_SHA256_HMAC_GENERAL: name="SHA256_HMAC_GENERAL"; break;
|
||||
//case CKM_SHA384: name="SHA384"; break;
|
||||
//case CKM_SHA384_HMAC: name="SHA384_HMAC"; break;
|
||||
//case CKM_SHA384_HMAC_GENERAL: name="SHA384_HMAC_GENERAL"; break;
|
||||
//case CKM_SHA512: name="SHA512"; break;
|
||||
//case CKM_SHA512_HMAC: name="SHA512_HMAC"; break;
|
||||
//case CKM_SHA512_HMAC_GENERAL: name="SHA512_HMAC_GENERAL"; break;
|
||||
case CKM_SHA256: name="SHA256"; break;
|
||||
case CKM_SHA256_HMAC: name="SHA256_HMAC"; break;
|
||||
case CKM_SHA256_HMAC_GENERAL: name="SHA256_HMAC_GENERAL"; break;
|
||||
case CKM_SHA384: name="SHA384"; break;
|
||||
case CKM_SHA384_HMAC: name="SHA384_HMAC"; break;
|
||||
case CKM_SHA384_HMAC_GENERAL: name="SHA384_HMAC_GENERAL"; break;
|
||||
case CKM_SHA512: name="SHA512"; break;
|
||||
case CKM_SHA512_HMAC: name="SHA512_HMAC"; break;
|
||||
case CKM_SHA512_HMAC_GENERAL: name="SHA512_HMAC_GENERAL"; break;
|
||||
case CKM_CAST_KEY_GEN: name="CAST_KEY_GEN"; break;
|
||||
case CKM_CAST_ECB: name="CAST_ECB"; break;
|
||||
case CKM_CAST_CBC: name="CAST_CBC"; break;
|
||||
@@ -442,19 +448,21 @@ namespace cryptoki {
|
||||
case CKM_CAST3_MAC: name="CAST3_MAC"; break;
|
||||
case CKM_CAST3_MAC_GENERAL: name="CAST3_MAC_GENERAL"; break;
|
||||
case CKM_CAST3_CBC_PAD: name="CAST3_CBC_PAD"; break;
|
||||
//case CKM_CAST5_KEY_GEN: name="CAST5_KEY_GEN"; break;
|
||||
case CKM_CAST128_KEY_GEN: name="CAST5_KEY_GEN or CAST128_KEY_GEN"; break;
|
||||
//case CKM_CAST5_ECB: name="CAST5_ECB"; break;
|
||||
case CKM_CAST128_ECB: name="CAST5_ECB or CAST128_ECB"; break;
|
||||
//case CKM_CAST5_CBC: name="CAST5_CBC"; break;
|
||||
case CKM_CAST128_CBC: name="CAST5_CBC or CAST128_CBC"; break;
|
||||
//case CKM_CAST5_MAC: name="CAST5_MAC"; break;
|
||||
case CKM_CAST128_MAC: name="CAST5_MAC or CAST128_MAC"; break;
|
||||
//case CKM_CAST5_MAC_GENERAL: name="CAST5_MAC_GENERAL"; break;
|
||||
case CKM_CAST128_MAC_GENERAL:
|
||||
name="CAST5_MAC_GENERAL or CAST128_MAC_GENERAL"; break;
|
||||
//case CKM_CAST5_CBC_PAD: name="CAST5_CBC_PAD"; break;
|
||||
case CKM_CAST128_CBC_PAD: name="CAST5_CBC_PAD or CAST128_CBC_PAD"; break;
|
||||
case CKM_CAST5_KEY_GEN: name="CAST5_KEY_GEN"; break;
|
||||
//case CKM_CAST128_KEY_GEN: name="CAST5_KEY_GEN or
|
||||
//CAST128_KEY_GEN"; break;
|
||||
case CKM_CAST5_ECB: name="CAST5_ECB"; break;
|
||||
//case CKM_CAST128_ECB: name="CAST5_ECB or CAST128_ECB"; break;
|
||||
case CKM_CAST5_CBC: name="CAST5_CBC"; break;
|
||||
//case CKM_CAST128_CBC: name="CAST5_CBC or CAST128_CBC"; break;
|
||||
case CKM_CAST5_MAC: name="CAST5_MAC"; break;
|
||||
//case CKM_CAST128_MAC: name="CAST5_MAC or CAST128_MAC"; break;
|
||||
case CKM_CAST5_MAC_GENERAL: name="CAST5_MAC_GENERAL"; break;
|
||||
//case CKM_CAST128_MAC_GENERAL: name="CAST5_MAC_GENERAL or
|
||||
//CAST128_MAC_GENERAL"; break;
|
||||
case CKM_CAST5_CBC_PAD: name="CAST5_CBC_PAD"; break;
|
||||
//case CKM_CAST128_CBC_PAD: name="CAST5_CBC_PAD or
|
||||
//CAST128_CBC_PAD"; break;
|
||||
case CKM_RC5_KEY_GEN: name="RC5_KEY_GEN"; break;
|
||||
case CKM_RC5_ECB: name="RC5_ECB"; break;
|
||||
case CKM_RC5_CBC: name="RC5_CBC"; break;
|
||||
@@ -476,31 +484,34 @@ namespace cryptoki {
|
||||
name="CONCATENATE_DATA_AND_BASE"; break;
|
||||
case CKM_XOR_BASE_AND_DATA: name="XOR_BASE_AND_DATA"; break;
|
||||
case CKM_EXTRACT_KEY_FROM_KEY: name="EXTRACT_KEY_FROM_KEY"; break;
|
||||
case CKM_SSL3_PRE_MASTER_KEY_GEN: name="SSL3_PRE_MASTER_KEY_GEN"; break;
|
||||
case CKM_SSL3_PRE_MASTER_KEY_GEN:
|
||||
name="SSL3_PRE_MASTER_KEY_GEN"; break;
|
||||
case CKM_SSL3_MASTER_KEY_DERIVE: name="SSL3_MASTER_KEY_DERIVE"; break;
|
||||
case CKM_SSL3_KEY_AND_MAC_DERIVE: name="SSL3_KEY_AND_MAC_DERIVE"; break;
|
||||
case CKM_SSL3_KEY_AND_MAC_DERIVE:
|
||||
name="SSL3_KEY_AND_MAC_DERIVE"; break;
|
||||
case CKM_SSL3_MASTER_KEY_DERIVE_DH:
|
||||
name="SSL3_MASTER_KEY_DERIVE_DH"; break;
|
||||
case CKM_TLS_PRE_MASTER_KEY_GEN: name="TLS_PRE_MASTER_KEY_GEN"; break;
|
||||
case CKM_TLS_MASTER_KEY_DERIVE: name="TLS_MASTER_KEY_DERIVE"; break;
|
||||
case CKM_TLS_KEY_AND_MAC_DERIVE: name="TLS_KEY_AND_MAC_DERIVE"; break;
|
||||
case CKM_TLS_MASTER_KEY_DERIVE_DH: name="TLS_MASTER_KEY_DERIVE_DH"; break;
|
||||
case CKM_TLS_MASTER_KEY_DERIVE_DH:
|
||||
name="TLS_MASTER_KEY_DERIVE_DH"; break;
|
||||
case CKM_SSL3_MD5_MAC: name="SSL3_MD5_MAC"; break;
|
||||
case CKM_SSL3_SHA1_MAC: name="SSL3_SHA1_MAC"; break;
|
||||
case CKM_MD5_KEY_DERIVATION: name="MD5_KEY_DERIVATION"; break;
|
||||
case CKM_MD2_KEY_DERIVATION: name="MD2_KEY_DERIVATION"; break;
|
||||
case CKM_SHA1_KEY_DERIVATION: name="SHA1_KEY_DERIVATION"; break;
|
||||
//case CKM_SHA256_KEY_DERIVATION: name="SHA256_KEY_DERIVATION"; break;
|
||||
case CKM_SHA256_KEY_DERIVATION: name="SHA256_KEY_DERIVATION"; break;
|
||||
case CKM_PBE_MD2_DES_CBC: name="PBE_MD2_DES_CBC"; break;
|
||||
case CKM_PBE_MD5_DES_CBC: name="PBE_MD5_DES_CBC"; break;
|
||||
case CKM_PBE_MD5_CAST_CBC: name="PBE_MD5_CAST_CBC"; break;
|
||||
case CKM_PBE_MD5_CAST3_CBC: name="PBE_MD5_CAST3_CBC"; break;
|
||||
//case CKM_PBE_MD5_CAST5_CBC: name="PBE_MD5_CAST5_CBC"; break;
|
||||
case CKM_PBE_MD5_CAST128_CBC:
|
||||
name="PBE_MD5_CAST5_CBC or PBE_MD5_CAST128_CBC"; break;
|
||||
//case CKM_PBE_SHA1_CAST5_CBC: name="PBE_SHA1_CAST5_CBC"; break;
|
||||
case CKM_PBE_SHA1_CAST128_CBC:
|
||||
name="PBE_SHA1_CAST5_CBC or PBE_SHA1_CAST128_CBC"; break;
|
||||
case CKM_PBE_MD5_CAST5_CBC: name="PBE_MD5_CAST5_CBC"; break;
|
||||
//case CKM_PBE_MD5_CAST128_CBC: name="PBE_MD5_CAST5_CBC or
|
||||
//PBE_MD5_CAST128_CBC"; break;
|
||||
case CKM_PBE_SHA1_CAST5_CBC: name="PBE_SHA1_CAST5_CBC"; break;
|
||||
//case CKM_PBE_SHA1_CAST128_CBC: name="PBE_SHA1_CAST5_CBC or
|
||||
//PBE_SHA1_CAST128_CBC"; break;
|
||||
case CKM_PBE_SHA1_RC4_128: name="PBE_SHA1_RC4_128"; break;
|
||||
case CKM_PBE_SHA1_RC4_40: name="PBE_SHA1_RC4_40"; break;
|
||||
case CKM_PBE_SHA1_DES3_EDE_CBC: name="PBE_SHA1_DES3_EDE_CBC"; break;
|
||||
@@ -508,7 +519,8 @@ namespace cryptoki {
|
||||
case CKM_PBE_SHA1_RC2_128_CBC: name="PBE_SHA1_RC2_128_CBC"; break;
|
||||
case CKM_PBE_SHA1_RC2_40_CBC: name="PBE_SHA1_RC2_40_CBC"; break;
|
||||
case CKM_PKCS5_PBKD2: name="PKCS5_PBKD2"; break;
|
||||
case CKM_PBA_SHA1_WITH_SHA1_HMAC: name="PBA_SHA1_WITH_SHA1_HMAC"; break;
|
||||
case CKM_PBA_SHA1_WITH_SHA1_HMAC:
|
||||
name="PBA_SHA1_WITH_SHA1_HMAC"; break;
|
||||
case CKM_KEY_WRAP_LYNKS: name="KEY_WRAP_LYNKS"; break;
|
||||
case CKM_KEY_WRAP_SET_OAEP: name="KEY_WRAP_SET_OAEP"; break;
|
||||
case CKM_SKIPJACK_KEY_GEN: name="SKIPJACK_KEY_GEN"; break;
|
||||
@@ -532,9 +544,9 @@ namespace cryptoki {
|
||||
case CKM_BATON_COUNTER: name="BATON_COUNTER"; break;
|
||||
case CKM_BATON_SHUFFLE: name="BATON_SHUFFLE"; break;
|
||||
case CKM_BATON_WRAP: name="BATON_WRAP"; break;
|
||||
//case CKM_ECDSA_KEY_PAIR_GEN: name="ECDSA_KEY_PAIR_GEN"; break;
|
||||
case CKM_EC_KEY_PAIR_GEN:
|
||||
name="ECDSA_KEY_PAIR_GEN or EC_KEY_PAIR_GEN"; break;
|
||||
case CKM_ECDSA_KEY_PAIR_GEN: name="ECDSA_KEY_PAIR_GEN"; break;
|
||||
//case CKM_EC_KEY_PAIR_GEN: name="ECDSA_KEY_PAIR_GEN or
|
||||
//EC_KEY_PAIR_GEN"; break;
|
||||
case CKM_ECDSA: name="ECDSA"; break;
|
||||
case CKM_ECDSA_SHA1: name="ECDSA_SHA1"; break;
|
||||
case CKM_ECDH1_DERIVE: name="ECDH1_DERIVE"; break;
|
||||
@@ -559,13 +571,26 @@ namespace cryptoki {
|
||||
case CKM_VENDOR_DEFINED: name="VENDOR_DEFINED"; break;
|
||||
default: {
|
||||
std::stringstream ss;
|
||||
ss<<"unknown mechanism: "<<id;
|
||||
throw exception(ss.str());
|
||||
ss<<id;
|
||||
name=ss.str();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
/// Assign information.
|
||||
MechanismInfo& operator=(const CK_MECHANISM_INFO& info) {
|
||||
minKeySize = info.ulMinKeySize;
|
||||
maxKeySize = info.ulMaxKeySize;
|
||||
flags = info.flags;
|
||||
return *this;
|
||||
}
|
||||
bool operator<(const MechanismInfo& o) const {
|
||||
return id<o.id;
|
||||
}
|
||||
};
|
||||
typedef std::set<MechanismInfo> MechanismList;
|
||||
|
||||
/// Handle slot information.
|
||||
struct SlotInfo {
|
||||
FixString<64> slotDescription;
|
||||
FixString<32> manufacturerID;
|
||||
@@ -589,6 +614,7 @@ namespace cryptoki {
|
||||
struct TokenInfo; // forward declaration
|
||||
inline std::ostream& operator<<(std::ostream& out, const TokenInfo& ti);
|
||||
|
||||
/// Handle token information.
|
||||
struct TokenInfo {
|
||||
FixString<32> label;
|
||||
FixString<32> manufacturerID;
|
||||
@@ -638,6 +664,7 @@ namespace cryptoki {
|
||||
|
||||
};
|
||||
|
||||
/// Textual representation for token information.
|
||||
inline std::ostream& operator<<(std::ostream& out, const TokenInfo& ti) {
|
||||
return out
|
||||
<<"label="<<ti.label<<std::endl
|
||||
@@ -661,7 +688,8 @@ namespace cryptoki {
|
||||
<<ti.firmwareVersion.minor<<std::endl
|
||||
<<"utcTime="<<ti.utcTime;
|
||||
}
|
||||
|
||||
|
||||
/// Handle library information.
|
||||
struct Info {
|
||||
CK_VERSION cryptokiVersion;
|
||||
FixString<32> manufacturerID;
|
||||
@@ -676,20 +704,22 @@ namespace cryptoki {
|
||||
//@{
|
||||
|
||||
/// Load Cryptoki Library for use with Smart Card.
|
||||
/** This is your starting point when accessing tokens through
|
||||
PKCS#11. Get an instance using Library::Library. */
|
||||
class Library {
|
||||
|
||||
friend class Slot;
|
||||
|
||||
public:
|
||||
|
||||
//! Initialize for a given library (default cryptoki)
|
||||
/*! Please notem, that you must not instanciate more than one
|
||||
Init per unique function list!
|
||||
//! Initialize for a given library
|
||||
/*! @note Do not instanciate more than one Library instance per
|
||||
shared library. Normally you need only one instance.
|
||||
|
||||
@param library name of the shared library that supports pkcs#11
|
||||
@param exc wether exceptions should be thrown */
|
||||
Library(const std::string& library, bool exc=true):
|
||||
_init(library, exc) {
|
||||
_init(new Init(library, exc)) {
|
||||
CRYPTOLOG("log");
|
||||
}
|
||||
|
||||
@@ -699,8 +729,9 @@ namespace cryptoki {
|
||||
CRYPTOLOG("log");
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
private:
|
||||
|
||||
/// Initiatlize the library: load and unload the shared object.
|
||||
class Init {
|
||||
|
||||
private:
|
||||
@@ -725,13 +756,8 @@ namespace cryptoki {
|
||||
std::string error(CK_RV res);
|
||||
|
||||
public:
|
||||
|
||||
//! Initialize for a given library (default cryptoki)
|
||||
/*! Please notem, that you must not instanciate more than one
|
||||
Init per unique function list!
|
||||
|
||||
@param library name of the shared library that supports pkcs#11
|
||||
@param exc wether exceptions should be thrown */
|
||||
|
||||
/// Called from Library::Library
|
||||
Init(const std::string& library="opensc-pkcs11.so", bool exc=true);
|
||||
|
||||
~Init();
|
||||
@@ -767,14 +793,12 @@ namespace cryptoki {
|
||||
|
||||
public:
|
||||
|
||||
/// Get pointer to cryptoki API functions.
|
||||
/** Used internally, normally you shouldn't use this directly. */
|
||||
CK_FUNCTION_LIST* operator->() {
|
||||
return _init->fn();
|
||||
}
|
||||
|
||||
bool exc() {
|
||||
return _init->_exc;
|
||||
}
|
||||
|
||||
/*! @name C Like Error Handling
|
||||
|
||||
You are strongly recommended not to disable exception
|
||||
@@ -782,6 +806,11 @@ namespace cryptoki {
|
||||
operation whether it was successful or not. These methods
|
||||
provide all you need for that. */
|
||||
//@{
|
||||
|
||||
/// @return true if exceptions are thrown in case of error
|
||||
bool exc() {
|
||||
return _init->_exc;
|
||||
}
|
||||
|
||||
/*! @return @c true if last cryptoki on this object call was successful */
|
||||
operator bool() {
|
||||
@@ -792,13 +821,15 @@ namespace cryptoki {
|
||||
std::string error() {
|
||||
return _init->error();
|
||||
}
|
||||
|
||||
|
||||
/// Convert @c CK_RV return code to a human readable text.
|
||||
std::string error(CK_RV res) {
|
||||
return _init->error(res);
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
/// Get cryptoki library informartion.
|
||||
Info info() {
|
||||
CRYPTOLOG("log");
|
||||
Info inf;
|
||||
@@ -825,7 +856,7 @@ namespace cryptoki {
|
||||
|
||||
private:
|
||||
|
||||
mrw::Shared<Init> _init;
|
||||
std::shared_ptr<Init> _init;
|
||||
|
||||
};
|
||||
|
||||
@@ -843,16 +874,21 @@ namespace cryptoki {
|
||||
|
||||
public:
|
||||
|
||||
Slot(const Library& lib, CK_SLOT_ID slot):
|
||||
_library(lib), _slot(slot), _res(CKR_OK) {
|
||||
CRYPTOLOG("ID="<<_slot);
|
||||
}
|
||||
|
||||
Slot(const Slot& o):
|
||||
_library(o._library), _slot(o._slot), _res(o._res) {
|
||||
CRYPTOLOG("ID="<<_slot);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// Slots are created from Library::slotList.
|
||||
Slot(const Library& lib, CK_SLOT_ID slot):
|
||||
_library(lib), _slot(slot), _res(CKR_OK) {
|
||||
CRYPTOLOG("ID="<<_slot);
|
||||
}
|
||||
|
||||
/// Slots are created from Library::slotList.
|
||||
/** Empty constructor needs immediate assignment. */
|
||||
Slot(): _slot(0), _res(-1) {
|
||||
CRYPTOLOG("ID="<<_slot);
|
||||
}
|
||||
@@ -877,6 +913,8 @@ namespace cryptoki {
|
||||
return _res==CKR_OK;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/*! @name C Like Error Handling
|
||||
|
||||
You are strongly recommended not to disable exception
|
||||
@@ -897,23 +935,23 @@ namespace cryptoki {
|
||||
|
||||
//@}
|
||||
|
||||
/// Access to the Library.
|
||||
Library& library() {
|
||||
return _library;
|
||||
}
|
||||
|
||||
/// Get the Slot's MechanismInfo given a @c CK_MECHANISM_TYPE
|
||||
/** Used internally by mechanismlist(). */
|
||||
MechanismInfo mechanisminfo(CK_MECHANISM_TYPE mechanism) {
|
||||
CRYPTOLOG("log");
|
||||
MechanismInfo info(mechanism);
|
||||
CK_MECHANISM_INFO cInfo;
|
||||
CK_MECHANISM_INFO info;
|
||||
//! calls @c C_GetMechanismInfo
|
||||
check(_library->C_GetMechanismInfo(_slot, mechanism, &cInfo),
|
||||
check(_library->C_GetMechanismInfo(_slot, mechanism, &info),
|
||||
CRYPTOKI_FN_LOG("C_GetMechanismInfo"));
|
||||
info.minKeySize = cInfo.ulMinKeySize;
|
||||
info.maxKeySize = cInfo.ulMaxKeySize;
|
||||
info.flags = cInfo.flags;
|
||||
return info;
|
||||
return MechanismInfo(mechanism, info);
|
||||
}
|
||||
|
||||
/// Get a list of the Slot's mechanisms.
|
||||
MechanismList mechanismlist() {
|
||||
CRYPTOLOG("log");
|
||||
MechanismList res;
|
||||
@@ -930,7 +968,7 @@ namespace cryptoki {
|
||||
return res;
|
||||
}
|
||||
for (CK_ULONG i(0); i<count; ++i)
|
||||
res.insert(mechanisms[i]);
|
||||
res.insert(mechanisminfo(mechanisms[i]));
|
||||
} catch (...) {
|
||||
delete[] mechanisms;
|
||||
throw;
|
||||
@@ -961,18 +999,79 @@ namespace cryptoki {
|
||||
return TokenInfo(cInfo);
|
||||
}
|
||||
|
||||
/*! @bug does not compile:
|
||||
@code
|
||||
/// Initialize a token.
|
||||
/** If the token has not been initialized (i.e. new from the
|
||||
factory), then the @c pin parameter becomes the initial value
|
||||
of the SO PIN. If the token is being reinitialized, the @c pin
|
||||
parameter is checked against the existing SO PIN to
|
||||
authorize the initialization operation. In both cases, the
|
||||
SO PIN is the value @c pin after the function completes
|
||||
successfully. If the SO PIN is lost, then the card must be
|
||||
reinitialized using a mechanism outside the scope of this
|
||||
standard. The CKF_TOKEN_INITIALIZED flag in the
|
||||
CK_TOKEN_INFO structure indicates the action that will
|
||||
result from calling C_InitToken. If set, the token will be
|
||||
reinitialized, and the client must supply the existing SO
|
||||
password in @c pin.
|
||||
|
||||
When a token is initialized, all objects that can be
|
||||
destroyed are destroyed (i.e., all except for
|
||||
“indestructible” objects such as keys built into the
|
||||
token). Also, access by the normal user is disabled until
|
||||
the SO sets the normal user’s PIN. Depending on the token,
|
||||
some “default” objects may be created, and attributes of
|
||||
some objects may be set to default values.
|
||||
|
||||
If the token has a “protected authentication path”, as
|
||||
indicated by the CKF_PROTECTED_AUTHENTICATION_PATH flag in
|
||||
its CK_TOKEN_INFO being set, then that means that there is
|
||||
some way for a user to be authenticated to the token without
|
||||
having the application send a PIN through the Cryptoki
|
||||
library. One such possibility is that the user enters a PIN
|
||||
on a PINpad on the token itself, or on the slot device. To
|
||||
initialize a token with such a protected authentication
|
||||
path, the @c pin parameter to C_InitToken should be empty.
|
||||
During the execution of C_InitToken, the SO’s PIN will be
|
||||
entered through the protected authentication path.
|
||||
|
||||
If the token has a protected authentication path other than
|
||||
a PINpad, then it is token- dependent whether or not
|
||||
C_InitToken can be used to initialize the token.
|
||||
|
||||
A token cannot be initialized if Cryptoki detects that any
|
||||
application has an open session with it; when a call to
|
||||
C_InitToken is made under such circumstances, the call fails
|
||||
with error CKR_SESSION_EXISTS. Unfortunately, it may happen
|
||||
when C_InitToken is called that some other application does
|
||||
have an open session with the token, but Cryptoki cannot
|
||||
detect this, because it cannot detect anything about other
|
||||
applications using the token. If this is the case, then the
|
||||
consequences of the C_InitToken call are undefined.
|
||||
|
||||
The C_InitToken function may not be sufficient to properly
|
||||
initialize complex tokens. In these situations, an
|
||||
initialization mechanism outside the scope of Cryptoki must
|
||||
be employed. The definition of “complex token” is product
|
||||
specific.
|
||||
|
||||
@param pin SO's initial PIN
|
||||
@param label label of the token */
|
||||
bool inittoken(std::string pin, FixString<32> label) {
|
||||
CRYPTOLOG("log");
|
||||
CRYPTOLOG("log");
|
||||
//! calls @c C_InitToken
|
||||
return check(_library->C_InitToken
|
||||
(_slot,
|
||||
(unsigned char*)&pin[0], pin.size(),
|
||||
(unsigned char*)label.&fix()[0])
|
||||
CRYPTOKI_FN_LOG("C_InitToken"));
|
||||
if (pin.size())
|
||||
return check(_library->C_InitToken
|
||||
(_slot,
|
||||
(unsigned char*)&pin[0], pin.size(),
|
||||
(unsigned char*)&label.fix()[0]),
|
||||
CRYPTOKI_FN_LOG("C_InitToken"));
|
||||
else
|
||||
return check(_library->C_InitToken
|
||||
(_slot,
|
||||
0, 0, // pin from external pin pad
|
||||
(unsigned char*)&label.fix()[0]),
|
||||
CRYPTOKI_FN_LOG("C_InitToken"));
|
||||
}
|
||||
@endcode */
|
||||
|
||||
/*! @todo Not implemented:
|
||||
@code
|
||||
@@ -983,14 +1082,14 @@ namespace cryptoki {
|
||||
bool registerforslotevent(SlotEventListener&) {
|
||||
CRYPTOLOG("log");
|
||||
//! calls @c C_WaitForSlotEvent
|
||||
return check(_library->C_WaitForSlotEvent(CK_FLAGS, &_slot, CK_VOID_PTR),
|
||||
return check(_library->C_WaitForSlotEvent(CK_FLAGS, &_slot, 0),
|
||||
CRYPTOKI_FN_LOG("C_WaitForSlotEvent"));
|
||||
}
|
||||
@endcode */
|
||||
};
|
||||
|
||||
//! Session Management
|
||||
//! Not implemented: CK_RV C_CloseAllSessions(CK_SLOT_ID);
|
||||
/// Session Management
|
||||
/** @note Not implemented: CK_RV C_CloseAllSessions(CK_SLOT_ID); */
|
||||
class Session {
|
||||
private:
|
||||
|
||||
@@ -2167,14 +2266,16 @@ namespace cryptoki {
|
||||
|
||||
}
|
||||
|
||||
//! @groupadd globaloperator
|
||||
//! @groupadd cryptokitypes
|
||||
//@{
|
||||
/// Append a cryptoki::Attribute to a cryptoki::AttributeList.
|
||||
inline cryptoki::AttributeList& operator<<(cryptoki::AttributeList& list,
|
||||
const cryptoki::Attribute& attr) {
|
||||
CRYPTOLOG("log");
|
||||
list.push_back(attr);
|
||||
return list;
|
||||
}
|
||||
/// Append a cryptoki::Attribute to a new copy of a cryptoki::AttributeList.
|
||||
inline cryptoki::AttributeList operator<<(const cryptoki::AttributeList& list,
|
||||
const cryptoki::Attribute& attr) {
|
||||
CRYPTOLOG("log");
|
||||
@@ -2184,5 +2285,4 @@ inline cryptoki::AttributeList operator<<(const cryptoki::AttributeList& list,
|
||||
}
|
||||
//@}
|
||||
|
||||
//@}
|
||||
#endif
|
||||
|
@@ -133,6 +133,12 @@ namespace suisseid {
|
||||
no_digsig() throw():
|
||||
exception("no digital signature certificate found") {}
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
class slot_not_found: public exception {
|
||||
public:
|
||||
slot_not_found(const std::string& name) throw():
|
||||
exception("matching cryptoki slot for "+name+" not found") {}
|
||||
};
|
||||
//@}
|
||||
|
||||
/*! @addtogroup suisseidtypes */
|
||||
@@ -145,9 +151,12 @@ namespace suisseid {
|
||||
|
||||
/*! @addtogroup suisseidconsts */
|
||||
//@{
|
||||
const std::string NON_REP = "SwissSign_nonRep ";
|
||||
const std::string DIG_SIG = "SwissSign_digSig ";
|
||||
const std::string DATA_ENC = "SwissSign_dataEnc ";
|
||||
/// Label of the key for digital signature certificate.
|
||||
const std::string NON_REP = "SwissSign_nonRep ";
|
||||
/// Label of the key for authentication certificate
|
||||
const std::string DIG_SIG = "SwissSign_digSig ";
|
||||
/// Label of the key required for getting the certificates
|
||||
const std::string DATA_ENC = "SwissSign_dataEnc ";
|
||||
//@}
|
||||
|
||||
/*! @addtogroup suisseidlib */
|
||||
@@ -160,16 +169,22 @@ namespace suisseid {
|
||||
|
||||
public:
|
||||
|
||||
/// Status of the card's certificates
|
||||
/** @note by now, only @c MISSING and @c VALID is supported */
|
||||
enum CertStatus {
|
||||
MISSING,
|
||||
EXPIRES_SOON,
|
||||
EXPIRED,
|
||||
REVOKED,
|
||||
VALID
|
||||
MISSING, ///< certificate is missing, needs initiatlization
|
||||
EXPIRES_SOON, ///< certificate will soon expire, needs renewal
|
||||
EXPIRED, ///< certificate is expired, needs new purchase
|
||||
REVOKED, ///< certificate has been revoked and is invalid
|
||||
VALID ///< certificate is valid
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/// Instanciation is done within suisseid::Scanner
|
||||
/** Instance requires a connenction to the reader an a cryptoky
|
||||
library. This is passes automatically when this class is
|
||||
instanciated through suisseid::Scanner. */
|
||||
Card(mrw::Shared<pcsc::Connection::Reader> reader,
|
||||
const cryptoki::Library& cryptoki):
|
||||
cardos::Commands(reader),
|
||||
@@ -177,13 +192,17 @@ namespace suisseid {
|
||||
}
|
||||
virtual ~Card() {}
|
||||
|
||||
/// Find the matching cryptoki::Slot for further access
|
||||
/** @throws slot_not_found if not exactly one matching slot exists */
|
||||
cryptoki::Slot slot() {
|
||||
cryptoki::SlotList slots(_cryptoki.slotList(true, name()));
|
||||
if (slots.size()==1) return slots[0];
|
||||
throw std::runtime_error("matching cryptoki slot not found");
|
||||
throw slot_not_found(name());
|
||||
}
|
||||
|
||||
/// Minimum allowed PIN length for this card.
|
||||
virtual unsigned int minimalPinLength() = 0;
|
||||
/// Maximum allowed PIN length for this card.
|
||||
virtual unsigned int maximalPinLength() = 0;
|
||||
|
||||
//! Name of the token/slot
|
||||
@@ -196,15 +215,17 @@ namespace suisseid {
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
/// status of the certificates on the card
|
||||
/// Status of the certificates on the card
|
||||
virtual CertStatus certStatus() {
|
||||
return MISSING;
|
||||
}
|
||||
|
||||
/// Starts and returns a cryptoki::Session.
|
||||
cryptoki::Session session() {
|
||||
return cryptoki::Session(slot());
|
||||
}
|
||||
|
||||
/// Starts a cryptoki::Session and returns cryptoki::Session::Info.
|
||||
cryptoki::Session::Info sessionInfo() {
|
||||
return session().getsessioninfo();
|
||||
}
|
||||
@@ -258,7 +279,8 @@ namespace suisseid {
|
||||
class Post: public Card {
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/// @copydoc Card::Card
|
||||
Post(mrw::Shared<pcsc::Connection::Reader> reader,
|
||||
const cryptoki::Library& cryptoki):
|
||||
Card(reader, cryptoki), _minPinLen(0), _maxPinLen(-1) {
|
||||
|
Reference in New Issue
Block a user