compiles for windoze

master
Marc Wäckerlin 15 years ago
parent 7840897598
commit 6f1bd2ae87
  1. 23
      configure.in
  2. 18
      doc/examples/makefile.am
  3. 21
      install-64-and-32-bit-linux.sh
  4. 26
      src/cryptoki.cxx
  5. 315
      src/cryptoki.hxx
  6. 4
      src/makefile.am
  7. 11
      src/pcsc.hxx
  8. 2
      test/makefile.am

@ -71,17 +71,11 @@ AC_ARG_ENABLE(dot,
test "$enableval" = "yes" && HAVE_DOT="YES" || HAVE_DOT="NO"; test "$enableval" = "yes" && HAVE_DOT="YES" || HAVE_DOT="NO";
AM_PATH_CPPUNIT([1.0.0], [have_cppunit="yes"], [have_cppunit="no"]) AM_PATH_CPPUNIT([1.0.0], [have_cppunit="yes"], [have_cppunit="no"])
# Special Options case $host_os in
AC_ARG_ENABLE(win, *mingw32*) MINGW32=yes;;
[AS_HELP_STRING([--enable-win], *) MINGW32=no;;
[on linux, also builds windows version using mingw])], esac
[build_win="$enableval"], [build_win="no"]) AM_CONDITIONAL(MINGW32, test "$MINGW32" = "yes")
AM_CONDITIONAL(BUILD_WIN, test "$build_win" = "yes")
AC_ARG_ENABLE(32bit-linux,
[AS_HELP_STRING([--enable-32bit-linux],
[build for 32bit linux instead of plattform specific])],
[build_lin32="$enableval"], [build_lin32="no"])
AM_CONDITIONAL(BUILD_LIN32, test "$build_lin32" = "yes")
# export macros # export macros
SRCDIR=${srcdir} SRCDIR=${srcdir}
@ -118,10 +112,3 @@ AC_MSG_NOTICE([Pedantic compile mode enabled!
- all warnings for GNU g++ are enabled - all warnings for GNU g++ are enabled
- all warnings result in an error - all warnings result in an error
- doxygen warnings are treated as error too]); fi - doxygen warnings are treated as error too]); fi
if test "$build_win" == "yes"; then
AC_MSG_NOTICE([Will cross-compile for windows
Requires:
- mingw32, mingw32-binutils, mingw32-runtime
- i586-mingw32msvc-g++, i586-mingw32msvc-ar,
i586-mingw32msvc-windres, i586-mingw32msvc-strip
- Boost for MinGW in ~/.wine/drive_c/Programme/Boost-1.34.1]); fi

@ -5,14 +5,26 @@
noinst_PROGRAMS = pcsc-demo cryptoki-demo noinst_PROGRAMS = pcsc-demo cryptoki-demo
AM_CXXFLAGS = -I${top_srcdir}/src \ AM_CPPFLAGS = -I${top_srcdir}/src
-I/usr/include/PCSC if !MINGW32
AM_CPPFLAGS += -I/usr/include/PCSC
endif
pcsc_demo_SOURCES = pcsc-demo.cxx pcsc_demo_SOURCES = pcsc-demo.cxx
if MINGW32
pcsc_demo_LDFLAGS = -L.
pcsc_demo_LDADD = winscard.a
else
pcsc_demo_LDADD = -lpcsclite pcsc_demo_LDADD = -lpcsclite
endif
cryptoki_demo_SOURCES = cryptoki-demo.cxx cryptoki_demo_SOURCES = cryptoki-demo.cxx
cryptoki_demo_LDADD = -ldl -lpthread -lssl -lcryptoki++ cryptoki_demo_LDADD = -lcryptoki++
cryptoki_demo_LDFLAGS = -L${top_builddir}/src cryptoki_demo_LDFLAGS = -L${top_builddir}/src
if MINGW32
cryptoki_demo_LDADD += -leay32
else
cryptoki_demo_LDADD += -ldl -lpthread -lssl
endif
MAINTAINERCLEANFILES = makefile.in MAINTAINERCLEANFILES = makefile.in

@ -0,0 +1,21 @@
./bootstrap.sh && \
LDFLAGS="-L/usr/lib32 -m32" CXXFLAGS="-m32" ./configure \
--libdir=/usr/local/lib32 \
--build=x86_64 \
--host=i386 && \
make && \
sudo make install && \
make clean && \
LDFLAGS="-L/opt/local/i586-mingw32msvc/lib" \
CPPFLAGS="-I/opt/local/i586-mingw32msvc/include" \
./configure \
--prefix=/opt/local/i586-mingw32msvc \
--build=x86_64 \
--host=i586-mingw32msvc && \
make && \
sudo make install && \
make clean && \
./configure && \
make check && \
sudo make install

@ -9,27 +9,29 @@
#include <sstream> #include <sstream>
#include <memory> #include <memory>
#ifndef WIN32
#include <dlfcn.h> #include <dlfcn.h>
#else
#include <iostream> #include <windows.h>
#define CRYPTOKI_LOG(X) std::clog<<"... "<<X<<" in "<<__PRETTY_FUNCTION__<<std::endl; #undef ERROR
#endif
namespace cryptoki { namespace cryptoki {
#ifndef CRYPTOKI_FN_LOG
#if __GNUC__ >= 2
#define CRYPTOKI_FN_LOG(X) (std::string(X " failed in ") \
+std::string(__PRETTY_FUNCTION__))
#else
#define CRYPTOKI_FN_LOG(X) X " failed"
#endif
#endif
bool Init::functionList(const std::string& library) { bool Init::functionList(const std::string& library) {
#ifndef WIN32
void* lib(dlopen(library.c_str(), RTLD_NOW)); void* lib(dlopen(library.c_str(), RTLD_NOW));
#else
HMODULE lib(LoadLibrary(library.c_str()));
#endif
if (!lib) throw exception("open of library failed: "+library); if (!lib) throw exception("open of library failed: "+library);
#ifndef WIN32
CK_RV(*fn)(CK_FUNCTION_LIST**) CK_RV(*fn)(CK_FUNCTION_LIST**)
((CK_RV(*)(CK_FUNCTION_LIST**))dlsym(lib, "C_GetFunctionList")); ((CK_RV(*)(CK_FUNCTION_LIST**))dlsym(lib, "C_GetFunctionList"));
#else
CK_RV(*fn)(CK_FUNCTION_LIST**)
((CK_RV(*)(CK_FUNCTION_LIST**))GetProcAddress(lib, "C_GetFunctionList"));
#endif
if (!fn) if (!fn)
throw exception("required library symbol C_GetFunctionList not found in " throw exception("required library symbol C_GetFunctionList not found in "
+library); +library);

@ -24,14 +24,53 @@
#include <memory> #include <memory>
#include <cryptaux.hxx> #include <cryptaux.hxx>
#include <iostream> // debug
/*! @defgroup gcryptoki C++ Wrapper around Cryptoki API */ /*! @defgroup gcryptoki C++ Wrapper around Cryptoki API */
//@{ //@{
/*! @defgroup cryptokilib Cryptoki C++ Library */ /*! @defgroup cryptokilib Cryptoki C++ Library */
/*! @defgroup globaloperator Global Operator */
/*! @defgroup cryptokitypes Cryptoki C++ Types and Auxiliary */ /*! @defgroup cryptokitypes Cryptoki C++ Types and Auxiliary */
/*! @defgroup cryptokiexceptions Cryptoki Exceptions */ /*! @defgroup cryptokiexceptions Cryptoki Exceptions */
#ifndef CRYPTOKI_FN_LOG
#include <iostream>
#if __GNUC__ >= 2
//! Cryptoki Error Message Formatting
/*! If you want to change cryptoki error formatting, just
redefine your own CRYPTOKY_FN_LOG macro before <code>#include
&lt;cryptoki.hxx&gt;</code>.
#return std::String */
#define CRYPTOKI_FN_LOG(X) (std::string(X " failed in ") \
+std::string(__PRETTY_FUNCTION__))
#else
#define CRYPTOKI_QUOTE(X) #X
//! Cryptoki Error Message Formatting
/*! If you want to change cryptoki error formatting, just
redefine your own CRYPTOKY_FN_LOG macro before <code>#include
&lt;cryptoki.hxx&gt;</code>.
#return std::String */
#define CRYPTOKI_FN_LOG(X) X " failed in \
" __FILE__ ":" CRYPTOKI_QUOTE(__LINE__)
#endif
#endif
#ifndef CRYPTOKI_LOG
#include <iostream>
#if __GNUC__ >= 2
//! Cryptoki Logging
/*! If you want to change cryptoki logging mechanism, just
redefine your own CRYPTOKY_LOG macro before <code>#include
&lt;cryptoki.hxx&gt;</code>. Define it empty for no logging at
all. By default logs to <code>std::clog</code>. */
#define CRYPTOKI_LOG(X) std::clog<<X<<" @ "<<__PRETTY_FUNCTION__<<std::endl
#else
//! Cryptoki Logging
/*! If you want to change cryptoki logging mechanism, just
redefine your own CRYPTOKY_LOG macro before <code>#include
&lt;cryptoki.hxx&gt;</code>. Define it empty for no logging at
all. By default logs to <code>std::clog</code>. */
#define CRYPTOKI_LOG(X) std::clog<<X<<" @ "<<__FILE__<<__LINE__<<std::endl
#endif
#endif
//! @see gcryptoki //! @see gcryptoki
namespace cryptoki { namespace cryptoki {
@ -148,17 +187,6 @@ namespace cryptoki {
T* _p; T* _p;
}; };
#ifndef CRYPTOKI_FN_LOG
#if __GNUC__ >= 2
#define CRYPTOKI_FN_LOG(X) (std::string(X " failed in ") \
+std::string(__PRETTY_FUNCTION__))
#else
#define CRYPTOKI_FN_LOG(X) X " failed in \
" __FILE__ ":" CRYPTOKI_QUOTE(__LINE__)
#endif
#define UNDEF_CRYPTOKI_FN_LOG
#endif
//! @addtogroup cryptokitypes //! @addtogroup cryptokitypes
//@{ //@{
@ -342,7 +370,7 @@ namespace cryptoki {
default: return crypto::readable(value); default: return crypto::readable(value);
} }
} }
template<typename TYPE> Attribute from(const TYPE& v) { template<typename TYPE> Attribute& from(const TYPE& v) {
value = std::string((char*)&v, sizeof(TYPE)); value = std::string((char*)&v, sizeof(TYPE));
return *this; return *this;
} }
@ -804,6 +832,17 @@ namespace cryptoki {
public: public:
//! Don't use without assignment! For standard containers only!
Slot(): _init(0) {
}
Slot& operator=(const Slot& o) {
_init = o._init;
_slot = o._slot;
_res = o._res;
return *this;
}
/*! @name C Like Error Handling /*! @name C Like Error Handling
You are strongly recommended not to disable exception You are strongly recommended not to disable exception
@ -1052,69 +1091,6 @@ namespace cryptoki {
//! Create a new object. //! Create a new object.
Object create(const AttributeList& attrs); Object create(const AttributeList& attrs);
std::string decrypt(std::string in) {
std::string res;
res.resize(in.size());
CK_ULONG size(res.size()); //! @todo check if size is ok (seems so ...)
//! calls @c C_Decrypt
check(_slot._init->_fn->C_Decrypt
(_session,
(unsigned char*)in.begin().operator->(), in.size(),
(unsigned char*)res.begin().operator->(), &size),
CRYPTOKI_FN_LOG("C_Decrypt"));
res.resize(size);
return res;
}
std::string decryptdigestupdate(std::string in) {
std::string res;
res.resize(in.size());
CK_ULONG size(res.size()); //! @todo check if size is ok
//! calls @c C_DecryptDigestUpdate
check(_slot._init->_fn->C_DecryptDigestUpdate
(_session,
(unsigned char*)in.begin().operator->(), in.size(),
(unsigned char*)res.begin().operator->(), &size),
CRYPTOKI_FN_LOG("C_DecryptDigestUpdate"));
res.resize(size);
return res;
}
bool decryptfinal() {
//! calls @c C_DecryptFinal
return check(_slot._init->_fn->C_DecryptFinal(_session, 0, 0),
CRYPTOKI_FN_LOG("C_DecryptFinal"));
//! @todo does this work?
}
std::string decryptupdate(std::string in) {
std::string res;
res.resize(in.size());
CK_ULONG size(res.size()); //! @todo check if size is ok
//! calls @c C_DecryptUpdate
check(_slot._init->_fn->C_DecryptUpdate
(_session,
(unsigned char*)in.begin().operator->(), in.size(),
(unsigned char*)res.begin().operator->(), &size),
CRYPTOKI_FN_LOG("C_DecryptUpdate"));
res.resize(size);
return res;
}
std::string decryptverifyupdate(std::string in) {
std::string res;
res.resize(in.size());
CK_ULONG size(res.size()); //! @todo check if size is ok
//! calls @c C_DecryptVerifyUpdate
check(_slot._init->_fn->C_DecryptVerifyUpdate
(_session,
(unsigned char*)in.begin().operator->(), in.size(),
(unsigned char*)res.begin().operator->(), &size),
CRYPTOKI_FN_LOG("C_DecryptVerifyUpdate"));
res.resize(size);
return res;
}
std::string digest(std::string in) { std::string digest(std::string in) {
std::string res; std::string res;
res.resize(in.size()); res.resize(in.size());
@ -1170,43 +1146,6 @@ namespace cryptoki {
} }
@endcode */ @endcode */
std::string encrypt(std::string in) {
std::string res;
res.resize(in.size());
CK_ULONG size(res.size()); //! @todo check if size is ok
//! calls @c C_Encrypt
check(_slot._init->_fn->C_Encrypt
(_session,
(unsigned char*)in.begin().operator->(), in.size(),
(unsigned char*)res.begin().operator->(), &size),
CRYPTOKI_FN_LOG("C_Encrypt"));
res.resize(size);
return res;
}
/*! @todo Not implemented:
@code
bool encryptfinal() {
//! calls @c C_EncryptFinal
return check(_slot._init->_fn->C_EncryptFinal(_session, CK_BYTE_PTR, CK_ULONG_PTR),
CRYPTOKI_FN_LOG("C_EncryptFinal"));
}
@endcode */
std::string encryptupdate(std::string in) {
std::string res;
res.resize(in.size());
CK_ULONG size(res.size()); //! @todo check if size is ok
//! calls @c C_EncryptUpdate
check(_slot._init->_fn->C_EncryptUpdate
(_session,
(unsigned char*)in.begin().operator->(), in.size(),
(unsigned char*)res.begin().operator->(), &size),
CRYPTOKI_FN_LOG("C_EncryptUpdate"));
res.resize(size);
return res;
}
/*! @todo Not implemented: /*! @todo Not implemented:
@code @code
bool findobjectsfinal() { bool findobjectsfinal() {
@ -1478,6 +1417,23 @@ namespace cryptoki {
return *this; return *this;
} }
/*! @name Comfortable Access
Use these methods in favour of the Low Level Cryptoki
Functions. They provide a higher level simpler access. */
//@{
std::string decrypt(std::string data, CK_MECHANISM_TYPE type,
std::string param=std::string()) {
CRYPTOKI_LOG("decryptinit");
decryptinit(type, param);
CRYPTOKI_LOG("decrypt");
return decrypt(data);
//! @todo don't call decryptfinal()?
}
//@}
/*! @name C Like Error Handling /*! @name C Like Error Handling
You are strongly recommended not to disable exception You are strongly recommended not to disable exception
@ -1514,17 +1470,89 @@ namespace cryptoki {
} }
@endcode */ @endcode */
//! Call this method on a key object only.
bool decryptinit(CK_MECHANISM_TYPE type, std::string param) { bool decryptinit(CK_MECHANISM_TYPE type, std::string param) {
CK_MECHANISM mech = { CK_MECHANISM mech = {
type, param.begin().operator->(), param.size() type, param.size()?&param[0]:0, param.size()
}; };
CRYPTOKI_LOG("decryptinit: type="<<type<<"; mech=("<<mech.mechanism
<<", "<<mech.pParameter<<", "<<mech.ulParameterLen<<')');
//! calls @c C_DecryptInit //! calls @c C_DecryptInit
return check(_session._slot._init->_fn->C_DecryptInit return check(_session._slot._init->_fn->C_DecryptInit
(_session._session, &mech, _object), (_session._session, &mech, _object),
CRYPTOKI_FN_LOG("C_DecryptInit")); CRYPTOKI_FN_LOG("C_DecryptInit"));
} }
//! requires decryptinit to be called before
std::string decrypt(std::string in) {
std::string res;
CK_ULONG size(0); // two calls, first to get minimum buffer length
CRYPTOKI_LOG("get size");
//! calls @c C_Decrypt
check(_session._slot._init->_fn->C_Decrypt
(_session._session,
(unsigned char*)&in[0], in.size(), 0, &size),
CRYPTOKI_FN_LOG("C_Decrypt"));
CRYPTOKI_LOG("maximum size is "<<size<<"Bytes");
res.resize(size, 0);
check(_session._slot._init->_fn->C_Decrypt
(_session._session,
(unsigned char*)&in[0], in.size(),
(unsigned char*)&res[0], &size),
CRYPTOKI_FN_LOG("C_Decrypt"));
CRYPTOKI_LOG("exact size is "<<size<<"Bytes");
res.resize(size);
return res;
}
std::string decryptdigestupdate(std::string in) {
std::string res;
res.resize(in.size());
CK_ULONG size(res.size()); //! @todo check if size is ok
//! calls @c C_DecryptDigestUpdate
check(_session._slot._init->_fn->C_DecryptDigestUpdate
(_session._session,
(unsigned char*)in.begin().operator->(), in.size(),
(unsigned char*)res.begin().operator->(), &size),
CRYPTOKI_FN_LOG("C_DecryptDigestUpdate"));
res.resize(size);
return res;
}
bool decryptfinal() {
//! calls @c C_DecryptFinal
return check(_session._slot._init->_fn->C_DecryptFinal
(_session._session, 0, 0),
CRYPTOKI_FN_LOG("C_DecryptFinal"));
//! @todo does this work?
}
std::string decryptupdate(std::string in) {
std::string res;
res.resize(in.size());
CK_ULONG size(res.size()); //! @todo check if size is ok
//! calls @c C_DecryptUpdate
check(_session._slot._init->_fn->C_DecryptUpdate
(_session._session,
(unsigned char*)in.begin().operator->(), in.size(),
(unsigned char*)res.begin().operator->(), &size),
CRYPTOKI_FN_LOG("C_DecryptUpdate"));
res.resize(size);
return res;
}
std::string decryptverifyupdate(std::string in) {
std::string res;
res.resize(in.size());
CK_ULONG size(res.size()); //! @todo check if size is ok
//! calls @c C_DecryptVerifyUpdate
check(_session._slot._init->_fn->C_DecryptVerifyUpdate
(_session._session,
(unsigned char*)in.begin().operator->(), in.size(),
(unsigned char*)res.begin().operator->(), &size),
CRYPTOKI_FN_LOG("C_DecryptVerifyUpdate"));
res.resize(size);
return res;
}
/*! @todo Not implemented: /*! @todo Not implemented:
@code @code
@ -1563,6 +1591,42 @@ namespace cryptoki {
} }
@endcode */ @endcode */
std::string encrypt(std::string in) {
std::string res;
res.resize(in.size());
CK_ULONG size(res.size()); //! @todo check if size is ok
//! calls @c C_Encrypt
check(_session._slot._init->_fn->C_Encrypt
(_session._session,
(unsigned char*)in.begin().operator->(), in.size(),
(unsigned char*)res.begin().operator->(), &size),
CRYPTOKI_FN_LOG("C_Encrypt"));
res.resize(size);
return res;
}
/*! @todo Not implemented:
@code
bool encryptfinal() {
//! calls @c C_EncryptFinal
return check(_session._slot._init->_fn->C_EncryptFinal(_session._session, CK_BYTE_PTR, CK_ULONG_PTR),
CRYPTOKI_FN_LOG("C_EncryptFinal"));
}
@endcode */
std::string encryptupdate(std::string in) {
std::string res;
res.resize(in.size());
CK_ULONG size(res.size()); //! @todo check if size is ok
//! calls @c C_EncryptUpdate
check(_session._slot._init->_fn->C_EncryptUpdate
(_session._session,
(unsigned char*)in.begin().operator->(), in.size(),
(unsigned char*)res.begin().operator->(), &size),
CRYPTOKI_FN_LOG("C_EncryptUpdate"));
res.resize(size);
return res;
}
/*! @todo Not implemented: /*! @todo Not implemented:
@code @code
@ -1883,11 +1947,22 @@ namespace cryptoki {
}; };
//@} //@}
#ifdef UNDEF_CRYPTOKI_FN_LOG // cleanup if it was set in here }
#undef CRYPTOKI_FN_LOG
#undef CRYPTOKI_QUOTE
#endif
//! @groupadd globaloperator
//@{
inline cryptoki::AttributeList& operator<<(cryptoki::AttributeList& list,
const cryptoki::Attribute& attr) {
list.push_back(attr);
return list;
}
inline cryptoki::AttributeList operator<<(const cryptoki::AttributeList& list,
const cryptoki::Attribute& attr) {
cryptoki::AttributeList res(list);
res.push_back(attr);
return res;
} }
//@}
//@} //@}
#endif #endif

@ -14,10 +14,6 @@ lib_LTLIBRARIES = libcryptoki++.la
libcryptoki___la_SOURCES = cryptoki.cxx cryptoki.hxx ${pkcs11_HEADERS} libcryptoki___la_SOURCES = cryptoki.cxx cryptoki.hxx ${pkcs11_HEADERS}
libcryptoki___la_LIBADD = -lssl libcryptoki___la_LIBADD = -lssl
if BUILD_WIN
else
endif
clean-local: clean-local:
-rm -r ${QMAKE_TARGET}.app -rm -r ${QMAKE_TARGET}.app

@ -34,12 +34,14 @@
#include <string> #include <string>
#ifdef WIN32 #ifdef WIN32
#undef UNICODE
#include <WinSCard.h> #include <WinSCard.h>
#undef ERROR
#ifndef MAX_ATR_SIZE #ifndef MAX_ATR_SIZE
#define MAX_ATR_SIZE 33 #define MAX_ATR_SIZE 33
#endif #endif
namespace pcsc { namespace pcsc {
//! stupid windows needs std::wstring #ifdef UNICODE
inline std::wstring strconv(std::string s) { inline std::wstring strconv(std::string s) {
return std::wstring(s.begin(), s.end()); return std::wstring(s.begin(), s.end());
} }
@ -48,6 +50,13 @@
} }
typedef wchar_t char_t; typedef wchar_t char_t;
typedef std::wstring string; typedef std::wstring string;
#else
inline const std::string& strconv(const std::string& s) {
return s;
}
typedef char char_t;
typedef std::string string;
#endif
} }
#else #else
#include <PCSC/pcsclite.h> #include <PCSC/pcsclite.h>

@ -13,5 +13,5 @@ TESTS=${check_PROGRAMS}
sharedpointer_test_SOURCES = sharedpointer_test.cxx sharedpointer_test_SOURCES = sharedpointer_test.cxx
sharedpointer_test_LDFLAGS = -lcryptoki++ sharedpointer_test_LDFLAGS = -lcryptoki++
CLEANFILES = CLEANFILES = $(check_PROGRAMS:%=%.xml)
MAINTAINERCLEANFILES = makefile.in MAINTAINERCLEANFILES = makefile.in

Loading…
Cancel
Save