This library provides a simple and nice C++ wrapper around these libraries, so that programmers can concentrate on functionality. It offers general support for PCSC-lite, OpenSSL, PKCS#11, plus specific functionality for the SuisseID.
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
7.3 KiB
202 lines
7.3 KiB
/*! @file |
|
|
|
@id $Id$ |
|
*/ |
|
// 1 2 3 4 5 6 7 8 |
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890 |
|
|
|
#ifndef __CRYPTAUX_HXX__ |
|
#define __CRYPTAUX_HXX__ |
|
|
|
#include <string> |
|
#include <sstream> |
|
#include <iomanip> |
|
#include <stdexcept> |
|
#include <algorithm> |
|
|
|
/*! @defgroup gcrypto Auxiliary Crypto-Functions |
|
|
|
Auxiliary often used funcions in cryptographic environment, such |
|
as logging, converting binary from and to hexadecimal or creating |
|
readable texts from binary data. */ |
|
//@{ |
|
|
|
#define CRYPTOLOG_QUOTE(X) CRYPTOLOG_QUOTE2(X) |
|
#define CRYPTOLOG_QUOTE2(X) #X |
|
#if __GNUC__ >= 2 |
|
# define CRYPTOLOG_END " -- "<<__PRETTY_FUNCTION__<<std::endl |
|
#else |
|
# define CRYPTOLOG_END std::endl |
|
#endif |
|
|
|
// Logging, enable with -DDEBUG |
|
#ifndef CRYPTOLOG |
|
# ifndef DEBUG |
|
# define CRYPTOLOG(X) |
|
# else |
|
# include <iostream> |
|
# define CRYPTOLOG(X) { \ |
|
std::string __C_FILE__(__FILE__); \ |
|
std::string __C_LINE__(CRYPTOLOG_QUOTE(__LINE__)); \ |
|
std::string::size_type __LOC_POS__(__C_FILE__.rfind('/')); \ |
|
if (__LOC_POS__!=std::string::npos) \ |
|
__C_FILE__=__C_FILE__.substr(__LOC_POS__+1); \ |
|
std::string __LOC_SPC1__(18>__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__<<" -- "<<X \ |
|
<<CRYPTOLOG_END; \ |
|
} |
|
# endif |
|
#endif |
|
|
|
// Verbose logging, use with care, will also log PINs. |
|
// Enable with -DDEBUG -DVERBOSE |
|
#ifndef CRYPTOLOG_VERBOSE |
|
# if !(defined(DEBUG)&&defined(VERBOSE)) |
|
# define CRYPTOLOG_VERBOSE(X) |
|
# else |
|
# include <iostream> |
|
# define CRYPTOLOG_VERBOSE(X) { \ |
|
std::string __C_FILE__(__FILE__); \ |
|
std::string __C_LINE__(CRYPTOLOG_QUOTE(__LINE__)); \ |
|
std::string::size_type __LOC_POS__(__C_FILE__.rfind('/')); \ |
|
if (__LOC_POS__!=std::string::npos) \ |
|
__C_FILE__=__C_FILE__.substr(__LOC_POS__+1); \ |
|
std::string __LOC_SPC1__(18>__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__<<" -- "<<X \ |
|
<<CRYPTOLOG_END; \ |
|
} |
|
# endif |
|
#endif |
|
|
|
namespace pcsc { |
|
/// Get library version identification |
|
std::string version(); |
|
} |
|
|
|
//! @ref gcrypto @copydoc gcrypto |
|
namespace crypto { |
|
|
|
static const std::string LETTER_CHARS |
|
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); |
|
static const std::string NUMBER_CHARS |
|
("0123456789"); |
|
//! Contains @c @ in addition to standard characters. |
|
static const std::string GRAFIC_CHARS |
|
("!\"#%&'()*+,-./:;<=>?[\\]^_{|}~@"); |
|
static const std::string BLANK_CHARS |
|
(" "); |
|
static const std::string VALID_CHARS |
|
(LETTER_CHARS+NUMBER_CHARS+GRAFIC_CHARS+BLANK_CHARS); |
|
|
|
inline std::string hex(const std::string& data) { |
|
std::stringstream res; |
|
for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it) |
|
res<<std::hex<<std::setfill('0')<<std::setw(2) |
|
<<(unsigned int)(unsigned char)*it; |
|
return res.str(); |
|
} |
|
|
|
inline std::string hexTxt(const std::string& data, |
|
std::string::size_type len=20, |
|
std::string::size_type indent=0) { |
|
std::stringstream res; |
|
std::string::size_type pos(0); |
|
for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it) { |
|
if (pos%len==0) res<<std::string(indent, ' '); |
|
res<<std::hex<<std::setfill('0')<<std::setw(2) |
|
<<(unsigned int)(unsigned char)*it; |
|
++pos; |
|
if (pos%len==0 || pos==data.size()) { |
|
res<<std::string(2*(len-(pos-1)%len), ' '); |
|
for (std::string::size_type i(pos-(pos-1)%len-1); i<pos; ++i) |
|
res<<(VALID_CHARS.find(data[i])==std::string::npos?'.':data[i]); |
|
if (pos!=data.size()) res<<std::endl; |
|
} |
|
} |
|
return res.str(); |
|
} |
|
|
|
inline std::string readable(const std::string& data, |
|
std::string::size_type len=20, |
|
std::string::size_type indent=0) { |
|
if (!data.size()) |
|
return std::string(indent, ' ')+"<empty>"; |
|
else if (data.find_first_not_of(VALID_CHARS)<data.size()) |
|
return hexTxt(data, len, indent); |
|
else |
|
return std::string(indent, ' ')+"\""+data+"\""; |
|
} |
|
|
|
//! Convert binary to readable hexadecimal |
|
inline std::string binToHex(char c) { |
|
std::stringstream ss; |
|
ss<<std::hex<<std::setw(2)<<std::setfill('0') |
|
<<(unsigned int)(unsigned char)(c); |
|
return ss.str(); |
|
} |
|
|
|
//! Convert binary to readable hexadecimal |
|
inline std::string binToHex(const std::string& s) { |
|
std::string result; |
|
for (std::string::const_iterator c(s.begin()); c!=s.end(); ++c) |
|
result += binToHex(*c); |
|
return result; |
|
} |
|
|
|
//! Convert readable lowercase hexadecimal to binary |
|
inline std::string hexToBin(std::string s) { |
|
const static std::string HEX("0123456789abcdef"); |
|
std::transform(s.begin(), s.end(), s.begin(), ::tolower); |
|
if (s.size()%2) |
|
throw std::runtime_error |
|
("input string \""+s |
|
+"\" must have an even number of hexadecimal numbers"); |
|
if (s.find_first_not_of(HEX)!=std::string::npos) |
|
throw std::runtime_error |
|
("input string \""+s+"\" has non hexadecimal value at position " |
|
+((std::stringstream&)(std::stringstream() |
|
<<s.find_first_not_of(HEX))).str()); |
|
std::string res; |
|
for (std::string::const_iterator it(s.begin()); it!=s.end(); ++it) { |
|
std::string::size_type c(HEX.find(*it)); |
|
if (++it!=s.end()) (c <<= 4) += HEX.find(*it); |
|
res += std::string(1, (std::string::value_type)c); |
|
} |
|
return res; |
|
} |
|
|
|
/// convert integer to binary of given size |
|
inline std::string toBinary(unsigned long data, int bytes=2) { |
|
std::string res(bytes, '\0'); |
|
for (int i(0); i<bytes; ++i) { |
|
res[i] = std::string::value_type(data&0xff); |
|
data>>=8; |
|
} |
|
return res; |
|
} |
|
|
|
/// convert integer from binary of given size |
|
inline unsigned long ulongFromBinary(const std::string& data) { |
|
unsigned long res(0); |
|
for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it) |
|
(res<<=8)+=(unsigned long)(unsigned char)*it; |
|
return res; |
|
} |
|
|
|
} |
|
|
|
//@} |
|
|
|
#endif
|
|
|