/*! @file @id $Id$ */ // 1 2 3 4 5 6 7 8 // 45678901234567890123456789012345678901234567890123456789012345678901234567890 #ifndef __SUISSEID_HXX__ #define __SUISSEID_HXX__ #include #include #include #include #include /*! @defgroup gsuisseid C+ Wrapper to access SuisseID smart cards This library allows access to the Swiss digital identity cards (SuisseID). You need to include @ref suisseid.hxx, then start with class @ref suisseid::Scanner to scan for a list of SuisseID cards on the system. @see http://www.suisseid.ch @see http://postsuisseid.ch */ //@{ namespace suisseid { //! Represents a SuisseID Card /*! This is the parent class for special classes for the respecive SuisseID providers. */ class Card: public cardos::Commands { public: enum Status { TRANSPORT }; public: Card(mrw::Shared reader, mrw::Shared slot): cardos::Commands(reader), _slot(slot) { } virtual ~Card() {} virtual unsigned int minimalPinLength() = 0; virtual unsigned int maximalPinLength() = 0; //! Name of the token/slot const std::string& name() { return _reader->name; } /// Version of the card virtual std::string version() { return ""; } private: mrw::Shared _slot; }; //! Instance of a Post SuisseID smartcard. /*! A SuisseID card issued by Swiss Post. @see http://postsuisseid.ch */ class PostSuisseID: public Card { public: PostSuisseID(mrw::Shared reader, mrw::Shared slot): Card(reader, slot), _minPinLen(0), _maxPinLen(-1) { } virtual unsigned int minimalPinLength() { if (_minPinLen==0) evaluatePinLengths(); return _minPinLen; } virtual unsigned int maximalPinLength() { if (_maxPinLen==-1) evaluatePinLengths(); return _maxPinLen; } std::string version() { if (_version.size()) return _version; // cache the version pcsc::Connection::Reader::Transaction lock(_reader); try { selectMfFile("5649"); return _version = cardos::BerValue(readBinary())[0].value(); } catch (...) { return _version = ""; } } private: void evaluatePinLengths() { pcsc::Connection::Reader::Transaction lock(_reader); selectPkcs15File("4408"); cardos::BerValues res(readBerFile()); for (cardos::BerValues::iterator it(res.begin()); it!=res.end(); ++it) if ((*it)[0][0].value()=="PIN" || (*it)[0][0].value()=="Digital Signature PIN") { if ((*it)[2][0][2].toULong()>_minPinLen) _minPinLen = (*it)[2][0][2].toULong(); if ((*it)[2][0][4].toULong()<_maxPinLen) _maxPinLen = (*it)[2][0][4].toULong(); } } private: std::string _version; // version is cached unsigned int _minPinLen; // minimal PIN length is cached unsigned int _maxPinLen; // maximal PIN length is cached }; //! List of cards, returned by @ref suisseid::Scanner::scan. typedef std::vector > Cards; //! Auxiliary SuisseID card manager. /** Use this manager to scan your system for SuisseID cards. Usage Example: @code #include #include [...] try { suisseid::Cards cards(suisseid::Scanner().scan()); for (auto card(cards.begin()); card!=cards.end(); ++card) std::cout<<"Found SuisseID: "<<(*card)->name()< (new PostSuisseID(_pcsc.reader(*reader), slots[0]))); } return res; } private: pcsc::Connection _pcsc; cryptoki::Library _cryptoki; }; } //@} #endif