now secure channel enabled
This commit is contained in:
@@ -30,7 +30,15 @@ namespace crypto {
|
||||
static const std::string VALID_CHARS
|
||||
(LETTER_CHARS+NUMBER_CHARS+GRAFIC_CHARS+BLANK_CHARS);
|
||||
|
||||
inline std::string hex(const std::string& data,
|
||||
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::stringstream res;
|
||||
std::string::size_type pos(0);
|
||||
@@ -53,7 +61,7 @@ namespace crypto {
|
||||
if (!data.size())
|
||||
return "<empty>";
|
||||
else if (data.find_first_not_of(VALID_CHARS)<data.size())
|
||||
return hex(data);
|
||||
return hexTxt(data);
|
||||
else
|
||||
return "\""+data+"\"";
|
||||
}
|
||||
|
@@ -239,6 +239,21 @@ namespace cryptoki {
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ObjectList Session::find(const Attribute& a) {
|
||||
AttributeList al;
|
||||
al.push_back(a);
|
||||
return find(al);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ObjectList Session::find(const Attribute& a1, const Attribute& a2) {
|
||||
AttributeList al;
|
||||
al.push_back(a1);
|
||||
al.push_back(a2);
|
||||
return find(al);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Object Session::create(const std::string& label, const openssl::X509& cert) {
|
||||
AttributeList attrs;
|
||||
|
@@ -1002,6 +1002,11 @@ namespace cryptoki {
|
||||
//! Get a list of matching objects.
|
||||
ObjectList find(const AttributeList& attrs=AttributeList());
|
||||
|
||||
//! Get a list of matching objects.
|
||||
ObjectList find(const Attribute& a);
|
||||
//! Get a list of matching objects.
|
||||
ObjectList find(const Attribute& a1, const Attribute& a2);
|
||||
|
||||
//! Create a new Certificate Object.
|
||||
Object create(const std::string& label, const openssl::X509& cert);
|
||||
//! Create a new PrivateKey Object.
|
||||
|
204
src/openssl.hxx
204
src/openssl.hxx
@@ -11,6 +11,7 @@
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/x509.h>
|
||||
#include "openssl/bio.h"
|
||||
#include "openssl/des.h"
|
||||
#include "openssl/ssl.h"
|
||||
#include <openssl/err.h>
|
||||
#include <vector>
|
||||
@@ -21,6 +22,8 @@
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
#include <iostream> //! @todo remove (debug only)
|
||||
|
||||
/*! @defgroup gopenssl C++ Wrapper around OpenSSL API */
|
||||
//@{
|
||||
//! @defgroup openssllib OpenSSL C++ Library
|
||||
@@ -55,6 +58,13 @@ namespace openssl {
|
||||
}
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
class encryption_error: public openssl_error {
|
||||
public:
|
||||
encryption_error(const std::string& reason) throw():
|
||||
openssl_error("encryption: "+reason) {
|
||||
}
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
class pkcs12_error: public openssl_error {
|
||||
public:
|
||||
pkcs12_error(const std::string& reason) throw():
|
||||
@@ -90,6 +100,13 @@ namespace openssl {
|
||||
}
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
class cannot_encrypt: public encryption_error {
|
||||
public:
|
||||
cannot_encrypt(std::string reason) throw():
|
||||
encryption_error("cannot encrypt text: "+reason) {
|
||||
}
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
class allocation_failed: public x509_error {
|
||||
public:
|
||||
allocation_failed() throw():
|
||||
@@ -225,6 +242,193 @@ namespace openssl {
|
||||
}
|
||||
};
|
||||
|
||||
inline std::string desEnc(const std::string& txt, DES_cblock key1) {
|
||||
std::string res(txt);
|
||||
if (txt.size()%8!=0)
|
||||
throw cannot_encrypt("text size must be a multiple of eight");
|
||||
DES_key_schedule ks1;
|
||||
DES_set_key_unchecked(&(DES_cblock&)key1, &ks1);
|
||||
for (std::string::size_type pos(0); pos<txt.size(); pos+=8) {
|
||||
union {
|
||||
DES_cblock array;
|
||||
const char* text;
|
||||
} in, out;
|
||||
in.text = txt.begin().operator->()+pos;
|
||||
out.text = res.begin().operator->()+pos;
|
||||
DES_ecb_encrypt(&in.array, &out.array, &ks1, DES_ENCRYPT);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
inline std::string desDec(const std::string& txt, DES_cblock key1) {
|
||||
std::string res(txt);
|
||||
if (txt.size()%8!=0)
|
||||
throw cannot_encrypt("text size must be a multiple of eight");
|
||||
DES_key_schedule ks1;
|
||||
DES_set_key_unchecked(&(DES_cblock&)key1, &ks1);
|
||||
for (std::string::size_type pos(0); pos<txt.size(); pos+=8) {
|
||||
union {
|
||||
DES_cblock array;
|
||||
const char* text;
|
||||
} in, out;
|
||||
in.text = txt.begin().operator->()+pos;
|
||||
out.text = res.begin().operator->()+pos;
|
||||
DES_ecb_encrypt(&in.array, &out.array, &ks1, DES_DECRYPT);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
class CBlock8 {
|
||||
public:
|
||||
CBlock8() {
|
||||
_cb[0] = _cb[1] = _cb[2] = _cb[3] =
|
||||
_cb[4] = _cb[5] = _cb[6] = _cb[7] = 0;
|
||||
}
|
||||
CBlock8(unsigned char c1, unsigned char c2, unsigned char c3,
|
||||
unsigned char c4, unsigned char c5, unsigned char c6,
|
||||
unsigned char c7, unsigned char c8) {
|
||||
_cb[0] = c1;
|
||||
_cb[1] = c2;
|
||||
_cb[2] = c3;
|
||||
_cb[3] = c4;
|
||||
_cb[4] = c5;
|
||||
_cb[5] = c6;
|
||||
_cb[6] = c7;
|
||||
_cb[7] = c8;
|
||||
}
|
||||
//! String must contain exactly 8 char.
|
||||
CBlock8(const std::string& s) {
|
||||
assert(s.size()==8);
|
||||
_cb[0] = s[0];
|
||||
_cb[1] = s[1];
|
||||
_cb[2] = s[3];
|
||||
_cb[3] = s[4];
|
||||
_cb[4] = s[5];
|
||||
_cb[5] = s[6];
|
||||
_cb[6] = s[7];
|
||||
_cb[7] = s[8];
|
||||
}
|
||||
operator DES_cblock&() {
|
||||
return _cb;
|
||||
}
|
||||
operator DES_cblock*() {
|
||||
return &_cb;
|
||||
}
|
||||
operator std::string() const {
|
||||
return std::string((char*)_cb, 8);
|
||||
}
|
||||
private:
|
||||
DES_cblock _cb;
|
||||
};
|
||||
|
||||
/*! @param txt If the length is not an integral multiple of eight
|
||||
bytes, it is zero filled. The output is always an
|
||||
integral multiple of eight bytes. */
|
||||
inline std::string desCbcEnc(std::string txt, CBlock8 key, CBlock8& ivec) {
|
||||
if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0);
|
||||
std::string res(txt.size(), 0);
|
||||
DES_key_schedule ks;
|
||||
DES_set_key_unchecked(key, &ks);
|
||||
DES_ncbc_encrypt((unsigned char*)&txt[0], (unsigned char*)&res[0],
|
||||
txt.size(), &ks, ivec, DES_ENCRYPT);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*! @param txt If the length is not an integral multiple of eight
|
||||
bytes, it is zero filled. The output is always an
|
||||
integral multiple of eight bytes. */
|
||||
inline std::string desCbcEnc(const std::string& txt, const CBlock8& key) {
|
||||
CBlock8 ivec;
|
||||
return desCbcEnc(txt, key, ivec);
|
||||
}
|
||||
|
||||
/*! @param txt If the length is not an integral multiple of eight
|
||||
bytes, it is zero filled. The output is always an
|
||||
integral multiple of eight bytes. */
|
||||
inline std::string desCbcDec(std::string txt, CBlock8 key, CBlock8& ivec) {
|
||||
if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0);
|
||||
std::string res(txt.size(), 0);
|
||||
DES_key_schedule ks;
|
||||
DES_set_key_unchecked(key, &ks);
|
||||
DES_ncbc_encrypt((unsigned char*)&txt[0], (unsigned char*)&res[0],
|
||||
txt.size(), &ks, ivec, DES_DECRYPT);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*! @param txt If the length is not an integral multiple of eight
|
||||
bytes, it is zero filled. The output is always an
|
||||
integral multiple of eight bytes. */
|
||||
inline std::string desCbcDec(const std::string& txt, const CBlock8& key) {
|
||||
CBlock8 ivec;
|
||||
return desCbcDec(txt, key, ivec);
|
||||
}
|
||||
|
||||
/*! @param txt If the length is not an integral multiple of eight
|
||||
bytes, it is zero filled. The output is always an
|
||||
integral multiple of eight bytes. */
|
||||
inline std::string des2edeCbcEnc(std::string txt,
|
||||
CBlock8 key1, CBlock8 key2,
|
||||
CBlock8 ivec = CBlock8()) {
|
||||
if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0);
|
||||
std::string res(txt.size(), 0);
|
||||
DES_key_schedule ks1, ks2;
|
||||
DES_set_key_unchecked(key1, &ks1);
|
||||
DES_set_key_unchecked(key2, &ks2);
|
||||
DES_ede2_cbc_encrypt((unsigned char*)&txt[0], (unsigned char*)&res[0],
|
||||
txt.size(), &ks1, &ks2, ivec, DES_ENCRYPT);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*! @param txt If the length is not an integral multiple of eight
|
||||
bytes, it is zero filled. The output is always an
|
||||
integral multiple of eight bytes. */
|
||||
inline std::string des2edeCbcDec(std::string txt,
|
||||
CBlock8 key1, CBlock8 key2,
|
||||
CBlock8 ivec = CBlock8()) {
|
||||
if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0);
|
||||
std::string res(txt.size(), 0);
|
||||
DES_key_schedule ks1, ks2;
|
||||
DES_set_key_unchecked(key1, &ks1);
|
||||
DES_set_key_unchecked(key2, &ks2);
|
||||
DES_ede2_cbc_encrypt((unsigned char*)&txt[0], (unsigned char*)&res[0],
|
||||
txt.size(), &ks1, &ks2, ivec, DES_DECRYPT);
|
||||
return res;
|
||||
}
|
||||
|
||||
//! @todo untested
|
||||
inline std::string des2ecbEnc(std::string txt,
|
||||
CBlock8 key1, CBlock8 key2) {
|
||||
std::string res;
|
||||
if (txt.size()%8!=0)
|
||||
throw cannot_encrypt("text size must be a multiple of eight");
|
||||
DES_key_schedule ks1, ks2;
|
||||
DES_set_key_unchecked(key1, &ks1);
|
||||
DES_set_key_unchecked(key2, &ks2);
|
||||
for (std::string::size_type pos(0); pos<txt.size(); pos+=8) {
|
||||
CBlock8 out, in(txt.substr(pos, 8));
|
||||
DES_ecb2_encrypt(in, out, &ks1, &ks2, DES_ENCRYPT);
|
||||
res+=out;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//! @todo untested
|
||||
inline std::string des2ecbDec(std::string txt,
|
||||
CBlock8 key1, CBlock8 key2) {
|
||||
std::string res;
|
||||
if (txt.size()%8!=0)
|
||||
throw cannot_encrypt("text size must be a multiple of eight");
|
||||
DES_key_schedule ks1, ks2;
|
||||
DES_set_key_unchecked(key1, &ks1);
|
||||
DES_set_key_unchecked(key2, &ks2);
|
||||
for (std::string::size_type pos(0); pos<txt.size(); pos+=8) {
|
||||
CBlock8 out, in(txt.substr(pos, 8));
|
||||
DES_ecb2_encrypt(in, out, &ks1, &ks2, DES_DECRYPT);
|
||||
res+=out;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
class X509 {
|
||||
public:
|
||||
|
34
src/pcsc.hxx
34
src/pcsc.hxx
@@ -10,6 +10,25 @@
|
||||
#ifndef PCSC_HXX
|
||||
#define PCSC_HXX
|
||||
|
||||
#ifndef PCSC_LOG
|
||||
//! Declare PCSC_LOG before #include in your code, if you want logging.
|
||||
/*! PCSC_LOG passes its argument to a stream, so your definition must
|
||||
behave so that the argument can be streamed.
|
||||
|
||||
Example, use std::log:
|
||||
@code
|
||||
#define PCSC_LOG(x) std::clog<<x<<" ("<<__PRETTY_FUNCTION__<<')'<<std::endl
|
||||
#include <pcsc.hxx>
|
||||
@endcode
|
||||
|
||||
Example, use qDebug():
|
||||
@code
|
||||
#define PCSC_LOG(x) qDebug()<<x
|
||||
#include <pcsc.hxx>
|
||||
@endcode */
|
||||
#define PCSC_LOG(x) // if unset, do nothing
|
||||
#endif
|
||||
|
||||
#include <cryptaux.hxx>
|
||||
|
||||
#include <string>
|
||||
@@ -221,6 +240,19 @@ namespace pcsc {
|
||||
return transmit(claInsP1P2, lc, le);
|
||||
}
|
||||
|
||||
//! Transmit data to reader.
|
||||
/*! @note Take care: Stings may contain embedded @c 0. */
|
||||
std::string transmit(char cla, char ins, char p1, char p2,
|
||||
unsigned char le) {
|
||||
std::string claInsP1P2;
|
||||
claInsP1P2.push_back(cla);
|
||||
claInsP1P2.push_back(ins);
|
||||
claInsP1P2.push_back(p1);
|
||||
claInsP1P2.push_back(p2);
|
||||
assert(claInsP1P2.size()==4);
|
||||
return transmit(claInsP1P2, std::string(), le);
|
||||
}
|
||||
|
||||
//! Transmit data to reader.
|
||||
/*! @note Take care: Stings may contain embedded @c 0. */
|
||||
std::string transmit(char cla, char ins, char p1, char p2,
|
||||
@@ -262,10 +294,12 @@ namespace pcsc {
|
||||
SCARD_IO_REQUEST rPci;
|
||||
rPci.dwProtocol = pci()->dwProtocol;
|
||||
rPci.cbPciLength = sizeof(rPci);
|
||||
PCSC_LOG("SCardTransmit: "<<crypto::hex(in));
|
||||
check(SCardTransmit(_id, &rPci,
|
||||
(unsigned char*)in.c_str(), in.size(),
|
||||
0, buff, &len),
|
||||
"smartcard transmit message "+crypto::hex(in));
|
||||
PCSC_LOG(" -> "<<crypto::hex(std::string((char*)buff, len)));
|
||||
return std::string((char*)buff, len);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user