From e2dc8a359552aa6e540ac337ef1158ebb15c70f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Wed, 26 Mar 2014 15:07:54 +0000 Subject: [PATCH] cleanup of connection management, new major version number 3, use static connection methods; refs #26, refs #28, refs #29 --- configure.in | 9 +- doc/examples/cardos-demo.cxx | 5 +- doc/examples/create-files-demo.cxx | 35 +- doc/examples/makefile.am | 11 +- doc/examples/moc_cardgui-model.cxx | 88 +++ doc/examples/pcsc-demo.cxx | 5 +- src/cardgui-model.hxx | 122 +++++ src/cardgui.cxx | 20 + src/cardgui.hxx | 108 ++++ src/cardgui.ui | 103 ++++ src/cardos.hxx | 229 +++++++- src/cryptaux.hxx | 51 +- src/makefile.am | 18 +- src/openssl-engine.cxx | 2 + src/openssl-engine.hxx | 2 + src/openssl.hxx | 2 + src/password.hxx | 30 ++ src/password.ui | 101 ++++ src/pcsc.hxx | 829 +++++++++++++---------------- src/suisseid.hxx | 18 +- 20 files changed, 1236 insertions(+), 552 deletions(-) create mode 100644 doc/examples/moc_cardgui-model.cxx create mode 100644 src/cardgui-model.hxx create mode 100644 src/cardgui.cxx create mode 100644 src/cardgui.hxx create mode 100644 src/cardgui.ui create mode 100644 src/password.hxx create mode 100644 src/password.ui diff --git a/configure.in b/configure.in index af9a240..a4a2ec2 100644 --- a/configure.in +++ b/configure.in @@ -22,7 +22,7 @@ TST_DIR= DOC_DIR=doc m4_define(x_packagename, libpcscxx) -m4_define(x_major, 2) +m4_define(x_major, 3) m4_define(x_minor, 0) PACKAGENAME=x_packagename MAJOR=x_major @@ -94,7 +94,12 @@ AC_CHECK_PROG(have_dot, dot, yes, no) PKG_PROG_PKG_CONFIG # libraries -PKG_CHECK_MODULES([QT], [QtNetwork]) +PKG_CHECK_MODULES([QT_GUI], [QtCore QtGui QtWidgets], + [AC_DEFINE([HAVE_QTGUI], [1], [Use QtGui])], + [PKG_CHECK_MODULES([QT_GUI], [Qt5Core Qt5Gui Qt5Widgets])]) +PKG_CHECK_MODULES([QT_NETWORK], [QtNetwork], + [AC_DEFINE([HAVE_QTNETWORK], [1], [Use QtNetwork])], + [PKG_CHECK_MODULES([QT_NETWORK], [Qt5Network])]) AC_ARG_ENABLE(pedantic, [AS_HELP_STRING([--enable-pedantic], diff --git a/doc/examples/cardos-demo.cxx b/doc/examples/cardos-demo.cxx index 49fca02..77864ca 100644 --- a/doc/examples/cardos-demo.cxx +++ b/doc/examples/cardos-demo.cxx @@ -93,7 +93,7 @@ class Commands: public cardos::Commands { } void listReader() { - _readers = _c.scan(); + _readers = pcsc::Connection::scan(); std::cout<<"Found "<<_readers.size()<<" readers" <<(_readers.size()?":":".")<>num && num>=0 && num<_readers.size()) { - _reader = _c.reader(_readers[num]); + _reader = pcsc::Connection::reader(_readers[num]); std::cout<<"Active Reader: "<<_readers[num]< #include -pcsc::Connection c; pcsc::Connection::Strings readers; - void list() { - pcsc::Connection c; - pcsc::Connection::Strings readers(c.scan()); + pcsc::Connection::Strings readers(pcsc::Connection::scan()); std::cout<<"Found "<>pin; - } - if (pin.size()) cmd.logonTransport(pin); - cmd.phaseControl(); - cmd.createBinary(path, id, data); - cmd.phaseControl(); + // if (!pin.size()) { + // std::cout<<"PIN: "; + // std::cin>>pin; + // } + // if (pin.size()) cmd.logonTransport(pin); + // cmd.phaseControl(); + // cmd.createBinary(path, id, data); + // cmd.phaseControl(); return 0; } catch (std::exception& x) { std::cerr<<"ERROR: "< +#include +#if !defined(Q_MOC_OUTPUT_REVISION) +#error "The header file 'cardgui-model.hxx' doesn't include ." +#elif Q_MOC_OUTPUT_REVISION != 67 +#error "This file was generated using the moc from 5.0.2. It" +#error "cannot be used with the include files from this version of Qt." +#error "(The moc has changed too much.)" +#endif + +QT_BEGIN_MOC_NAMESPACE +struct qt_meta_stringdata_CardGuiModel_t { + QByteArrayData data[1]; + char stringdata[14]; +}; +#define QT_MOC_LITERAL(idx, ofs, len) \ + Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ + offsetof(qt_meta_stringdata_CardGuiModel_t, stringdata) + ofs \ + - idx * sizeof(QByteArrayData) \ + ) +static const qt_meta_stringdata_CardGuiModel_t qt_meta_stringdata_CardGuiModel = { + { +QT_MOC_LITERAL(0, 0, 12) + }, + "CardGuiModel\0" +}; +#undef QT_MOC_LITERAL + +static const uint qt_meta_data_CardGuiModel[] = { + + // content: + 7, // revision + 0, // classname + 0, 0, // classinfo + 0, 0, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + 0 // eod +}; + +void CardGuiModel::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + Q_UNUSED(_o); + Q_UNUSED(_id); + Q_UNUSED(_c); + Q_UNUSED(_a); +} + +const QMetaObject CardGuiModel::staticMetaObject = { + { &QAbstractItemModel::staticMetaObject, qt_meta_stringdata_CardGuiModel.data, + qt_meta_data_CardGuiModel, qt_static_metacall, 0, 0} +}; + + +const QMetaObject *CardGuiModel::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject; +} + +void *CardGuiModel::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_CardGuiModel.stringdata)) + return static_cast(const_cast< CardGuiModel*>(this)); + return QAbstractItemModel::qt_metacast(_clname); +} + +int CardGuiModel::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QAbstractItemModel::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + return _id; +} +QT_END_MOC_NAMESPACE diff --git a/doc/examples/pcsc-demo.cxx b/doc/examples/pcsc-demo.cxx index a75af7a..61e1cc6 100644 --- a/doc/examples/pcsc-demo.cxx +++ b/doc/examples/pcsc-demo.cxx @@ -3,15 +3,14 @@ #include int main(int, char const*const*const argv) try { - pcsc::Connection c; - pcsc::Connection::Strings reader(c.scan()); + pcsc::Connection::Strings reader(pcsc::Connection::scan()); std::cout<<"Library-Version: "<status()); + pcsc::Connection::Reader::Status s(pcsc::Connection::reader(*it)->status()); std::cout<<"Status = "<logicalName()); + case 1: return QString::fromStdString(o->name()); + case 3: return QString::fromStdString(o->contentInfo()); + case 2: if (o->content().size()) + return QString::fromStdString(crypto::readable(o->content())); + default: return QVariant(); + } + default: return QVariant(); + } + } + + Qt::ItemFlags flags(const QModelIndex &index) const { + if (!index.isValid()) return 0; + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } + + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const { + if (orientation!=Qt::Horizontal || role!=Qt::DisplayRole) + return QVariant(); + switch (section) { + case 0: return "Object"; + case 1: return "ID"; + case 3: return "Logical Content"; + case 2: return "Binary Content"; + default: return QVariant(); + } + } + + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const { + if (!hasIndex(row, column, parent)) return QModelIndex(); + const cardos::Object* parentItem(0); + if (!parent.isValid()) + parentItem = &_rootItem; + else + parentItem = static_cast(parent.internalPointer()); + if (rowsize()) + return + createIndex(row, column, &(*parentItem->children().at(row))); + return QModelIndex(); + } + + std::pair scan(const cardos::Object& o, + const cardos::Object* c) const { + int i(0); + for (cardos::Object::Children::const_iterator it(o.children().begin()); + it!=o.children().end(); ++it, ++i) { + if (it->get()==c) return std::make_pair(&o, i); + std::pair res(scan(**it, c)); + if (res.first) return res; + } + return std::make_pair((const cardos::Object*)0, 0); + } + + QModelIndex parent(const QModelIndex &index) const { + if (!index.isValid()) return QModelIndex(); + cardos::Object* childItem + (static_cast(index.internalPointer())); + if (childItem==&_rootItem) return QModelIndex(); + std::pair + parentItem(scan(_rootItem, childItem)); + if (!parentItem.first) return QModelIndex(); + return createIndex(parentItem.second, 0, + const_cast(parentItem.first)); + } + + int rowCount(const QModelIndex &parent = QModelIndex()) const { + if (parent.isValid() && parent.internalPointer()) + return static_cast(parent.internalPointer())->size(); + else + return _rootItem.size(); + } + + int columnCount(const QModelIndex &parent = QModelIndex()) const { + return 4; + } + + protected: + cardos::Dir _rootItem; +}; + +#endif diff --git a/src/cardgui.cxx b/src/cardgui.cxx new file mode 100644 index 0000000..010e231 --- /dev/null +++ b/src/cardgui.cxx @@ -0,0 +1,20 @@ +/*! @file + + @id $Id$ +*/ +// 1 2 3 4 5 6 7 8 +// 45678901234567890123456789012345678901234567890123456789012345678901234567890 + +#include + +#include +#include + +#include + +int main(int argc, char** argv) { + QApplication app(argc, argv); + CardGui win; + win.show(); + return app.exec(); +} diff --git a/src/cardgui.hxx b/src/cardgui.hxx new file mode 100644 index 0000000..3667f3b --- /dev/null +++ b/src/cardgui.hxx @@ -0,0 +1,108 @@ +/*! @file + + @id $Id$ +*/ +// 1 2 3 4 5 6 7 8 +// 45678901234567890123456789012345678901234567890123456789012345678901234567890 + +#ifndef CARDGUI_HXX +#define CARDGUI_HXX + +#include +#include +#include + +#include +#include + +class CardGui: public QMainWindow, protected Ui_CardGui { + + Q_OBJECT; + + public: + + CardGui(QWidget* p=0): + QMainWindow(p), _pwd(this) { + setupUi(this); + on__rescan_clicked(); + } + + void resizeEvent(QResizeEvent* event) { + QMainWindow::resizeEvent(event); + if (_tree->model()) + for (int i = 0; i < _tree->model()->columnCount(); ++i) + _tree->resizeColumnToContents(i); + } + + public Q_SLOTS: + + void on__rescan_clicked(bool=true) { + static bool inRescan(false); + if (inRescan) return; + inRescan = true; + try { + delete _tree->model(); + _tree->setModel(0); + _card->clear(); + pcsc::Connection::Strings readers(pcsc::Connection::scan()); + for (pcsc::Connection::Strings::iterator r(readers.begin()); + r!=readers.end(); ++r) + _card->addItem(QString::fromStdString(*r)); + } catch (...) { + } + inRescan = false; + } + + void on__card_currentIndexChanged(int) { + on__reload_clicked(); + } + + void on__reload_clicked(bool=true) { + try { + delete _tree->model(); + _tree->setModel(0); + cardos::Commands cmd(pcsc::Connection::reader + (_card->currentText().toStdString())); + _tree->setModel(new CardGuiModel(cmd, "3f00")); + } catch (...) { + on__rescan_clicked(); + } + } + + void on__actionRestartPCSCD_triggered() { + delete _tree->model(); + _tree->setModel(0); + if (_pwd.exec()) { + _p.start("sudo -S service pcscd restart"); + _p.write((_pwd.password()+"\n").toUtf8()); + _p.closeWriteChannel(); + if (!_p.waitForFinished()) + QMessageBox::warning(this, tr("Restarting PCSC Daemon failed"), + tr("

Restarting PCSC daemon" + " failed with message:

" + "\n
%1
") + .arg(QString::fromUtf8 + (_p.readAll()+"\n"+ + _p.readAllStandardOutput()+"\n"+ + _p.readAllStandardError()))); + else + QMessageBox::information(this, tr("Restarted PCSC Daemon"), + tr("

Restarted PCSC daemon" + " with message:

" + "\n
%1
") + .arg(QString::fromUtf8 + (_p.readAll()+"\n"+ + _p.readAllStandardOutput()+"\n"+ + _p.readAllStandardError()))); + } + on__reload_clicked(); + } + + protected: + + Password _pwd; + QProcess _p; + +}; + +#endif diff --git a/src/cardgui.ui b/src/cardgui.ui new file mode 100644 index 0000000..d786e5c --- /dev/null +++ b/src/cardgui.ui @@ -0,0 +1,103 @@ + + + CardGui + + + + 0 + 0 + 1349 + 878 + + + + MainWindow + + + + + + + 0 + + + + CardOS V4.4 + + + + + + true + + + QAbstractItemView::ScrollPerPixel + + + + + + + + + + + + + + 0 + 0 + + + + rescan for cards + + + + + + + + + + + 0 + 0 + + + + reload card info + + + + + + + + + + + 0 + 0 + 1349 + 23 + + + + + File + + + + + + + + + Restart PCSCD + + + + + + diff --git a/src/cardos.hxx b/src/cardos.hxx index f8a391c..6f458ea 100644 --- a/src/cardos.hxx +++ b/src/cardos.hxx @@ -124,6 +124,8 @@ namespace cardos { //@} //============================================================================ + /// @addtogroup cardoslib + //@{ class BerValue { public: @@ -262,6 +264,10 @@ namespace cardos { return _value; } + std::string hex() { + return crypto::hex(_value); + } + unsigned long ulong() { return crypto::ulongFromBinary(_value); } @@ -346,6 +352,7 @@ namespace cardos { }; + //============================================================================ /// Store a sequence of BerValue class BerValues: public std::vector { public: @@ -401,12 +408,7 @@ namespace cardos { } }; - //@} - //============================================================================ - /// @addtogroup cardoslib - //@{ - /// Implements CardOS V4.4 commands. /** Directly sends CardOS V4.4 commands to a smart card using APDUs. */ class Commands { @@ -422,12 +424,12 @@ namespace cardos { Commands() {} /// Initialize with given smart card reader. - Commands(mrw::Shared reader): + Commands(pcsc::shared_ptr::t reader): _reader(reader) { } /// Set smart card reader. - void reader(mrw::Shared reader) { + void reader(pcsc::shared_ptr::t reader) { _reader = reader; } @@ -941,10 +943,13 @@ namespace cardos { }; //! Read a record oriented file - std::string readRecord(unsigned char record = 0, + std::string readRecord(const std::string& path = std::string(), + unsigned char record = 0, unsigned char sfi = 0, ReadRecordMode mode = ABSOLUTE_RECORD) { CRYPTOLOG("log"); + pcsc::Connection::Reader::Transaction lock(_reader); + if (path.size()) select(path); return check(send(0x00, 0xB2, record, (sfi&0xF8)|mode)); } @@ -1529,9 +1534,215 @@ namespace cardos { protected: - mrw::Shared _reader; + pcsc::shared_ptr::t _reader; }; + + //============================================================================ + /// Represents a CardOS Filesystem Object + class Object { + public: + typedef pcsc::shared_ptr::t Child; + typedef std::vector Children; + public: + Object(const std::string& path): _path(path) {} + virtual ~Object() {} + virtual const std::string& path() const { + return _path; + } + virtual std::string name() const { + return _path; + } + virtual std::string logicalName() const { + switch (crypto::ulongFromBinary(crypto::hexToBin(name()))) { + case 0x3f00: return "Masterfile"; + case 0x5649: return "Version Info"; + case 0x2F02: return "Global Definition Object"; + case 0x5015: return "PKCS#15"; + case 0x5032: return "Token Info"; + case 0x5600: return "File System Version"; + case 0x4404: return "Certificate Definition"; + case 0x4304: return "Certificates"; + case 0x4401: return "Public Key Definition"; + case 0x5075: return "Public Keys"; + case 0x4408: return "Authentication Object Definition"; + case 0x5031: return "Object Definition"; + case 0x4407: return "Data Object Definition"; + case 0x4444: return "Data Objects"; + case 0x4400: return "Private Key Definition"; + case 0x5072: return "Private Keys"; + case 0x1fff: return "SigG"; + case 0xfe15: return "Transport Protection State"; + case 0xc100: return "Public Key"; + default: + switch (crypto::ulongFromBinary(crypto::hexToBin(name()))&0xff00) { + case 0x4b00: return "Private Key "+name().substr(2); + case 0x5500: return "Public Key "+name().substr(2); + default: return type(); + } + } + } + virtual const std::string& content() const { + const static std::string c; + return c; + } + virtual const std::string& contentInfo() const { + const static std::string c; + return c; + } + virtual std::string print(int indent=0, int=4) const { + return std::string(indent, ' ')+type()+": "+name(); + } + virtual bool isFile() const { + return false; + } + virtual bool isDir() const { + return false; + } + virtual bool hasChildren() const { + return _children.size(); + } + virtual Children::size_type size() const { + return _children.size(); + } + virtual const Children& children() const { + return _children; + } + virtual std::string type() const = 0; + protected: + std::string _path; + Children _children; + }; + + //============================================================================ + /// Represents a File on a Smart Card + class File: public Object { + public: + File(Commands& cmd, const std::string& path, const std::string& file): + Object(path), _file(file) { + CRYPTOLOG("new file "<print(indent+step, step); + return res; + } + std::string type() const { + return "Directory"; + } + protected: + void setup(Commands& cmd) { + _children.clear(); + BerValues i(cmd.directory(_path)); + CRYPTOLOG("Found Structure: "< Value: "<print()); + if (it->size()<2) continue; // empty dir + switch ((*it)[0].ulong()) { + case 0x38: + _children.push_back(Child(new Dir(cmd, _path+(*it)[1].hex()))); + break; + case 0x01: + _children.push_back(Child(new File(cmd, _path, (*it)[1].hex()))); + break; + case 0x05: + _children.push_back(Child(new Link(cmd, _path, (*it)[1].hex()))); + break; + case 0x06: + _children.push_back(Child(new Counter(cmd, _path, (*it)[1].hex()))); + break; + default: // unknown + throw runtime_error("unknown object: "+it->print()); + } + } + } + + }; + //@} } diff --git a/src/cryptaux.hxx b/src/cryptaux.hxx index 46d7be3..8048d5c 100644 --- a/src/cryptaux.hxx +++ b/src/cryptaux.hxx @@ -36,15 +36,19 @@ # else # include # define CRYPTOLOG(X) { \ - std::string file(__FILE__); \ - std::string line(CRYPTOLOG_QUOTE(__LINE__)); \ - std::string::size_type pos(file.rfind('/')); \ - if (pos!=std::string::npos) file=file.substr(pos+1); \ - std::string spc1(18>file.size()?std::string(18-file.size(), ' ') \ - :std::string()); \ - std::string spc2(4>line.size()?std::string(4-line.size(), ' ') \ - :std::string()); \ - std::clog<<"CRYPTO: "<__C_FILE__.size() \ + ?std::string(18-__C_FILE__.size(), ' ') \ + :std::string()); \ + std::string __LOC_SPC2__(4>__C_LINE__.size() \ + ?std::string(4-__C_LINE__.size(), ' ') \ + :std::string()); \ + std::clog<<"CRYPTO: "<<__LOC_SPC1__<<__C_FILE__ \ + <<':'<<__LOC_SPC2__<<__C_LINE__<<" -- "< # define CRYPTOLOG_VERBOSE(X) { \ - std::string file(__FILE__); \ - std::string line(CRYPTOLOG_QUOTE(__LINE__)); \ - std::string::size_type pos(file.rfind('/')); \ - if (pos!=std::string::npos) file=file.substr(pos+1); \ - std::string spc1(18>file.size()?std::string(18-file.size(), ' ') \ - :std::string()); \ - std::string spc2(4>line.size()?std::string(4-line.size(), ' ') \ - :std::string()); \ - std::clog<<"CRYPTO: "<__C_FILE__.size() \ + ?std::string(18-__C_FILE__.size(), ' ') \ + :std::string()); \ + std::string __LOC_SPC2__(4>__C_LINE__.size() \ + ?std::string(4-__C_LINE__.size(), ' ') \ + :std::string()); \ + std::clog<<"CRYPTO: "<<__LOC_SPC1__<<__C_FILE__<<':' \ + <<__LOC_SPC2__<<__C_LINE__<<" -- "<>=8; } return res; @@ -177,9 +185,8 @@ namespace crypto { /// convert integer from binary of given size inline unsigned long ulongFromBinary(const std::string& data) { unsigned long res(0); - for (std::string::const_reverse_iterator it(data.rbegin()); - it!=data.rend(); ++it) - (res<<=8)+=(unsigned)*it; + for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it) + (res<<=8)+=(unsigned long)(unsigned char)*it; return res; } diff --git a/src/makefile.am b/src/makefile.am index e3ba8ca..68ffc08 100644 --- a/src/makefile.am +++ b/src/makefile.am @@ -10,6 +10,8 @@ include_HEADERS = pcsc.hxx cryptoki.hxx openssl.hxx cryptaux.hxx \ openssl-engine.hxx suisseid.hxx cardos.hxx #certimport.hxx +noinst_HEADERS = cardgui.hxx cardgui-model.hxx + if !MINGW32 if MAC AM_CPPFLAGS += -I/opt/local/include -I/Library/OpenSC/include @@ -29,15 +31,15 @@ pkgconfig2_DATA = $(pkgconfig_DATA) EXTRA_DIST = $(pkgconfig_DATA).in ${top_srcdir}/src/*.doc +bin_PROGRAMS = cardgui + lib_LTLIBRARIES = libpcscxx.la libpcscxx_la_SOURCES = cryptoki.cxx cryptoki.hxx pcsc.cxx version.cxx \ openssl-engine.cxx #moc_certimport.cxx libpcscxx_la_LDFLAGS = -version-info ${LIB_VERSION} -#libpcscxx_la_CXXFLAGS = ${QT_CFLAGS} libpcscxx_la_LIBADD = -lssl -lcrypto -# ${QT_LIBS} if MINGW32 libpcscxx_la_LIBADD += -lgdi32 -lws2_32 else @@ -47,15 +49,25 @@ libpcscxx_la_LIBADD += -lpcsclite endif endif +cardgui_SOURCES = cardgui.cxx +nodist_cardgui_SOURCES = cardgui_ui.hxx password_ui.hxx \ + moc_cardgui.cxx moc_password.cxx moc_cardgui-model.cxx +BUILT_SOURCES = ${nodist_cardgui_SOURCES} +cardgui_CXXFLAGS = ${QT_GUI_CFLAGS} -fPIC +cardgui_LDADD = ${QT_GUI_LIBS} libpcscxx.la ${libpcscxx_la_LIBADD} + noinst_PROGRAMS = versiontest versiontest_SOURCES = versiontest.cxx +%_ui.hxx: %.ui + uic -o $@ $< + moc_%.cxx: %.hxx moc -o $@ $< clean-local: -rm -r ${QMAKE_TARGET}.app -CLEANFILES = ${MOC_FILES} +CLEANFILES = ${MOC_FILES} ${BUILT_SOURCES} DISTCLEANFILES = $(pkgconfig_DATA) MAINTAINERCLEANFILES = makefile.in diff --git a/src/openssl-engine.cxx b/src/openssl-engine.cxx index d5ea2c1..32762ad 100644 --- a/src/openssl-engine.cxx +++ b/src/openssl-engine.cxx @@ -5,6 +5,8 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) + This product includes cryptographic software written by + Eric Young (eay@cryptsoft.com) */ // 1 2 3 4 5 6 7 8 // 45678901234567890123456789012345678901234567890123456789012345678901234567890 diff --git a/src/openssl-engine.hxx b/src/openssl-engine.hxx index 1af1410..8919829 100644 --- a/src/openssl-engine.hxx +++ b/src/openssl-engine.hxx @@ -5,6 +5,8 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) + This product includes cryptographic software written by + Eric Young (eay@cryptsoft.com) */ // 1 2 3 4 5 6 7 8 // 45678901234567890123456789012345678901234567890123456789012345678901234567890 diff --git a/src/openssl.hxx b/src/openssl.hxx index e45569a..557d318 100644 --- a/src/openssl.hxx +++ b/src/openssl.hxx @@ -5,6 +5,8 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) + This product includes cryptographic software written by + Eric Young (eay@cryptsoft.com) */ // 1 2 3 4 5 6 7 8 // 45678901234567890123456789012345678901234567890123456789012345678901234567890 diff --git a/src/password.hxx b/src/password.hxx new file mode 100644 index 0000000..b9ce238 --- /dev/null +++ b/src/password.hxx @@ -0,0 +1,30 @@ +/*! @file + + @id $Id$ +*/ +// 1 2 3 4 5 6 7 8 +// 45678901234567890123456789012345678901234567890123456789012345678901234567890 + +#ifndef PASSWORD_HXX +#define PASSWORD_HXX + +#include + +class Password: public QDialog, protected Ui_Password { + + Q_OBJECT; + + public: + + Password(QWidget* p=0): + QDialog(p) { + setupUi(this); + } + + QString password() { + return _pwd->text(); + } + +}; + +#endif diff --git a/src/password.ui b/src/password.ui new file mode 100644 index 0000000..a264b6c --- /dev/null +++ b/src/password.ui @@ -0,0 +1,101 @@ + + + Password + + + + 0 + 0 + 360 + 152 + + + + Dialog + + + + + + + 0 + 0 + + + + Your password is required to restart PCSC daemon. Please anter your user password and make sure, you are allowed to sudo on this host. + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + + + Password: + + + + + + + QLineEdit::Password + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Password + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Password + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/pcsc.hxx b/src/pcsc.hxx index 3ecb042..5a75d12 100644 --- a/src/pcsc.hxx +++ b/src/pcsc.hxx @@ -12,7 +12,6 @@ #include -#include #include #ifdef WIN32 @@ -205,7 +204,8 @@ namespace pcsc { /*! @note Please note that the Reader is required in the destructor und must therefore live longer than the Transaction instance. */ - Transaction(mrw::Shared r): _reader(r), _running(true) { + Transaction(shared_ptr::t r): + _reader(r), _running(true) { CRYPTOLOG("log"); _reader->beginTransaction(); } @@ -222,7 +222,7 @@ namespace pcsc { _running = false; } private: - mrw::Shared _reader; + shared_ptr::t _reader; bool _running; }; @@ -424,7 +424,7 @@ namespace pcsc { friend class Connection; //! Establishes a connection to the given named cardreader - Reader(const std::string& nm, const Connection& c, + Reader(const std::string& nm, shared_ptr::t c, DWORD mode=SCARD_SHARE_SHARED, DWORD protocol=SCARD_PROTOCOL_T1): name(nm), _connection(c) { @@ -441,7 +441,7 @@ namespace pcsc { //...........................................................variables private: - mrw::Shared _connection; + shared_ptr::t _connection; SCARDHANDLE _id; DWORD _state; DWORD _protocol; @@ -461,160 +461,108 @@ namespace pcsc { //................................................................methods public: - //! Opens a connection (establishes a smartcard context) - /*! The errorhandling is defined with the @c exceptions flag: - - Using exceptions: - @code - try { - pcsc::Connection c; // standard with exceptions - pcsc::Connection::Strings r(c.scan()); - } catch (std::exception& x) { - std::cout<<"Error with message: "<id(), - groups.size()?strconv(grp).data():0, 0, - &num), - "smartcard get size of readers of groups "+grp)) + if (!c.check(SCardListReaders(c._id, + groups.size()?strconv(grp).data():0, 0, + &num), + "smartcard get size of readers of groups "+grp)) return res; CRYPTOLOG("size of readers: "< nm(new char_t[num]); - if (!check(SCardListReaders(_connectionlifetime->id(), - groups.size()?strconv(grp).data():0, - nm.get(), &num), - "smartcard list reader names of groups "+grp)) + if (!c.check(SCardListReaders(c._id, + groups.size()?strconv(grp).data():0, + nm.get(), &num), + "smartcard list reader names of groups "+grp)) return res; CRYPTOLOG("got all readers, size is "< reader(const std::string& name) { - return _connectionlifetime->reader(name, this); - } - - // //! Close connection of a named reader. - // /*! If you access the same reader through raeder() later, the - // connection will be reestablished. */ - // void close(const std::string& s) { - - // } - - /// Reset and reestablish the connection. - /** @note You must remove all readers that have been returned by - @ref reader(), if you have assigned them to a variable - and stored them. Otherwise the connections will remain - open and next access should probably fail. - @begincode - { - mrw::Shared r(c.reader(name)); - // use r - c.reset(); // now r is invalid - // either reassign r: - r = c.reader(name); - // or simply reset it - r.reset(); - } - // or clenaup by leaving the context of r - @endcode */ - void reset() { - _connectionlifetime->reset(); - } - //! Find all readers with a given ATR. /*! @param atr full or partial ATR to match to the reader's ATR @returns list of readers that contain @c atr in their ATR */ - Strings getReadersWithAtr(const std::string& atr) { + static Strings getReadersWithAtr(const std::string& atr, + Scope s=USER, bool exceptions=true) { + Connection c(s, exceptions); Strings res; - pcsc::Connection::Strings readers(scan()); + pcsc::Connection::Strings readers(c.scan()); for (pcsc::Connection::Strings::const_iterator it(readers.begin()); it!=readers.end(); ++it) - if (crypto::hex(reader(*it)->status().atr).find(atr)!=string::npos) + if (crypto::hex(c.reader(*it)->status().atr).find(atr)!=string::npos) res.push_back(*it); return res; } - //! @c false if last operation was not successful - operator bool() const { - return *_connectionlifetime; + //! Get a reader, open a connection if not already open. + /*! First use scan() to get a list of readers, then open a + connection to the reader, then access it. */ + static shared_ptr::t reader(const std::string& name, + Scope s=USER, bool exceptions=true) { + CRYPTOLOG("get reader: "<::t + (new Reader(name, + shared_ptr::t + (new Connection(s, exceptions)))); } - + //................................................................methods private: - mrw::Shared newreader(const std::string& name) { - return new Reader(name, *this); - } - - //! Sets state and throws an exception if neccessary. - /*! @throw access_error if it is instanciated for exceptions and - an error occured in the last command. */ - bool check(long state, const std::string& context="") { - _connectionlifetime->state(state); - return check(context); - } + //! Opens a connection (establishes a smartcard context) + /*! The errorhandling is defined with the @c exceptions flag: - //! Throws an exception if neccessary. - /*! @throw access_error if it is instanciated for exceptions and - an error occured in the last command. */ - bool check(const std::string& context="") { - return _connectionlifetime->check(context); + Using exceptions: + @code + try { + pcsc::Connection c; // standard with exceptions + pcsc::Connection::Strings r(c.scan()); + } catch (std::exception& x) { + std::cout<<"Error with message: "<size()+1) @@ -623,7 +571,7 @@ namespace pcsc { } //! Joins a vector of strings into a buffer with 0 separators. - std::string join(const Strings& in) { + static std::string join(const Strings& in) { std::string res; if (in.size()) { for (Strings::const_iterator it(in.begin()); @@ -634,498 +582,433 @@ namespace pcsc { return res; } - //! Connection id - SCARDCONTEXT id() { - return _connectionlifetime->id(); + operator bool() const { +#ifdef WIN32 + return (_state>>30&3)==0; +#else + return _state==SCARD_S_SUCCESS; +#endif } - //! @c true if exceptions are thrown - bool exc() { - return _connectionlifetime->exc(); + //! Throws an exception if neccessary. + /*! @throw access_error if it is instanciated for exceptions and + an error occured in the last command. */ + bool check(long state, const std::string& context="") { + _state = state; + check(context); } - //..............................................................variables - private: - - class ConnectionLifetime { - public: - //! opens connection that is closed on destruction - ConnectionLifetime(Scope s, bool exc): - _exc(exc), _id(0), _s(s), - _state(SCardEstablishContext(s, 0, 0, &_id)) { - CRYPTOLOG("Open Connection"); - check("establish smartcard context"); - } - //! Closes the connection (releases the smartcard context) - ~ConnectionLifetime() { - CRYPTOLOG("Close Connection"); - _state = SCardReleaseContext(_id); - if (!std::uncaught_exception()) check("smartcard release context"); - } - //! @c false if last operation was not successful - operator bool() const { -#ifdef WIN32 - return (_state>>30&3)==0; -#else - return _state==SCARD_S_SUCCESS; -#endif - } - //! Throws an exception if neccessary. - /*! @throw access_error if it is instanciated for exceptions and + //! Throws an exception if neccessary. + /*! @throw access_error if it is instanciated for exceptions and an error occured in the last command. */ - bool check(const std::string& context="") { - if (_exc&&!*this) { - if (context.size()) { + bool check(const std::string& context="") { + if (_exc&&!*this) { + if (context.size()) { #ifdef SCARD_W_WRONG_CHV - if (_state==SCARD_W_WRONG_CHV) { - throw wrong_pin(context+": "+error()); - } else { + if (_state==SCARD_W_WRONG_CHV) { + throw wrong_pin(context+": "+error()); + } else { #endif - throw access_error(context+": "+error()); + throw access_error(context+": "+error()); #ifdef SCARD_W_WRONG_CHV - } + } #endif - } else { + } else { #ifdef SCARD_W_WRONG_CHV - if (_state==SCARD_W_WRONG_CHV) { - throw wrong_pin(error()); - } else { + if (_state==SCARD_W_WRONG_CHV) { + throw wrong_pin(error()); + } else { #endif - throw access_error(error()); + throw access_error(error()); #ifdef SCARD_W_WRONG_CHV - } -#endif - } } - return *this; +#endif } - - //! Get the describing text of the last error - std::string error() const { - std::stringstream ss; - switch (_state) { + } + return *this; + } + + //! Get the describing text of the last error + std::string error() const { + std::stringstream ss; + switch (_state) { #ifdef SCARD_E_CANCELLED - case SCARD_E_CANCELLED: - ss<<"The action was canceled by an SCardCancel request."; - break; + case SCARD_E_CANCELLED: + ss<<"The action was canceled by an SCardCancel request."; + break; #endif #ifdef SCARD_E_CANT_DISPOSE - case SCARD_E_CANT_DISPOSE: - ss<<"The system could not dispose of the media in the requested" - <<" manner."; - break; + case SCARD_E_CANT_DISPOSE: + ss<<"The system could not dispose of the media in the requested" + <<" manner."; + break; #endif #ifdef SCARD_E_CARD_UNSUPPORTED - case SCARD_E_CARD_UNSUPPORTED: - ss<<"The smart card does not meet minimal requirements for" - <<" support."; - break; + case SCARD_E_CARD_UNSUPPORTED: + ss<<"The smart card does not meet minimal requirements for" + <<" support."; + break; #endif #ifdef SCARD_E_DUPLICATE_READER - case SCARD_E_DUPLICATE_READER: - ss<<"The reader driver did not produce a unique reader name."; - break; + case SCARD_E_DUPLICATE_READER: + ss<<"The reader driver did not produce a unique reader name."; + break; #endif #ifdef SCARD_E_INSUFFICIENT_BUFFER - case SCARD_E_INSUFFICIENT_BUFFER: - ss<<"The data buffer for returned data is too small for the" - <<" returned data."; - break; + case SCARD_E_INSUFFICIENT_BUFFER: + ss<<"The data buffer for returned data is too small for the" + <<" returned data."; + break; #endif #ifdef SCARD_E_INVALID_ATR - case SCARD_E_INVALID_ATR: - ss<<"An ATR string obtained from the registry is not a valid" - <<" ATR string."; - break; + case SCARD_E_INVALID_ATR: + ss<<"An ATR string obtained from the registry is not a valid" + <<" ATR string."; + break; #endif #ifdef SCARD_E_INVALID_HANDLE - case SCARD_E_INVALID_HANDLE: - ss<<"The supplied handle was not valid."; - break; + case SCARD_E_INVALID_HANDLE: + ss<<"The supplied handle was not valid."; + break; #endif #ifdef SCARD_E_INVALID_PARAMETER - case SCARD_E_INVALID_PARAMETER: - ss<<"One or more of the supplied parameters could not be properly" - <<" interpreted."; - break; + case SCARD_E_INVALID_PARAMETER: + ss<<"One or more of the supplied parameters could not be properly" + <<" interpreted."; + break; #endif #ifdef SCARD_E_INVALID_TARGET - case SCARD_E_INVALID_TARGET: - ss<<"Registry startup information is missing or not valid."; - break; + case SCARD_E_INVALID_TARGET: + ss<<"Registry startup information is missing or not valid."; + break; #endif #ifdef SCARD_E_INVALID_VALUE - case SCARD_E_INVALID_VALUE: - ss<<"One or more of the supplied parameters values could not" - <<" be properly interpreted."; - break; + case SCARD_E_INVALID_VALUE: + ss<<"One or more of the supplied parameters values could not" + <<" be properly interpreted."; + break; #endif #ifdef SCARD_E_NOT_READY - case SCARD_E_NOT_READY: - ss<<"The reader or smart card is not ready to accept commands."; - break; + case SCARD_E_NOT_READY: + ss<<"The reader or smart card is not ready to accept commands."; + break; #endif #ifdef SCARD_E_NOT_TRANSACTED - case SCARD_E_NOT_TRANSACTED: - ss<<"An attempt was made to end a nonexistent transaction."; - break; + case SCARD_E_NOT_TRANSACTED: + ss<<"An attempt was made to end a nonexistent transaction."; + break; #endif #ifdef SCARD_E_NO_MEMORY - case SCARD_E_NO_MEMORY: - ss<<"Not enough memory available to complete this command."; - break; + case SCARD_E_NO_MEMORY: + ss<<"Not enough memory available to complete this command."; + break; #endif #ifdef SCARD_E_NO_SERVICE - case SCARD_E_NO_SERVICE: - ss<<"The smart card resource manager is not running."; - break; + case SCARD_E_NO_SERVICE: + ss<<"The smart card resource manager is not running."; + break; #endif #ifdef SCARD_E_NO_SMARTCARD - case SCARD_E_NO_SMARTCARD: - ss<<"The operation requires a smart card, but no smart card" - <<" is currently in the device."; - break; + case SCARD_E_NO_SMARTCARD: + ss<<"The operation requires a smart card, but no smart card" + <<" is currently in the device."; + break; #endif #ifdef SCARD_E_PCI_TOO_SMALL - case SCARD_E_PCI_TOO_SMALL: - ss<<"The PCI receive buffer was too small."; - break; + case SCARD_E_PCI_TOO_SMALL: + ss<<"The PCI receive buffer was too small."; + break; #endif #ifdef SCARD_E_PROTO_MISMATCH - case SCARD_E_PROTO_MISMATCH: - ss<<"The requested protocols are incompatible with the protocol" - <<" currently in use with the smart card."; - break; + case SCARD_E_PROTO_MISMATCH: + ss<<"The requested protocols are incompatible with the protocol" + <<" currently in use with the smart card."; + break; #endif #ifdef SCARD_E_READER_UNAVAILABLE - case SCARD_E_READER_UNAVAILABLE: - ss<<"The specified reader is not currently available for use."; - break; + case SCARD_E_READER_UNAVAILABLE: + ss<<"The specified reader is not currently available for use."; + break; #endif #ifdef SCARD_E_READER_UNSUPPORTED - case SCARD_E_READER_UNSUPPORTED: - ss<<"The reader driver does not meet minimal requirements for" - <<" support."; - break; + case SCARD_E_READER_UNSUPPORTED: + ss<<"The reader driver does not meet minimal requirements for" + <<" support."; + break; #endif #ifdef SCARD_E_SERVICE_STOPPED - case SCARD_E_SERVICE_STOPPED: - ss<<"The smart card resource manager has shut down."; - break; + case SCARD_E_SERVICE_STOPPED: + ss<<"The smart card resource manager has shut down."; + break; #endif #ifdef SCARD_E_SHARING_VIOLATION - case SCARD_E_SHARING_VIOLATION: - ss<<"The smart card cannot be accessed because of other" - <<" outstanding connections."; - break; + case SCARD_E_SHARING_VIOLATION: + ss<<"The smart card cannot be accessed because of other" + <<" outstanding connections."; + break; #endif #ifdef SCARD_E_SYSTEM_CANCELLED - case SCARD_E_SYSTEM_CANCELLED: - ss<<"The action was cancelled by the system, presumably to log" - <<" off or shut down."; - break; + case SCARD_E_SYSTEM_CANCELLED: + ss<<"The action was cancelled by the system, presumably to log" + <<" off or shut down."; + break; #endif #ifdef SCARD_E_TIMEOUT - case SCARD_E_TIMEOUT: - ss<<"The user-specified time-out value has expired."; - break; + case SCARD_E_TIMEOUT: + ss<<"The user-specified time-out value has expired."; + break; #endif #ifdef SCARD_E_UNKNOWN_CARD - case SCARD_E_UNKNOWN_CARD: - ss<<"The specified smart card name is not recognized."; - break; + case SCARD_E_UNKNOWN_CARD: + ss<<"The specified smart card name is not recognized."; + break; #endif #ifdef SCARD_E_UNKNOWN_READER - case SCARD_E_UNKNOWN_READER: - ss<<"The specified reader name is not recognized."; - break; + case SCARD_E_UNKNOWN_READER: + ss<<"The specified reader name is not recognized."; + break; #endif #ifdef SCARD_F_COMM_ERROR - case SCARD_F_COMM_ERROR: - ss<<"An internal communications error has been detected."; - break; + case SCARD_F_COMM_ERROR: + ss<<"An internal communications error has been detected."; + break; #endif #ifdef SCARD_F_INTERNAL_ERROR - case SCARD_F_INTERNAL_ERROR: - ss<<"An internal consistency check failed."; - break; + case SCARD_F_INTERNAL_ERROR: + ss<<"An internal consistency check failed."; + break; #endif #ifdef SCARD_F_UNKNOWN_ERROR - case SCARD_F_UNKNOWN_ERROR: - ss<<"An internal error has been detected, but the source is" - <<" unknown."; - break; + case SCARD_F_UNKNOWN_ERROR: + ss<<"An internal error has been detected, but the source is" + <<" unknown."; + break; #endif #ifdef SCARD_F_WAITED_TOO_LONG - case SCARD_F_WAITED_TOO_LONG: - ss<<"An internal consistency timer has expired."; - break; + case SCARD_F_WAITED_TOO_LONG: + ss<<"An internal consistency timer has expired."; + break; #endif #ifdef SCARD_S_SUCCESS - case SCARD_S_SUCCESS: - ss<<"No error was encountered."; - break; + case SCARD_S_SUCCESS: + ss<<"No error was encountered."; + break; #endif #ifdef SCARD_W_REMOVED_CARD - case SCARD_W_REMOVED_CARD: - ss<<"The smart card has been removed, so that further" - <<" communication is not possible."; - break; + case SCARD_W_REMOVED_CARD: + ss<<"The smart card has been removed, so that further" + <<" communication is not possible."; + break; #endif #ifdef SCARD_W_RESET_CARD - case SCARD_W_RESET_CARD: - ss<<"The smart card was reset."; - break; + case SCARD_W_RESET_CARD: + ss<<"The smart card was reset."; + break; #endif #ifdef SCARD_W_UNPOWERED_CARD - case SCARD_W_UNPOWERED_CARD: - ss<<"Power has been removed from the smart card, so that" - <<" further communication is not possible."; - break; + case SCARD_W_UNPOWERED_CARD: + ss<<"Power has been removed from the smart card, so that" + <<" further communication is not possible."; + break; #endif #ifdef SCARD_W_UNRESPONSIVE_CARD - case SCARD_W_UNRESPONSIVE_CARD: - ss<<"The smart card is not responding to a reset."; - break; + case SCARD_W_UNRESPONSIVE_CARD: + ss<<"The smart card is not responding to a reset."; + break; #endif #ifdef SCARD_W_UNSUPPORTED_CARD - case SCARD_W_UNSUPPORTED_CARD: - ss<<"The reader cannot communicate with the smart card," - <<" due to ATR configuration conflicts."; - break; + case SCARD_W_UNSUPPORTED_CARD: + ss<<"The reader cannot communicate with the smart card," + <<" due to ATR configuration conflicts."; + break; #endif #ifdef SCARD_E_NO_READERS_AVAILABLE - case SCARD_E_NO_READERS_AVAILABLE: - ss<<"No smart card reader is available."; - break; + case SCARD_E_NO_READERS_AVAILABLE: + ss<<"No smart card reader is available."; + break; #endif #ifdef ERROR_BROKEN_PIPE - 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 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; #endif #ifdef SCARD_E_BAD_SEEK - case SCARD_E_BAD_SEEK: - ss<<"There was an error trying to set the smart card file" - <<" object pointer."; - break; + case SCARD_E_BAD_SEEK: + ss<<"There was an error trying to set the smart card file" + <<" object pointer."; + break; #endif #ifdef SCARD_E_CERTIFICATE_UNAVAILABLE - case SCARD_E_CERTIFICATE_UNAVAILABLE: - ss<<"The requested certificate could not be obtained."; - break; + case SCARD_E_CERTIFICATE_UNAVAILABLE: + ss<<"The requested certificate could not be obtained."; + break; #endif #ifdef SCARD_E_COMM_DATA_LOST - case SCARD_E_COMM_DATA_LOST: - ss<<"A communications error with the smart card has been detected."; - break; + case SCARD_E_COMM_DATA_LOST: + ss<<"A communications error with the smart card has been detected."; + break; #endif #ifdef SCARD_E_DIR_NOT_FOUND - case SCARD_E_DIR_NOT_FOUND: - ss<<"The specified directory does not exist in the smart card."; - break; + case SCARD_E_DIR_NOT_FOUND: + ss<<"The specified directory does not exist in the smart card."; + break; #endif #ifdef SCARD_E_FILE_NOT_FOUND - case SCARD_E_FILE_NOT_FOUND: - ss<<"The specified file 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; #endif #ifdef SCARD_E_ICC_CREATEORDER - case SCARD_E_ICC_CREATEORDER: - ss<<"The requested order of object creation is not supported."; - break; + case SCARD_E_ICC_CREATEORDER: + ss<<"The requested order of object creation is not supported."; + break; #endif #ifdef SCARD_E_ICC_INSTALLATION - case SCARD_E_ICC_INSTALLATION: - ss<<"No primary provider can be found for the smart card."; - break; + case SCARD_E_ICC_INSTALLATION: + ss<<"No primary provider can be found for the smart card."; + break; #endif #ifdef SCARD_E_INVALID_CHV - case SCARD_E_INVALID_CHV: - ss<<"The supplied PIN is incorrect."; - break; + case SCARD_E_INVALID_CHV: + ss<<"The supplied PIN is incorrect."; + break; #endif #ifdef SCARD_E_NO_ACCESS - case SCARD_E_NO_ACCESS: - ss<<"Access is denied to this file."; - break; + case SCARD_E_NO_ACCESS: + ss<<"Access is denied to this file."; + break; #endif #ifdef SCARD_E_NO_DIR - case SCARD_E_NO_DIR: - ss<<"The supplied path does not represent a smart card directory."; - break; + case SCARD_E_NO_DIR: + ss<<"The supplied path does not represent a smart card directory."; + break; #endif #ifdef SCARD_E_NO_FILE - case SCARD_E_NO_FILE: - ss<<"The supplied path does not represent a smart card file."; - break; + case SCARD_E_NO_FILE: + ss<<"The supplied path does not represent a smart card file."; + break; #endif #ifdef SCARD_E_NO_KEY_CONTAINER - case SCARD_E_NO_KEY_CONTAINER: - ss<<"The requested key container does not exist on the smart card."; - break; + case SCARD_E_NO_KEY_CONTAINER: + ss<<"The requested key container does not exist on the smart card."; + break; #endif #ifdef SCARD_E_NO_SUCH_CERTIFICATE - case SCARD_E_NO_SUCH_CERTIFICATE: - ss<<"The requested certificate does not exist."; - break; + case SCARD_E_NO_SUCH_CERTIFICATE: + ss<<"The requested certificate does not exist."; + break; #endif #ifdef SCARD_E_SERVER_TOO_BUSY - case SCARD_E_SERVER_TOO_BUSY: - ss<<"The Smart card resource manager is too busy to complete this" - <<" operation."; - break; + case SCARD_E_SERVER_TOO_BUSY: + ss<<"The Smart card resource manager is too busy to complete this" + <<" operation."; + break; #endif #ifdef SCARD_E_UNSUPPORTED_FEATURE - case SCARD_E_UNSUPPORTED_FEATURE: - ss<<"This smart card does not support the requested feature."; - break; + case SCARD_E_UNSUPPORTED_FEATURE: + ss<<"This smart card does not support the requested feature."; + break; #else #ifdef SCARD_E_UNEXPECTED - case SCARD_E_UNEXPECTED: - ss<<"An unexpected card error has occurred."; - break; + case SCARD_E_UNEXPECTED: + ss<<"An unexpected card error has occurred."; + break; #endif #endif #ifdef SCARD_E_UNKNOWN_RES_MNG - case SCARD_E_UNKNOWN_RES_MNG: - ss<<"An unrecognized error code was returned from a layered" - <<" component."; - break; + case SCARD_E_UNKNOWN_RES_MNG: + ss<<"An unrecognized error code was returned from a layered" + <<" component."; + break; #endif #ifdef SCARD_E_WRITE_TOO_MANY - case SCARD_E_WRITE_TOO_MANY: - ss<<"The smartcard does not have enough memory to store the" - <<" information."; - break; + case SCARD_E_WRITE_TOO_MANY: + ss<<"The smartcard does not have enough memory to store the" + <<" information."; + break; #endif #ifdef SCARD_P_SHUTDOWN - case SCARD_P_SHUTDOWN: - ss<<"The operation has been aborted to allow the server application" - <<" to exit."; - break; + case SCARD_P_SHUTDOWN: + ss<<"The operation has been aborted to allow the server application" + <<" to exit."; + break; #endif #ifdef SCARD_W_CANCELLED_BY_USER - case SCARD_W_CANCELLED_BY_USER: - ss<<"The action was cancelled by the user."; - break; + case SCARD_W_CANCELLED_BY_USER: + ss<<"The action was cancelled by the user."; + break; #endif #ifdef SCARD_W_CARD_NOT_AUTHENTICATED - case SCARD_W_CARD_NOT_AUTHENTICATED: - ss<<"No PIN was presented to the smart card."; - break; + case SCARD_W_CARD_NOT_AUTHENTICATED: + ss<<"No PIN was presented to the smart card."; + break; #endif #ifdef SCARD_W_CHV_BLOCKED - 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_CHV_BLOCKED: + ss<<"The card cannot be accessed because the maximum number" + <<" of PIN entry attempts has been reached."; + break; #endif #ifdef SCARD_W_EOF - case SCARD_W_EOF: - ss<<"The end of the smart card file has been reached."; - break; + case SCARD_W_EOF: + ss<<"The end of the smart card file has been reached."; + break; #endif #ifdef SCARD_W_SECURITY_VIOLATION - case SCARD_W_SECURITY_VIOLATION: - ss<<"Access was denied because of a security violation."; - break; + case SCARD_W_SECURITY_VIOLATION: + ss<<"Access was denied because of a security violation."; + break; #endif #ifdef SCARD_W_WRONG_CHV - case SCARD_W_WRONG_CHV: - ss<<"The card cannot be accessed because the wrong PIN was" - <<" presented."; - break; -#endif - default: - ss<<"unknown PCSC state=0x" - <>30) { - case 0: ss<<" means SUCCESS"; break; - case 1: ss<<" means INFORMATIONAL"; break; - case 2: ss<<" means WARNING"; break; - case 3: ss<<" means ERROR"; break; - default: ss<<" illegal value"; - } - ss<<" C="<<(_state>>29&1); - ss<<" R="<<(_state>>28&1); - ss<<" Facility=0x"<>16&0xfff); - ss<<" Code=0x"<>30) { + case 0: ss<<" means SUCCESS"; break; + case 1: ss<<" means INFORMATIONAL"; break; + case 2: ss<<" means WARNING"; break; + case 3: ss<<" means ERROR"; break; + default: ss<<" illegal value"; } - return ss.str(); - } - //! set state - void state(long s) { - _state = s; - } - //! @returns state - long state() { - return _state; - } - //! @returns connection id - SCARDCONTEXT id() { - return _id; - } - bool exc() { - return _exc; - } - - //! Get a reader, open a connection if not already open. - /*! First use scan() to get a list of readers, then open a - connection to the reader, then access it. */ - mrw::Shared reader(const std::string& name, Connection* c) { - CRYPTOLOG("get reader: "<newreader(name))); - return _readers.find(name)->second; - } - - /// Cleans up the readers, resets the context. - void reset() { - _readers.clear(); - _state = SCardReleaseContext(_id); - check("smartcard release context"); - _state = SCardEstablishContext(_s, 0, 0, &_id); - check("establish smartcard context"); - } - - private: - - bool _exc; - SCARDCONTEXT _id; - Scope _s; - long _state; - - //! Readers are closed when the last shared object is destructed - std::map > _readers; - }; - - //! Connection is closed when the last shared object is destructed - /*! Handling the connection lifetime in a separate shared object - allows to copy connections and still make sure, that the - lifetime of the connection is as long as all copied opbjects - live. */ - static ConnectionLifetime*& - connectionlifetime(Scope s=USER, bool exc=true) { - static ConnectionLifetime* instance(0); - if (instance==0) { - CRYPTOLOG("New Connection"); - instance = new ConnectionLifetime(s, exc); + ss<<" C="<<(_state>>29&1); + ss<<" R="<<(_state>>28&1); + ss<<" Facility=0x"<>16&0xfff); + ss<<" Code=0x"< - (new Post(_pcsc.reader(*reader), _cryptoki))); + (new Post(pcsc::Connection::reader(*reader), + _cryptoki))); } return res; } private: - pcsc::Connection _pcsc; cryptoki::Library _cryptoki; };