preparations for writing a file; refs #28
This commit is contained in:
		| @@ -40,6 +40,7 @@ class Commands: public cardos::Commands { | |||||||
|         <<"  (s)elect(f)ile       <hex> Select file below master"<<std::endl |         <<"  (s)elect(f)ile       <hex> Select file below master"<<std::endl | ||||||
|         <<"  (s)elect(p)15(f)ile  <hex> Select file below PKCS#15"<<std::endl |         <<"  (s)elect(p)15(f)ile  <hex> Select file below PKCS#15"<<std::endl | ||||||
|         <<"  (s)elect(s)igg(f)ile <hex> Select file below SigG"<<std::endl |         <<"  (s)elect(s)igg(f)ile <hex> Select file below SigG"<<std::endl | ||||||
|  |         <<"  (r)ead(b)erfile            Read selected BER file"<<std::endl | ||||||
|         <<"  (r)ead(b)in(f)ile          Read selected binary file"<<std::endl |         <<"  (r)ead(b)in(f)ile          Read selected binary file"<<std::endl | ||||||
|         <<"  (r)ead(a)bsolute(r)ecord   Read absolute record"<<std::endl |         <<"  (r)ead(a)bsolute(r)ecord   Read absolute record"<<std::endl | ||||||
|         <<"  (r)ead(f)irst(r)ecord      Read first record"<<std::endl |         <<"  (r)ead(f)irst(r)ecord      Read first record"<<std::endl | ||||||
| @@ -69,7 +70,8 @@ class Commands: public cardos::Commands { | |||||||
|           else if (cmd=="selectfile"||cmd=="sf") selectMfFile(apdu()); |           else if (cmd=="selectfile"||cmd=="sf") selectMfFile(apdu()); | ||||||
|           else if (cmd=="selectp15file"||cmd=="spf") selectPkcs15File(apdu()); |           else if (cmd=="selectp15file"||cmd=="spf") selectPkcs15File(apdu()); | ||||||
|           else if (cmd=="selectsiggfile"||cmd=="ssf") selectSigGFile(apdu()); |           else if (cmd=="selectsiggfile"||cmd=="ssf") selectSigGFile(apdu()); | ||||||
|           else if (cmd=="readbinfile"||cmd=="rbf") _ber=readBinFile(); |           else if (cmd=="readberfile"||cmd=="rb") _ber=readBerFile(); | ||||||
|  |           else if (cmd=="readbinfile"||cmd=="rbf") readBinary(); | ||||||
|           else if (cmd=="readabsoluterecord"||cmd=="rar") _ber=readRecord(); |           else if (cmd=="readabsoluterecord"||cmd=="rar") _ber=readRecord(); | ||||||
|           else if (cmd=="readfirstrecord"||cmd=="rfr") |           else if (cmd=="readfirstrecord"||cmd=="rfr") | ||||||
|             _ber=readRecord(0, 0, FIRST_RECORD); |             _ber=readRecord(0, 0, FIRST_RECORD); | ||||||
| @@ -116,12 +118,12 @@ class Commands: public cardos::Commands { | |||||||
|       while (true) { |       while (true) { | ||||||
|         std::string res(send(0x00, 0xB2, 0, NEXT_RECORD)); |         std::string res(send(0x00, 0xB2, 0, NEXT_RECORD)); | ||||||
|         if (cardos::Commands::retCode(res)!=0x9000) break; |         if (cardos::Commands::retCode(res)!=0x9000) break; | ||||||
|         cardos::BerValue record(cardos::Commands::retData(res).substr(2)); |         cardos::BerValues record(cardos::Commands::retData(res).substr(2)); | ||||||
|         _ber += record; |         _ber += record; | ||||||
|         std::cout<<record[0][0].value() |         std::cout<<record[0][0][0].string() | ||||||
|                  <<": len=" |                  <<": len=" | ||||||
|                  <<record[2][0][2].toULong() |                  <<record[0][2][0][2].ulong() | ||||||
|                  <<"-"<<record[2][0][4].toULong()<<std::endl; |                  <<"-"<<record[0][2][0][4].ulong()<<std::endl; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|          |          | ||||||
|   | |||||||
| @@ -6,7 +6,8 @@ | |||||||
| noinst_HEADERS = suisse-id-demo.hxx | noinst_HEADERS = suisse-id-demo.hxx | ||||||
| noinst_PROGRAMS = pcsc-demo cryptoki-sign-demo cryptoki-demo		\ | noinst_PROGRAMS = pcsc-demo cryptoki-sign-demo cryptoki-demo		\ | ||||||
|                   openssl-tcp-demo openssl-ssl-demo			\ |                   openssl-tcp-demo openssl-ssl-demo			\ | ||||||
|                   openssl-engine-demo suisse-id-demo cardos-demo |                   openssl-engine-demo suisse-id-demo cardos-demo        \ | ||||||
|  |                   create-files-demo | ||||||
|  |  | ||||||
| AM_CPPFLAGS += -I${top_srcdir}/src -I/usr/include/PCSC | AM_CPPFLAGS += -I${top_srcdir}/src -I/usr/include/PCSC | ||||||
| AM_LDFLAGS = -L${top_builddir}/src -lpcscxx | AM_LDFLAGS = -L${top_builddir}/src -lpcscxx | ||||||
| @@ -35,6 +36,7 @@ openssl_ssl_demo_SOURCES = openssl-ssl-demo.cxx | |||||||
| openssl_engine_demo_SOURCES = openssl-engine-demo.cxx | openssl_engine_demo_SOURCES = openssl-engine-demo.cxx | ||||||
| cardos_demo_SOURCES = cardos-demo.cxx | cardos_demo_SOURCES = cardos-demo.cxx | ||||||
| suisse_id_demo_SOURCES = suisse-id-demo.cxx | suisse_id_demo_SOURCES = suisse-id-demo.cxx | ||||||
|  | create_files_demo_SOURCES = create-files-demo.cxx | ||||||
| # moc_suisse-id-demo.cxx | # moc_suisse-id-demo.cxx | ||||||
| suisse_id_demo_CXXFLAGS = ${QT_CFLAGS} | suisse_id_demo_CXXFLAGS = ${QT_CFLAGS} | ||||||
| suisse_id_demo_LDADD = ${QT_LIBS} | suisse_id_demo_LDADD = ${QT_LIBS} | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ int main(int argc, char** argv) try { | |||||||
|                    "Sign a text (optionally several times for performance" |                    "Sign a text (optionally several times for performance" | ||||||
|                    " measurements).", |                    " measurements).", | ||||||
|                    mrw::args::defaults() |                    mrw::args::defaults() | ||||||
|                    <<mrw::args::decl("l", "library", "cryptoki lirary to load", |                    <<mrw::args::decl("l", "library", "cryptoki library to load", | ||||||
|                                      mrw::args::decl::param_list() |                                      mrw::args::decl::param_list() | ||||||
|                                      <<mrw::args::param(lib, "lib"))); |                                      <<mrw::args::param(lib, "lib"))); | ||||||
|   // now lib contains the dynamic library to load |   // now lib contains the dynamic library to load | ||||||
|   | |||||||
							
								
								
									
										154
									
								
								src/cardos.hxx
									
									
									
									
									
								
							
							
						
						
									
										154
									
								
								src/cardos.hxx
									
									
									
									
									
								
							| @@ -19,7 +19,7 @@ | |||||||
| // use e.g. #define CARDOS_LOG(X) std::clog<<X<<std::endl | // use e.g. #define CARDOS_LOG(X) std::clog<<X<<std::endl | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /** @defgroup gcardos C++ Access to Siemens CardOS V4.4 | /** @defgroup gcardos C++ Access to Siemens CardOS 4.4 | ||||||
|     Implements APDUs for accessing Siemens CardOS V4.4 smartcards. */ |     Implements APDUs for accessing Siemens CardOS V4.4 smartcards. */ | ||||||
| //@{ | //@{ | ||||||
| /// @defgroup cardosexception CardOS Exceptions | /// @defgroup cardosexception CardOS Exceptions | ||||||
| @@ -157,33 +157,44 @@ namespace cardos { | |||||||
|         CHARACTER_STRING         = 0x1D, |         CHARACTER_STRING         = 0x1D, | ||||||
|         BMP_STRING               = 0x1E, |         BMP_STRING               = 0x1E, | ||||||
|       }; |       }; | ||||||
|     public: |  | ||||||
|  |  | ||||||
|       BerValue(std::vector<BerValue> sequence): |     protected: // use BerValues instead | ||||||
|  |  | ||||||
|  |       friend class BerValues; | ||||||
|  |  | ||||||
|  |       BerValue(const std::vector<BerValue>& sequence): | ||||||
|           _tag(PRIVATE|CONSTRUCTED|SEQUENCE), |           _tag(PRIVATE|CONSTRUCTED|SEQUENCE), | ||||||
|           _length(0), |  | ||||||
|           _sequence(sequence) { |           _sequence(sequence) { | ||||||
|       } |       } | ||||||
|        |        | ||||||
|       BerValue(const std::string& content) { |       BerValue(std::string& content) { | ||||||
|         if (content.size()<2) |         if (content.size()<2) | ||||||
|           throw wrong_dataformat(content, "not a BER, header size too small: \"" |           throw wrong_dataformat(content, "not a BER, header size too small: \"" | ||||||
|                                  +crypto::binToHex(content)+"\""); |                                  +crypto::binToHex(content)+"\""); | ||||||
|         _tag = content[0]; |         _tag = content[0]; | ||||||
|         _length = content[1]; |         unsigned char length = content[1]; | ||||||
|         _value = content.substr(2, _length); |         _value = content.substr(2, length); | ||||||
|         if (std::string::size_type(_length)+2>content.size()) |         if (content.size()<std::string::size_type(length)+2) | ||||||
|           throw wrong_dataformat(content, "not a BER, content size too" |           throw wrong_dataformat(content, "not a BER, content size too" | ||||||
|                                  " small: \""+crypto::binToHex(_value)+"\""); |                                  " small: \""+crypto::binToHex(_value)+"\""); | ||||||
|  |         content.erase(0, 2+length); | ||||||
|         if (tagType()==END_OF_CONTENT) return; // done |         if (tagType()==END_OF_CONTENT) return; // done | ||||||
|         if (isContainer()) { |         if (isContainer()) | ||||||
|           for (std::string::size_type pos(0); pos+1<_value.size(); |           while (_value.size()) _sequence.push_back(BerValue(_value)); | ||||||
|                pos+=2+_value[pos+1]) { // recursively extract value |  | ||||||
|             _sequence.push_back(BerValue(_value.substr(pos, 2+_value[pos+1]))); |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |     public: | ||||||
|  |  | ||||||
|  |       BerValue(unsigned char tag, const std::string& value): | ||||||
|  |           _tag(tag), _value(value) { | ||||||
|  |         if (isContainer()) | ||||||
|  |           while (_value.size()) _sequence.push_back(BerValue(_value)); | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |       BerValue(unsigned char tag, const std::vector<BerValue>& values): | ||||||
|  |           _tag(tag), _sequence(values) { | ||||||
|  |       } | ||||||
|  |        | ||||||
|       unsigned char tagClass() { |       unsigned char tagClass() { | ||||||
|         return _tag&0xC0; |         return _tag&0xC0; | ||||||
|       } |       } | ||||||
| @@ -213,21 +224,31 @@ namespace cardos { | |||||||
|         return _sequence[i]; |         return _sequence[i]; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       std::string value() { |       operator std::string() { | ||||||
|  |         std::string res; | ||||||
|  |         res.push_back(_tag); | ||||||
|  |         if (isContainer()) { | ||||||
|  |           for (std::vector<BerValue>::iterator it(_sequence.begin()); | ||||||
|  |                it!=_sequence.end(); ++it) { | ||||||
|  |             res += *it; | ||||||
|  |           } | ||||||
|  |         } else { | ||||||
|  |           (res += (char)_value.size()) += _value; | ||||||
|  |         } | ||||||
|  |         return res; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       std::string string() { | ||||||
|         return _value; |         return _value; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       unsigned long toULong() { |       unsigned long ulong() { | ||||||
|         unsigned long res(0); |         return crypto::ulongFromBinary(_value); | ||||||
|         for (std::string::reverse_iterator it(_value.rbegin()); |  | ||||||
|              it!=_value.rend(); ++it) |  | ||||||
|           (res<<=8)+=(unsigned)*it; |  | ||||||
|         return res; |  | ||||||
|       } |       } | ||||||
|        |        | ||||||
|       std::string print(int indent=0, int indentStep = 4) { |       std::string print(int indent=0, int indentStep = 4) { | ||||||
|         std::stringstream ss; |         std::stringstream ss; | ||||||
|         ss<<std::string(indent*indentStep, ' ')<<'['; |         ss<<std::string(indent*indentStep, ' ')<<'['<<crypto::binToHex(_tag)<<'='; | ||||||
|         switch (tagClass()) { |         switch (tagClass()) { | ||||||
|           case UNIVERSAL: ss<<"UNIVERSAL,"; break; |           case UNIVERSAL: ss<<"UNIVERSAL,"; break; | ||||||
|           case APPLICATION: ss<<"APPLICATION,"; break; |           case APPLICATION: ss<<"APPLICATION,"; break; | ||||||
| @@ -279,7 +300,7 @@ namespace cardos { | |||||||
|           for (std::vector<BerValue>::iterator it(_sequence.begin()); |           for (std::vector<BerValue>::iterator it(_sequence.begin()); | ||||||
|                it!=_sequence.end(); ++it) { |                it!=_sequence.end(); ++it) { | ||||||
|             ss<<std::string((indent+1)*indentStep, ' ') |             ss<<std::string((indent+1)*indentStep, ' ') | ||||||
|               <<" ["<<i++<<"]{" |               <<"["<<i++<<"] {" | ||||||
|               <<std::endl |               <<std::endl | ||||||
|               <<it->print(indent+2, indentStep) |               <<it->print(indent+2, indentStep) | ||||||
|               <<std::endl |               <<std::endl | ||||||
| @@ -292,15 +313,14 @@ namespace cardos { | |||||||
|           for (std::string::const_iterator it(_value.begin()); |           for (std::string::const_iterator it(_value.begin()); | ||||||
|                it!=_value.end(); ++it) |                it!=_value.end(); ++it) | ||||||
|             ss<<(isprint(*it)?*it:'.'); |             ss<<(isprint(*it)?*it:'.'); | ||||||
|  |           ss<<"\""; | ||||||
|         } |         } | ||||||
|         ss<<"\""; |  | ||||||
|         return ss.str(); |         return ss.str(); | ||||||
|       } |       } | ||||||
|        |        | ||||||
|     private: |     private: | ||||||
|        |        | ||||||
|       unsigned char _tag; |       unsigned char _tag; | ||||||
|       unsigned char _length; |  | ||||||
|       std::string _value; |       std::string _value; | ||||||
|       std::vector<BerValue> _sequence; |       std::vector<BerValue> _sequence; | ||||||
|  |  | ||||||
| @@ -309,13 +329,24 @@ namespace cardos { | |||||||
|   /// Store a sequence of BerValue |   /// Store a sequence of BerValue | ||||||
|   class BerValues: public std::vector<BerValue> { |   class BerValues: public std::vector<BerValue> { | ||||||
|     public: |     public: | ||||||
|       BerValues& operator=(const std::string& content) { |       BerValues() {} | ||||||
|  |       BerValues(const std::string& content) { | ||||||
|  |         std::string contentCopy(content); | ||||||
|  |         while (contentCopy.size()) push_back(BerValue(contentCopy)); | ||||||
|  |       } | ||||||
|  |       BerValues& operator=(std::string& content) { | ||||||
|         clear(); |         clear(); | ||||||
|         push_back(BerValue(content)); |         std::string contentCopy(content); | ||||||
|  |         while (contentCopy.size()) push_back(BerValue(contentCopy)); | ||||||
|         return *this; |         return *this; | ||||||
|       } |       } | ||||||
|       BerValues& operator+=(const BerValue& value) { |       BerValues& operator+=(const std::string& content) { | ||||||
|         push_back(value); |         std::string contentCopy(content); | ||||||
|  |         while (contentCopy.size()) push_back(BerValue(contentCopy)); | ||||||
|  |         return *this; | ||||||
|  |       } | ||||||
|  |       BerValues& operator+=(const BerValues& values) { | ||||||
|  |         insert(end(), values.begin(), values.end()); | ||||||
|         return *this; |         return *this; | ||||||
|       } |       } | ||||||
|       std::string print(int indent=0, int indentStep = 4) { |       std::string print(int indent=0, int indentStep = 4) { | ||||||
| @@ -327,7 +358,7 @@ namespace cardos { | |||||||
|           ss<<"{"<<std::endl; |           ss<<"{"<<std::endl; | ||||||
|           for (iterator it(begin()); it!=end(); ++it) { |           for (iterator it(begin()); it!=end(); ++it) { | ||||||
|             ss<<std::string((indent+1)*indentStep, ' ') |             ss<<std::string((indent+1)*indentStep, ' ') | ||||||
|               <<" ["<<i++<<"]{" |               <<"["<<i++<<"] {" | ||||||
|               <<std::endl |               <<std::endl | ||||||
|               <<it->print(indent+2, indentStep) |               <<it->print(indent+2, indentStep) | ||||||
|               <<std::endl |               <<std::endl | ||||||
| @@ -590,13 +621,30 @@ namespace cardos { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       //! Creates a file (only EF or DF) |       //! Creates a file (only EF or DF) | ||||||
|       void createFile(BerValue) { |       void createFile(std::string path="", const std::string data="") { | ||||||
|         CRYPTOLOG("log"); |         CRYPTOLOG("log"); | ||||||
|  |         // pcsc::Connection::Reader::Transaction lock(_reader); | ||||||
|  |         // if (path.size()) select(path); | ||||||
|  |         // check(send(0x00, 0xE0, 0x00, 0x00,  | ||||||
|         // check(send(0x00, 0xE0, 0x00, 0x00, BerValue(0x62h, |         // check(send(0x00, 0xE0, 0x00, 0x00, BerValue(0x62h, | ||||||
|         // data).raw())); |         // data).raw())); | ||||||
|         assert(!"not implemented"); |         assert(!"not implemented"); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       //! Creates a EF file | ||||||
|  |       void createBinary(std::string path="", std::string id="", | ||||||
|  |                         const std::string data="") { | ||||||
|  |         CRYPTOLOG("log"); | ||||||
|  |         pcsc::Connection::Reader::Transaction lock(_reader); | ||||||
|  |         if (path.size()) select(path); | ||||||
|  |         BerValues c; | ||||||
|  |         c += BerValue(0x80, crypto::toBinary(data.size())); | ||||||
|  |         std::string idbin(crypto::hexToBin(id)); | ||||||
|  |         if (idbin.size()!=2) throw runtime_error("file id must be two bytes"); | ||||||
|  |         c += BerValue(0x83, idbin); | ||||||
|  |         check(send(0x00, 0xE0, 0x00, 0x00, BerValue(82, c))); | ||||||
|  |       } | ||||||
|  |  | ||||||
|       //! Deactivates a file or a file tree |       //! Deactivates a file or a file tree | ||||||
|       void deactivateFile() { |       void deactivateFile() { | ||||||
|         CRYPTOLOG("log"); |         CRYPTOLOG("log"); | ||||||
| @@ -618,9 +666,19 @@ namespace cardos { | |||||||
|       enum FileTypes {DF=0x00, EF=0x01, DF_EF=0x02}; |       enum FileTypes {DF=0x00, EF=0x01, DF_EF=0x02}; | ||||||
|  |  | ||||||
|       //! Reads file information of EFs and/or DFs in the current DF |       //! Reads file information of EFs and/or DFs in the current DF | ||||||
|       BerValue directory(FileTypes types, unsigned char offset=0) { |       BerValues directory(std::string path, FileTypes types=DF_EF, | ||||||
|  |                           unsigned char offset=0) { | ||||||
|         CRYPTOLOG("log"); |         CRYPTOLOG("log"); | ||||||
|         return BerValue(check(send(0x80, 0x16, types, offset))); |         unsigned char o(offset); | ||||||
|  |         BerValues content; | ||||||
|  |         pcsc::Connection::Reader::Transaction lock(_reader); | ||||||
|  |         if (path.size()) select(path); | ||||||
|  |         /*while (o<(unsigned char)-1)*/ { /// @todo read until done | ||||||
|  |           std::string res(check(send(0x80, 0x16, types, o++))); | ||||||
|  |           //if (cardos::Commands::retCode(res)!=0x9000) break; | ||||||
|  |           content += res; | ||||||
|  |         } | ||||||
|  |         return content; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       //! Enables an already loaded and activated but disabled license package. |       //! Enables an already loaded and activated but disabled license package. | ||||||
| @@ -832,8 +890,10 @@ namespace cardos { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       //! Read a BINARY file |       //! Read a BINARY file | ||||||
|       std::string readBinary(unsigned short offset = 0) { |       std::string readBinary(std::string path="", unsigned short offset = 0) { | ||||||
|         CRYPTOLOG("log"); |         CRYPTOLOG("log"); | ||||||
|  |         pcsc::Connection::Reader::Transaction lock(_reader); | ||||||
|  |         if (path.size()) select(path); | ||||||
|         return check(send(0x00, 0xB0, offset>>8, offset&0xFF)); |         return check(send(0x00, 0xB0, offset>>8, offset&0xFF)); | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -855,14 +915,15 @@ namespace cardos { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       /// Read all records from a record oriented file |       /// Read all records from a record oriented file | ||||||
|       BerValues readBerFile() { |       BerValues readBerFile(std::string path="") { | ||||||
|         CRYPTOLOG("log"); |         CRYPTOLOG("log"); | ||||||
|         BerValues content; |         BerValues content; | ||||||
|         pcsc::Connection::Reader::Transaction lock(_reader); |         pcsc::Connection::Reader::Transaction lock(_reader); | ||||||
|  |         if (path.size()) select(path); | ||||||
|         while (true) { |         while (true) { | ||||||
|           std::string res(send(0x00, 0xB2, 0, NEXT_RECORD)); |           std::string res(send(0x00, 0xB2, 0, NEXT_RECORD)); | ||||||
|           if (cardos::Commands::retCode(res)!=0x9000) break; |           if (cardos::Commands::retCode(res)!=0x9000) break; | ||||||
|           content += BerValue(retData(res).substr(2)); |           content += retData(res).substr(2); | ||||||
|         } |         } | ||||||
|         return content; |         return content; | ||||||
|       } |       } | ||||||
| @@ -896,13 +957,13 @@ namespace cardos { | |||||||
|       }; |       }; | ||||||
|  |  | ||||||
|       //! Selects a file |       //! Selects a file | ||||||
|       BerValue selectFile(std::string file, |       BerValues selectFile(std::string file, | ||||||
|                           FileSelectionMode mode |                           FileSelectionMode mode | ||||||
|                           = DF_OR_EF_USING_PATH_FROM_MF, |                           = DF_OR_EF_USING_PATH_FROM_MF, | ||||||
|                           FileSelectionReturn ret |                           FileSelectionReturn ret | ||||||
|                           = RETURN_NOTHING) { |                           = RETURN_NOTHING) { | ||||||
|         CRYPTOLOG("log"); |         CRYPTOLOG("log"); | ||||||
|         return BerValue(check(send(0x00, 0xA4, mode, ret, file))); |         return BerValues(check(send(0x00, 0xA4, mode, ret, file))); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       //! Sets the so-called Data_Field_Length parameter relevant for |       //! Sets the so-called Data_Field_Length parameter relevant for | ||||||
| @@ -932,11 +993,12 @@ namespace cardos { | |||||||
|         assert(!"not implemented"); |         assert(!"not implemented"); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       /// Read the previously file from smart card |       // same as readBinary | ||||||
|       std::string readBinFile() { |       // /// Read the previously file from smart card | ||||||
|         CRYPTOLOG("log"); |       // std::string readBinFile() { | ||||||
|         return check(send(0x00, 0xB0, 0x00, 0x00)); |       //   CRYPTOLOG("log"); | ||||||
|       } |       //   return check(send(0x00, 0xB0, 0x00, 0x00)); | ||||||
|  |       // } | ||||||
|  |  | ||||||
|       //! Updates a BINARY file |       //! Updates a BINARY file | ||||||
|       void updateBinary(std::string data, unsigned short offset=0) { |       void updateBinary(std::string data, unsigned short offset=0) { | ||||||
| @@ -1123,6 +1185,12 @@ namespace cardos { | |||||||
|         check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin("3f00"+file))); |         check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin("3f00"+file))); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       /// Generic select file | ||||||
|  |       void select(std::string path) { | ||||||
|  |         CRYPTOLOG("log"); | ||||||
|  |         check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin(path))); | ||||||
|  |       } | ||||||
|  |  | ||||||
|      /// Select the PKCS#15 part on the smart card |      /// Select the PKCS#15 part on the smart card | ||||||
|       void selectPkcs15() { |       void selectPkcs15() { | ||||||
|         CRYPTOLOG("log"); |         CRYPTOLOG("log"); | ||||||
|   | |||||||
| @@ -163,6 +163,25 @@ namespace crypto { | |||||||
|     } |     } | ||||||
|     return res; |     return res; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /// convert integer to binary of given size | ||||||
|  |   inline std::string toBinary(unsigned long data, int bytes=2) { | ||||||
|  |     std::string res(0, bytes); | ||||||
|  |     for (int i(0); i<bytes; ++i) { | ||||||
|  |       res[bytes-i-1] = data&0xff; | ||||||
|  |       data>>=8; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   /// 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; | ||||||
|  |     return res; | ||||||
|  |   } | ||||||
|  |    | ||||||
| } | } | ||||||
|  |  | ||||||
| //@} | //@} | ||||||
|   | |||||||
| @@ -337,12 +337,12 @@ namespace suisseid { | |||||||
|         selectPkcs15File("4408"); |         selectPkcs15File("4408"); | ||||||
|         cardos::BerValues res(readBerFile()); |         cardos::BerValues res(readBerFile()); | ||||||
|         for (cardos::BerValues::iterator it(res.begin()); it!=res.end(); ++it) |         for (cardos::BerValues::iterator it(res.begin()); it!=res.end(); ++it) | ||||||
|           if ((*it)[0][0].value()=="PIN" || |           if ((*it)[0][0].string()=="PIN" || | ||||||
|               (*it)[0][0].value()=="Digital Signature PIN") { |               (*it)[0][0].string()=="Digital Signature PIN") { | ||||||
|             if ((*it)[2][0][2].toULong()>_minPinLen) |             if ((*it)[2][0][2].ulong()>_minPinLen) | ||||||
|               _minPinLen = (*it)[2][0][2].toULong(); |               _minPinLen = (*it)[2][0][2].ulong(); | ||||||
|             if ((*it)[2][0][4].toULong()<_maxPinLen) |             if ((*it)[2][0][4].ulong()<_maxPinLen) | ||||||
|               _maxPinLen = (*it)[2][0][4].toULong(); |               _maxPinLen = (*it)[2][0][4].ulong(); | ||||||
|           } |           } | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -350,7 +350,7 @@ namespace suisseid { | |||||||
|         pcsc::Connection::Reader::Transaction lock(_reader); |         pcsc::Connection::Reader::Transaction lock(_reader); | ||||||
|         try { |         try { | ||||||
|           selectMfFile(file); |           selectMfFile(file); | ||||||
|           return _version = cardos::BerValue(readBinary())[0].value(); |           return _version = cardos::BerValues(readBinary())[0].string(); | ||||||
|         } catch (...) { |         } catch (...) { | ||||||
|           return _version = "<unknown>"; |           return _version = "<unknown>"; | ||||||
|         } |         } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user