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.
 
 
 
 

204 lines
7.4 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.
To enable logging, add @c -DDEBUG to @c CPPFLAGS */
//@{
#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