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
|
||||||
|
146
src/cardos.hxx
146
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,31 +157,42 @@ 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() {
|
||||||
@@ -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;
|
||||||
@@ -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) {
|
||||||
@@ -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