better logging in PCSC and first engine release; refs #11
This commit is contained in:
@@ -3,7 +3,8 @@
|
|||||||
## 1 2 3 4 5 6 7 8
|
## 1 2 3 4 5 6 7 8
|
||||||
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
|
|
||||||
noinst_PROGRAMS = pcsc-demo cryptoki-demo openssl-tcp-demo openssl-ssl-demo
|
noinst_PROGRAMS = pcsc-demo cryptoki-demo openssl-tcp-demo \
|
||||||
|
openssl-ssl-demo openssl-engine-demo
|
||||||
|
|
||||||
AM_CPPFLAGS = -I${top_srcdir}/src
|
AM_CPPFLAGS = -I${top_srcdir}/src
|
||||||
if !MINGW32
|
if !MINGW32
|
||||||
@@ -56,4 +57,11 @@ if MINGW32
|
|||||||
openssl_ssl_demo_LDADD += /opt/local/i586-mingw32msvc/lib/ssleay32.a /opt/local/i586-mingw32msvc/lib/libeay32.a
|
openssl_ssl_demo_LDADD += /opt/local/i586-mingw32msvc/lib/ssleay32.a /opt/local/i586-mingw32msvc/lib/libeay32.a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
openssl_engine_demo_SOURCES = openssl-engine-demo.cxx
|
||||||
|
openssl_engine_demo_LDFLAGS = -L${top_builddir}/src
|
||||||
|
openssl_engine_demo_LDADD = -lcryptoki++
|
||||||
|
if MINGW32
|
||||||
|
openssl_engine_demo_LDADD += /opt/local/i586-mingw32msvc/lib/ssleay32.a /opt/local/i586-mingw32msvc/lib/libeay32.a
|
||||||
|
endif
|
||||||
|
|
||||||
MAINTAINERCLEANFILES = makefile.in
|
MAINTAINERCLEANFILES = makefile.in
|
||||||
|
@@ -177,7 +177,8 @@ namespace cryptoki {
|
|||||||
check(_fn->C_Initialize(0), //! @todo add optional argument
|
check(_fn->C_Initialize(0), //! @todo add optional argument
|
||||||
CRYPTOKI_FN_LOG("C_Initialize"));
|
CRYPTOKI_FN_LOG("C_Initialize"));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
throw access_error(CRYPTOKI_FN_LOG("C_Initialize")+": Error in library");
|
throw access_error(CRYPTOKI_FN_LOG("C_Initialize")
|
||||||
|
+": Error in initialization of library "+library);
|
||||||
}
|
}
|
||||||
|
|
||||||
Init::operator bool() {
|
Init::operator bool() {
|
||||||
|
@@ -5,7 +5,8 @@
|
|||||||
## 1 2 3 4 5 6 7 8
|
## 1 2 3 4 5 6 7 8
|
||||||
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
|
|
||||||
include_HEADERS = pcsc.hxx cryptoki.hxx openssl.hxx cryptaux.hxx
|
include_HEADERS = pcsc.hxx cryptoki.hxx openssl.hxx cryptaux.hxx \
|
||||||
|
openssl-engine.hxx
|
||||||
|
|
||||||
if !MINGW32
|
if !MINGW32
|
||||||
if MAC
|
if MAC
|
||||||
@@ -28,7 +29,8 @@ EXTRA_DIST = $(pkgconfig_DATA).in $(shell ls -1 *.doc)
|
|||||||
|
|
||||||
lib_LTLIBRARIES = libcryptoki++.la
|
lib_LTLIBRARIES = libcryptoki++.la
|
||||||
|
|
||||||
libcryptoki___la_SOURCES = cryptoki.cxx cryptoki.hxx pcsc.cxx version.cxx
|
libcryptoki___la_SOURCES = cryptoki.cxx cryptoki.hxx pcsc.cxx \
|
||||||
|
version.cxx openssl-engine.cxx
|
||||||
libcryptoki___la_LIBADD =
|
libcryptoki___la_LIBADD =
|
||||||
if !MINGW32
|
if !MINGW32
|
||||||
if !MAC
|
if !MAC
|
||||||
|
11
src/openssl-engine.cxx
Normal file
11
src/openssl-engine.cxx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/*! @file
|
||||||
|
|
||||||
|
@id $Id$
|
||||||
|
*/
|
||||||
|
// 1 2 3 4 5 6 7 8
|
||||||
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
|
|
||||||
|
#include <openssl-engine.hxx>
|
||||||
|
|
||||||
|
std::map<ENGINE*, openssl::Engine*> openssl::EngineMapper::_map;
|
||||||
|
std::map<std::string, openssl::Engine*> openssl::EngineMapper::_prototypes;
|
272
src/openssl-engine.hxx
Normal file
272
src/openssl-engine.hxx
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
/*! @file
|
||||||
|
|
||||||
|
@id $Id$
|
||||||
|
*/
|
||||||
|
// 1 2 3 4 5 6 7 8
|
||||||
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
|
|
||||||
|
#ifndef __OPENSSL_ENGINE_HXX__
|
||||||
|
#define __OPENSSL_ENGINE_HXX__
|
||||||
|
#include <openssl/opensslv.h>
|
||||||
|
#ifndef OPENSSL_VERSION_NUMBER
|
||||||
|
# error OpenSSL Version Number not Found
|
||||||
|
#elif OPENSSL_VERSION_NUMBER < 0x10000000L
|
||||||
|
# define OPENSSL_0
|
||||||
|
# define OPENSSL_V0_CONST
|
||||||
|
#else
|
||||||
|
# define OPENSSL_1
|
||||||
|
# define OPENSSL_V0_CONST const
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifndef OPENSSL_CHECK
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <sstream>
|
||||||
|
#if __GNUC__ >= 2
|
||||||
|
//! Macro for internal OpenSSL checks.
|
||||||
|
/*! You can define a different implementation in your compile call */
|
||||||
|
#define OPENSSL_CHECK(X) if (!X) {ERR_load_ENGINE_strings(); std::stringstream ss; for (unsigned int err(0); err=ERR_get_error();) ss<<"Error: "<<ERR_error_string(err, 0)<<"; "; ss<<"Command "<<#X<<" failed in function "<<__PRETTY_FUNCTION__<<" in file "<<__FILE__<<":"<<__LINE__; throw std::runtime_error(ss.str());}
|
||||||
|
#else
|
||||||
|
#define OPENSSL_CHECK(X) if (!X) {ERR_load_ENGINE_strings(); std::stringstream ss; for (unsigned int err(0); err=ERR_get_error();) ss<<"Error: "<<ERR_error_string(err, 0)<<"; "; ss<<"Command "<<#X<<" failed in file "<<__FILE__<<":"<<__LINE__; throw std::runtime_error(ss.str());}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef OPENSSL_LOG
|
||||||
|
#include <iostream>
|
||||||
|
#if __GNUC__ >= 2
|
||||||
|
//! Openssl Logging
|
||||||
|
/*! If you want to change openssl logging mechanism, just
|
||||||
|
redefine your own OPENSSL_LOG macro before <code>#include
|
||||||
|
<openssl.hxx></code>. Define it empty for no logging at
|
||||||
|
all. By default logs to <code>std::clog</code>. */
|
||||||
|
#define OPENSSL_LOG(X) std::clog<<X<<" @ "<<__PRETTY_FUNCTION__<<std::endl
|
||||||
|
#else
|
||||||
|
//! Openssl Logging
|
||||||
|
/*! If you want to change openssl logging mechanism, just
|
||||||
|
redefine your own OPENSSL_LOG macro before <code>#include
|
||||||
|
<openssl.hxx></code>. Define it empty for no logging at
|
||||||
|
all. By default logs to <code>std::clog</code>. */
|
||||||
|
#define OPENSSL_LOG(X) std::clog<<X<<" @ "<<__FILE__<<__LINE__<<std::endl
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! @addtogroup gopenssl
|
||||||
|
//@{
|
||||||
|
//! @defgroup opensslengine OpenSSL Engine C++ Wrapper
|
||||||
|
//@}
|
||||||
|
|
||||||
|
namespace openssl {
|
||||||
|
|
||||||
|
//! @addtogroup opensslengine
|
||||||
|
//@{
|
||||||
|
|
||||||
|
//! Abstract Engine Base
|
||||||
|
/*! Inherit and overwrite to implement your own Engine.
|
||||||
|
|
||||||
|
Then in the scope where you need it, register your engine:
|
||||||
|
<code>
|
||||||
|
openssl::RegisterEngine myEngine(new MyEngine);
|
||||||
|
</code> */
|
||||||
|
class Engine {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Engine(): _e(ENGINE_new()) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
}
|
||||||
|
virtual ~Engine() {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
OPENSSL_CHECK(ENGINE_free(_e));
|
||||||
|
}
|
||||||
|
virtual const char* id() = 0;
|
||||||
|
virtual const char* name() = 0;
|
||||||
|
virtual int init() {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
virtual int finish() {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
virtual int ctrl(int, long, void*, void(*)()) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
virtual int cmd() {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
virtual EVP_PKEY* pubkey(const char*, UI_METHOD*, void*) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
virtual EVP_PKEY* privkey(const char*, UI_METHOD*, void*) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
virtual int rsaEncrypt() {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
virtual int rsaDecrypt() {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
virtual int rsaSign() {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
virtual int rsaVerify() {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
virtual int rsaFinish() {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
friend class EngineMapper;
|
||||||
|
ENGINE* _e;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class EngineMapper {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static int add(Engine *e) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
_prototypes[e->id()] = e;
|
||||||
|
_map[e->_e] = e;
|
||||||
|
OPENSSL_CHECK(ENGINE_set_id(e->_e, e->id()));
|
||||||
|
OPENSSL_CHECK(ENGINE_set_name(e->_e, e->name()));
|
||||||
|
OPENSSL_CHECK(ENGINE_set_destroy_function(e->_e, EngineMapper::destroy));
|
||||||
|
OPENSSL_CHECK(ENGINE_set_init_function(e->_e, EngineMapper::init));
|
||||||
|
OPENSSL_CHECK(ENGINE_set_finish_function(e->_e, EngineMapper::finish));
|
||||||
|
OPENSSL_CHECK(ENGINE_set_ctrl_function(e->_e, EngineMapper::ctrl));
|
||||||
|
//OPENSSL_CHECK(ENGINE_set_cmd_defns(e->_e, EngineMapper::cmd));
|
||||||
|
#ifndef OPENSSL_NO_RSA
|
||||||
|
OPENSSL_CHECK(ENGINE_set_RSA(e->_e, rsa()));
|
||||||
|
#endif
|
||||||
|
#ifndef OPENSSL_NO_DSA
|
||||||
|
// OPENSSL_CHECK(ENGINE_set_DSA(e->_e, DSA_get_default_method()));
|
||||||
|
#endif
|
||||||
|
#ifndef OPENSSL_NO_DH
|
||||||
|
// OPENSSL_CHECK(ENGINE_set_DH(e->_e, DSA_get_default_method()));
|
||||||
|
#endif
|
||||||
|
// OPENSSL_CHECK(ENGINE_set_RAND(e->_e, rand()));
|
||||||
|
OPENSSL_CHECK(ENGINE_set_load_pubkey_function(e->_e, pubkey));
|
||||||
|
OPENSSL_CHECK(ENGINE_set_load_privkey_function(e->_e, privkey));
|
||||||
|
OPENSSL_CHECK(ENGINE_init(e->_e));
|
||||||
|
OPENSSL_CHECK(ENGINE_add(e->_e));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove(Engine *e) {
|
||||||
|
OPENSSL_CHECK(ENGINE_remove(e->_e));
|
||||||
|
OPENSSL_CHECK(ENGINE_finish(e->_e));
|
||||||
|
_map.erase(e->_e);
|
||||||
|
delete e;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static int destroy(ENGINE* e) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int init(ENGINE* e) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return _map[e]->init();
|
||||||
|
}
|
||||||
|
static int finish(ENGINE* e) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return _map[e]->finish();
|
||||||
|
}
|
||||||
|
static int ctrl(ENGINE* e, int cmd, long i, void* p, void(*f)()) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return _map[e]->ctrl(cmd, i, p, f);
|
||||||
|
}
|
||||||
|
static EVP_PKEY* pubkey(ENGINE* e, const char* c, UI_METHOD* u, void* d) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return _map[e]->pubkey(c, u, d);
|
||||||
|
}
|
||||||
|
static EVP_PKEY* privkey(ENGINE* e, const char* c, UI_METHOD* u, void* d) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return _map[e]->privkey(c, u, d);
|
||||||
|
}
|
||||||
|
static int rsaEncrypt(int flen,const unsigned char *from,
|
||||||
|
unsigned char *to,
|
||||||
|
RSA *rsa, int padding) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return _map[rsa->engine]->rsaEncrypt();
|
||||||
|
}
|
||||||
|
static int rsaDecrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return _map[rsa->engine]->rsaDecrypt();
|
||||||
|
}
|
||||||
|
static int rsaSign(int flen, const unsigned char *from,
|
||||||
|
unsigned int,
|
||||||
|
unsigned char *to,
|
||||||
|
unsigned int*,
|
||||||
|
const RSA *rsa) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return _map[rsa->engine]->rsaSign();
|
||||||
|
}
|
||||||
|
static int rsaVerify(int, const unsigned char*,
|
||||||
|
unsigned int, OPENSSL_V0_CONST unsigned char*,
|
||||||
|
unsigned int, const RSA* rsa) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return _map[rsa->engine]->rsaVerify();
|
||||||
|
}
|
||||||
|
static int rsaFinish(RSA *rsa) {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
return _map[rsa->engine]->rsaFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static RSA_METHOD* rsa() {
|
||||||
|
OPENSSL_LOG("log");
|
||||||
|
static RSA_METHOD ops;
|
||||||
|
if (!ops.rsa_priv_enc) {
|
||||||
|
ops = *RSA_get_default_method();
|
||||||
|
ops.rsa_pub_enc = rsaEncrypt;
|
||||||
|
ops.rsa_priv_dec = rsaDecrypt;
|
||||||
|
// a.k.a Verify/Sign. actLibrary just allows the proper functions
|
||||||
|
// and has this 'backdoor' closed. Breaks 'rsautl', sadly.
|
||||||
|
ops.rsa_pub_dec = NULL;
|
||||||
|
ops.rsa_priv_enc = NULL;
|
||||||
|
ops.rsa_sign = rsaSign;
|
||||||
|
ops.rsa_verify = rsaVerify;
|
||||||
|
ops.finish = rsaFinish;
|
||||||
|
}
|
||||||
|
return &ops;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static std::map<ENGINE*, Engine*> _map;
|
||||||
|
static std::map<std::string, Engine*> _prototypes;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Scoped Engine Registry
|
||||||
|
/*! Engine will be deregistered and freed at destruction */
|
||||||
|
class RegisterEngine {
|
||||||
|
public:
|
||||||
|
RegisterEngine(Engine* e): _e(e) {
|
||||||
|
EngineMapper::add(_e);
|
||||||
|
}
|
||||||
|
~RegisterEngine() {
|
||||||
|
EngineMapper::remove(_e);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Engine* _e;
|
||||||
|
};
|
||||||
|
|
||||||
|
//@}
|
||||||
|
}
|
||||||
|
#endif
|
@@ -314,12 +314,12 @@ namespace pcsc {
|
|||||||
SCARD_IO_REQUEST rPci;
|
SCARD_IO_REQUEST rPci;
|
||||||
rPci.dwProtocol = pci()->dwProtocol;
|
rPci.dwProtocol = pci()->dwProtocol;
|
||||||
rPci.cbPciLength = sizeof(rPci);
|
rPci.cbPciLength = sizeof(rPci);
|
||||||
PCSC_LOG("SCardTransmit: "<<crypto::hex(in));
|
//PCSC_LOG("SCardTransmit: "<<crypto::hex(in));
|
||||||
check(SCardTransmit(_id, &rPci,
|
check(SCardTransmit(_id, &rPci,
|
||||||
(unsigned char*)in.c_str(), in.size(),
|
(unsigned char*)in.c_str(), in.size(),
|
||||||
0, buff, &len),
|
0, buff, &len),
|
||||||
"smartcard transmit message "+crypto::hex(in));
|
"smartcard transmit message "+crypto::hex(in));
|
||||||
PCSC_LOG(" -> "<<crypto::hex(std::string((char*)buff, len)));
|
//PCSC_LOG(" -> "<<crypto::hex(std::string((char*)buff, len)));
|
||||||
return std::string((char*)buff, len);
|
return std::string((char*)buff, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,11 +484,15 @@ namespace pcsc {
|
|||||||
&num),
|
&num),
|
||||||
"smartcard get size of readers of groups "+grp))
|
"smartcard get size of readers of groups "+grp))
|
||||||
return res;
|
return res;
|
||||||
|
PCSC_LOG("size of readers: "<<num);
|
||||||
std::auto_ptr<char_t> nm(new char_t[num]);
|
std::auto_ptr<char_t> nm(new char_t[num]);
|
||||||
if (!check(SCardListReaders(_id, groups.size()?strconv(grp).data():0,
|
if (!check(SCardListReaders(_id, groups.size()?strconv(grp).data():0,
|
||||||
nm.get(), &num),
|
nm.get(), &num),
|
||||||
"smartcard list reader names of groups "+grp))
|
"smartcard list reader names of groups "+grp))
|
||||||
return res;
|
return res;
|
||||||
|
PCSC_LOG("got all readers, size is "<<num);
|
||||||
|
PCSC_LOG("list of readers: "
|
||||||
|
<<crypto::readable(std::string(nm.get(), num-1)));
|
||||||
return res = split(strconv(string(nm.get(), num-1)));
|
return res = split(strconv(string(nm.get(), num-1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user