/*! @file
@ id $ Id $
*/
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
// #include <pcsc.hxx>
// #include <cryptaux.hxx>
// #include <openssl.hxx>
# include <string>
# include <mrw/checkcxx11.hxx>
# include <memory>
# include <cctype>
# include <stdexcept>
# include <sstream>
# include <iostream>
# include <iomanip>
# define CARDOS_LOG(X) std::cout<<X<<std::endl
# include <cardos.hxx>
class Commands : public cardos : : Commands {
public :
void help ( ) {
std : : cout
< < " Commands: " < < std : : endl
< < " COMMAND DATA PURPOSE " < < std : : endl
< < " (h)elp Show this help " < < std : : endl
< < " (q)quit Quit " < < std : : endl
< < " (l)ist List all reader " < < std : : endl
< < " (r)eader <num> Select reader by number " < < std : : endl
< < " (s)erial Show token serial number " < < std : : endl
< < " (a)pdu <hex> Send APDU hex data " < < std : : endl
< < " (m)aster(f)ile Select master file " < < std : : endl
< < " (p)kcs(15) Select PKCS#15 file " < < std : : endl
< < " (s)ig(g) Select SigG file " < < 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(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(a)bsolute(r)ecord Read absolute record " < < std : : endl
< < " (r)ead(f)irst(r)ecord Read first record " < < std : : endl
< < " (r)ead(n)ext(r)ecord Read next record " < < std : : endl
< < " (p)in(s)status <id> Query status of PIN <id> " < < std : : endl
< < " (l)ogon <id> <pin> logon to key with PIN " < < std : : endl
< < " (l)ogon(p)15 <pin> logon with user PIN " < < std : : endl
< < " (l)ogonpu(k) <pin> logon with user PUK " < < std : : endl
< < " (l)ogon(s)igg <pin> logon with SigG PIN " < < std : : endl
< < " (l)ogon(t)transport <pin> logon with transport PIN " < < std : : endl
< < " (g)et(p)in(l)engths get PIN min max lengths " < < std : : endl
< < " Note: \" (h)elp \" means: type \" help \" or simply \" h \" " < < std : : endl ;
}
int run ( ) {
std : : string cmd ;
while ( std : : cout < < " cmd> " , std : : cin > > cmd ) try {
if ( cmd = = " help " | | cmd = = " h " ) help ( ) ;
else if ( cmd = = " quit " | | cmd = = " q " ) return 0 ;
else if ( cmd = = " list " | | cmd = = " l " ) listReader ( ) ;
else if ( cmd = = " reader " | | cmd = = " r " ) selectReader ( ) ;
else if ( cmd = = " serial " | | cmd = = " s " ) serial ( ) ;
else if ( cmd = = " apdu " | | cmd = = " a " ) sendAPDU ( apdu ( ) ) ;
else if ( cmd = = " masterfile " | | cmd = = " mf " ) selectMF ( ) ;
else if ( cmd = = " pkcs15 " | | cmd = = " p15 " ) selectPkcs15 ( ) ;
else if ( cmd = = " sigg " | | cmd = = " sg " ) selectSigG ( ) ;
else if ( cmd = = " selectfile " | | cmd = = " sf " ) selectMfFile ( apdu ( ) ) ;
else if ( cmd = = " selectp15file " | | cmd = = " spf " ) selectPkcs15File ( apdu ( ) ) ;
else if ( cmd = = " selectsiggfile " | | cmd = = " ssf " ) selectSigGFile ( apdu ( ) ) ;
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 = = " readfirstrecord " | | cmd = = " rfr " )
_ber = readRecord ( 0 , 0 , FIRST_RECORD ) ;
else if ( cmd = = " readnextrecord " | | cmd = = " rnr " )
_ber = readRecord ( 0 , 0 , NEXT_RECORD ) ;
else if ( cmd = = " pinstatus " | | cmd = = " ps " ) pinStatus ( id ( ) ) ;
else if ( cmd = = " logon " | | cmd = = " l " ) logon ( id ( ) , pin ( ) ) ;
else if ( cmd = = " logonp15 " | | cmd = = " lp " ) logonPkcs15 ( pin ( ) ) ;
else if ( cmd = = " logonppuk " | | cmd = = " lk " ) logonPuk ( pin ( ) ) ;
else if ( cmd = = " logonsigg " | | cmd = = " ls " ) logonSigG ( pin ( ) ) ;
else if ( cmd = = " logontransport " | | cmd = = " lt " ) logonTransport ( pin ( ) ) ;
else if ( cmd = = " getpinlengths " | | cmd = = " gpl " ) getPinLengths ( ) ;
else if ( cmd = = " print " | | cmd = = " p " ) std : : cout < < _ber . print ( ) < < std : : endl ;
else help ( ) ;
} catch ( const std : : exception & e ) {
std : : cout < < " **** Error: " < < e . what ( ) < < std : : endl ;
}
return 0 ;
}
void listReader ( ) {
_readers = pcsc : : Connection : : scan ( ) ;
std : : cout < < " Found " < < _readers . size ( ) < < " readers "
< < ( _readers . size ( ) ? " : " : " . " ) < < std : : endl ;
int i ( 0 ) ;
for ( pcsc : : Connection : : Strings : : const_iterator it ( _readers . begin ( ) ) ;
it ! = _readers . end ( ) ; + + it , + + i )
std : : cout < < " " < < i < < " . " < < * it < < std : : endl ;
}
void selectReader ( ) {
listReader ( ) ;
pcsc : : Connection : : Strings : : size_type num ( 0 ) ;
if ( std : : cin > > num & & num < _readers . size ( ) ) {
_reader = pcsc : : Connection : : reader ( _readers [ num ] ) ;
std : : cout < < " Active Reader: " < < _readers [ num ] < < std : : endl ;
} else throw std : : runtime_error ( " no valid reader selected " ) ;
}
void getPinLengths ( ) {
selectPkcs15File ( " 4408 " ) ;
_ber . clear ( ) ;
while ( true ) {
std : : string res ( send ( 0x00 , 0xB2 , 0 , NEXT_RECORD ) ) ;
if ( cardos : : Commands : : retCode ( res ) ! = 0x9000 ) break ;
cardos : : BerValues record ( cardos : : Commands : : retData ( res ) . substr ( 2 ) ) ;
_ber + = record ;
std : : cout < < record [ 0 ] [ 0 ] [ 0 ] . string ( )
< < " : len= "
< < record [ 0 ] [ 2 ] [ 0 ] [ 2 ] . ulong ( )
< < " - " < < record [ 0 ] [ 2 ] [ 0 ] [ 4 ] . ulong ( ) < < std : : endl ;
}
}
private :
std : : string apdu ( ) {
std : : string data ;
if ( ! ( std : : cin > > data ) )
throw std : : runtime_error ( " please enter bytes in hex " ) ;
return data ;
}
std : : string pin ( ) {
std : : string data ;
if ( ! ( std : : cin > > data ) )
throw std : : runtime_error ( " please enter pin " ) ;
return data ;
}
unsigned char id ( ) {
std : : string data ;
if ( ! ( std : : cin > > data ) | | data . size ( ) ! = 2 | |
data . find_first_not_of ( " 0123456789abcdef " ) ! = std : : string : : npos )
throw std : : runtime_error ( " please enter one byte in hex " ) ;
return crypto : : hexToBin ( data ) [ 0 ] ;
}
private :
pcsc : : Connection : : Strings _readers ;
cardos : : BerValues _ber ;
} ;
int main ( int , char * * ) {
std : : cout < < " Type \" help \" for help. " < < std : : endl ;
return Commands ( ) . run ( ) ;
}