Added all SuisseID Functionality except certificate import from server, which shall remain closed; refs #28
This commit is contained in:
@@ -75,7 +75,7 @@ AC_SUBST_FILE(CHANGE_LOG)
|
|||||||
|
|
||||||
AM_CPPFLAGS="-DPACKAGEVERSION='\"${VERSION}\"' -DPACKAGENAME='\"${PACKAGENAME}\"'"
|
AM_CPPFLAGS="-DPACKAGEVERSION='\"${VERSION}\"' -DPACKAGENAME='\"${PACKAGENAME}\"'"
|
||||||
|
|
||||||
# Get rid of that stupid -O2 -g opions!
|
# Get rid of that stupid -O2 -g options!
|
||||||
CXXFLAGS="${CXXFLAGS:-}"
|
CXXFLAGS="${CXXFLAGS:-}"
|
||||||
|
|
||||||
# languages
|
# languages
|
||||||
@@ -93,6 +93,9 @@ AC_CHECK_PROG(have_doxygen, doxygen, yes, no)
|
|||||||
AC_CHECK_PROG(have_dot, dot, yes, no)
|
AC_CHECK_PROG(have_dot, dot, yes, no)
|
||||||
PKG_PROG_PKG_CONFIG
|
PKG_PROG_PKG_CONFIG
|
||||||
|
|
||||||
|
# libraries
|
||||||
|
#PKG_CHECK_MODULES([QT], [QtNetwork])
|
||||||
|
|
||||||
AC_ARG_ENABLE(pedantic,
|
AC_ARG_ENABLE(pedantic,
|
||||||
[AS_HELP_STRING([--enable-pedantic],
|
[AS_HELP_STRING([--enable-pedantic],
|
||||||
[enable all warnings and checks, abort on warnings])],
|
[enable all warnings and checks, abort on warnings])],
|
||||||
|
14
debian/control
vendored
14
debian/control
vendored
@@ -14,6 +14,20 @@ Description: C++ Wrapper around PCSClite, Cryptoki, OpenSSL
|
|||||||
C++ wrappers around the ugly C-Interfaces of pcsc-lite, cryptoki and
|
C++ wrappers around the ugly C-Interfaces of pcsc-lite, cryptoki and
|
||||||
open-ssl.
|
open-ssl.
|
||||||
.
|
.
|
||||||
|
Development Package
|
||||||
|
.
|
||||||
|
For more details, see: https://dev.marc.waeckerlin.org/projects/libpcscxx
|
||||||
|
|
||||||
|
Package: libpcscxx-dbg
|
||||||
|
Section: debug
|
||||||
|
Architecture: any
|
||||||
|
Depends: libpcscxx (= ${binary:Version})
|
||||||
|
Description: C++ Wrapper around PCSClite, Cryptoki, OpenSSL
|
||||||
|
C++ wrappers around the ugly C-Interfaces of pcsc-lite, cryptoki and
|
||||||
|
open-ssl.
|
||||||
|
.
|
||||||
|
Debugging Symbols
|
||||||
|
.
|
||||||
For more details, see: https://dev.marc.waeckerlin.org/projects/libpcscxx
|
For more details, see: https://dev.marc.waeckerlin.org/projects/libpcscxx
|
||||||
|
|
||||||
Package: libpcscxx
|
Package: libpcscxx
|
||||||
|
4
debian/rules
vendored
4
debian/rules
vendored
@@ -40,7 +40,7 @@ endif
|
|||||||
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
|
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
|
||||||
cp -f /usr/share/misc/config.guess config.guess
|
cp -f /usr/share/misc/config.guess config.guess
|
||||||
endif
|
endif
|
||||||
CPPFLAGS="-DALLOW_SSL_0_8 -std=c++0x" ./configure $(CROSS) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info CFLAGS="$(CFLAGS)"
|
CPPFLAGS="-DALLOW_SSL_0_8 -std=c++0x" CXXFLAGS="-ggdb" LDFLAG="-ggdb" ./configure $(CROSS) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info CFLAGS="$(CFLAGS)"
|
||||||
# does not work: LDFLAGS="-Wl,-z,defs"
|
# does not work: LDFLAGS="-Wl,-z,defs"
|
||||||
|
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ binary-arch: install
|
|||||||
# dh_installinfo
|
# dh_installinfo
|
||||||
# dh_installman
|
# dh_installman
|
||||||
dh_link
|
dh_link
|
||||||
dh_strip
|
dh_strip --dbg-package=libpcscxx-dbg
|
||||||
dh_compress
|
dh_compress
|
||||||
dh_fixperms
|
dh_fixperms
|
||||||
# dh_perl
|
# dh_perl
|
||||||
|
@@ -86,7 +86,7 @@ int main(int argc, char** argv) try {
|
|||||||
std::cout<<"Pin: ";
|
std::cout<<"Pin: ";
|
||||||
std::string pin;
|
std::string pin;
|
||||||
std::cin>>pin;
|
std::cin>>pin;
|
||||||
cryptoki::Session::Login l(session, pin);
|
session.login(pin);
|
||||||
keys = session.find(cryptoki::Attribute(CKA_CLASS)
|
keys = session.find(cryptoki::Attribute(CKA_CLASS)
|
||||||
.from<CK_OBJECT_CLASS>(CKO_PRIVATE_KEY),
|
.from<CK_OBJECT_CLASS>(CKO_PRIVATE_KEY),
|
||||||
id);
|
id);
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
## 1 2 3 4 5 6 7 8
|
## 1 2 3 4 5 6 7 8
|
||||||
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
|
|
||||||
|
noinst_HEADERS = suisse-id-demo.hxx
|
||||||
noinst_PROGRAMS = pcsc-demo cryptoki-sign-demo cryptoki-demo \
|
noinst_PROGRAMS = pcsc-demo cryptoki-sign-demo cryptoki-demo \
|
||||||
openssl-tcp-demo openssl-ssl-demo \
|
openssl-tcp-demo openssl-ssl-demo \
|
||||||
openssl-engine-demo suisse-id-demo cardos-demo
|
openssl-engine-demo suisse-id-demo cardos-demo
|
||||||
@@ -32,7 +33,14 @@ cryptoki_sign_demo_SOURCES = cryptoki-sign-demo.cxx
|
|||||||
openssl_tcp_demo_SOURCES = openssl-tcp-demo.cxx
|
openssl_tcp_demo_SOURCES = openssl-tcp-demo.cxx
|
||||||
openssl_ssl_demo_SOURCES = openssl-ssl-demo.cxx
|
openssl_ssl_demo_SOURCES = openssl-ssl-demo.cxx
|
||||||
openssl_engine_demo_SOURCES = openssl-engine-demo.cxx
|
openssl_engine_demo_SOURCES = openssl-engine-demo.cxx
|
||||||
suisse_id_demo_SOURCES = suisse-id-demo.cxx
|
|
||||||
cardos_demo_SOURCES = cardos-demo.cxx
|
cardos_demo_SOURCES = cardos-demo.cxx
|
||||||
|
suisse_id_demo_SOURCES = suisse-id-demo.cxx
|
||||||
|
# moc_suisse-id-demo.cxx
|
||||||
|
#suisse_id_demo_CXXFLAGS = ${QT_CFLAGS}
|
||||||
|
#suisse_id_demo_LDADD = ${QT_LIBS}
|
||||||
|
|
||||||
|
moc_%.cxx: %.hxx
|
||||||
|
moc -o $@ $<
|
||||||
|
|
||||||
|
CLEANFILES = moc_suisse-id-demo.cxx
|
||||||
MAINTAINERCLEANFILES = makefile.in
|
MAINTAINERCLEANFILES = makefile.in
|
||||||
|
@@ -14,11 +14,11 @@ class TestEngine: virtual public openssl::Engine {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
virtual const char* id() {
|
virtual const char* id() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return "TestEngine_ID";
|
return "TestEngine_ID";
|
||||||
}
|
}
|
||||||
virtual const char* name() {
|
virtual const char* name() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return "TestEngine_NAME";
|
return "TestEngine_NAME";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -5,14 +5,10 @@
|
|||||||
// 1 2 3 4 5 6 7 8
|
// 1 2 3 4 5 6 7 8
|
||||||
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
|
|
||||||
#include <suisseid.hxx>
|
#include <suisse-id-demo.hxx>
|
||||||
|
|
||||||
#include <mrw/args.hxx>
|
#include <mrw/args.hxx>
|
||||||
#include <stdexcept>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
int main(int argc, char** argv) try {
|
int main(int argc, char** argv) try {
|
||||||
|
|
||||||
std::string lib("libcvP11.so");
|
std::string lib("libcvP11.so");
|
||||||
mrw::args::parse(argc, argv,
|
mrw::args::parse(argc, argv,
|
||||||
"Sign a text (optionally several times for performance"
|
"Sign a text (optionally several times for performance"
|
||||||
@@ -23,13 +19,77 @@ int main(int argc, char** argv) try {
|
|||||||
<<mrw::args::param(lib, "lib")));
|
<<mrw::args::param(lib, "lib")));
|
||||||
|
|
||||||
suisseid::Cards cards(suisseid::Scanner(lib).scan());
|
suisseid::Cards cards(suisseid::Scanner(lib).scan());
|
||||||
for (suisseid::Cards::iterator card(cards.begin()); card!=cards.end(); ++card)
|
for (suisseid::Cards::iterator card(cards.begin());
|
||||||
std::cout<<"Found SuisseID:"<<std::endl
|
card!=cards.end(); ++card) {
|
||||||
<<" Reader Name: "<<(*card)->name()<<std::endl
|
std::string choice;
|
||||||
<<" Version: "<<(*card)->version()<<std::endl
|
while (choice!="n") try {
|
||||||
<<" PIN-Length: "<<(*card)->minimalPinLength()
|
std::cout<<"=================================================="<<std::endl
|
||||||
<<" - "<<(*card)->maximalPinLength()<<std::endl;
|
<<"Found SuisseID:"<<std::endl
|
||||||
|
<<" Reader Name: "<<(*card)->name()<<std::endl
|
||||||
|
<<" Version: "<<(*card)->version()<<std::endl
|
||||||
|
<<" PIN-Length: "<<(*card)->minimalPinLength()
|
||||||
|
<<" - "<<(*card)->maximalPinLength()<<std::endl
|
||||||
|
<<" PIN retries:"<<std::endl
|
||||||
|
<<" PKCS#15: "<<(*card)->pkcs15PinRetries()<<std::endl
|
||||||
|
<<" SigG: "<<(*card)->sigGPinRetries()<<std::endl
|
||||||
|
<<" Transport: "<<(*card)->transportPinRetries()<<std::endl
|
||||||
|
<<" PUK: "<<(*card)->pukRetries()<<std::endl;
|
||||||
|
cryptoki::Session session((*card)->slot());
|
||||||
|
cryptoki::Session::Info info(session.getsessioninfo());
|
||||||
|
std::cout<<" Session:"<<std::endl
|
||||||
|
<<" Slot: "<<info.slotID<<std::endl
|
||||||
|
<<" State: "<<session.state(info)<<std::endl
|
||||||
|
<<" Flags: "<<((info.flags|CKF_RW_SESSION)
|
||||||
|
?"read/write":"read only")<<std::endl
|
||||||
|
<<" Device Error: "<<info.ulDeviceError<<std::endl;
|
||||||
|
cryptoki::ObjectList certs
|
||||||
|
(session.find(cryptoki::Attribute(CKA_CLASS)
|
||||||
|
.from<CK_OBJECT_CLASS>(CKO_CERTIFICATE)));
|
||||||
|
std::cout<<" Certificates: "<<certs.size()<<std::endl;
|
||||||
|
std::cout<<"--------------------------------------------------"<<std::endl
|
||||||
|
<<"Your Order Sir:"<<std::endl
|
||||||
|
<<" n: proceed to next card"<<std::endl
|
||||||
|
<<" c: check this card"<<std::endl
|
||||||
|
<<" r: remove all certificates"<<std::endl
|
||||||
|
<<" p: PIN change"<<std::endl
|
||||||
|
<<" i: (re-) import certificates"<<std::endl
|
||||||
|
<<" q: quit"<<std::endl;
|
||||||
|
std::cin>>choice;
|
||||||
|
try {
|
||||||
|
if (choice=="n") { // handled above in the while-loop
|
||||||
|
} else if (choice=="c") {
|
||||||
|
TextualCycle check(*card);
|
||||||
|
if (check.run())
|
||||||
|
std::cout<<"----> SuisseID is fine"<<std::endl;
|
||||||
|
else
|
||||||
|
std::cout<<"****> SuisseID is bad"<<std::endl;
|
||||||
|
} else if (choice=="r") {
|
||||||
|
std::cout<<"Not yet implemented."<<std::endl;
|
||||||
|
} else if (choice=="p") {
|
||||||
|
std::string oldpin, newpin;
|
||||||
|
std::cout<<"Enter Old PIN: ";
|
||||||
|
std::cin>>oldpin;
|
||||||
|
std::cout<<"Enter New PIN: ";
|
||||||
|
std::cin>>newpin;
|
||||||
|
if (oldpin.size() && newpin.size())
|
||||||
|
(*card)->changePins(newpin, oldpin);
|
||||||
|
} else if (choice=="i") {
|
||||||
|
TextualCycle check(*card);
|
||||||
|
check.installCerts(true);
|
||||||
|
} else if (choice=="q") {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
std::cout<<"I beg your pardon, Sir?"<<std::endl;
|
||||||
|
}
|
||||||
|
} catch (const std::exception& x) {
|
||||||
|
std::cerr<<"**** ERROR: "<<x.what()<<std::endl;
|
||||||
|
}
|
||||||
|
} catch (std::exception& x) {
|
||||||
|
std::cerr<<"**** ERROR: "<<x.what()<<std::endl;
|
||||||
|
choice="n"; // proceed
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} catch (std::exception& x) {
|
} catch (std::exception& x) {
|
||||||
std::cerr<<"**** ERROR in "<<*argv<<": "<<x.what()<<std::endl;
|
std::cerr<<"**** ERROR: "<<x.what()<<std::endl;
|
||||||
}
|
}
|
||||||
|
100
doc/examples/suisse-id-demo.hxx
Normal file
100
doc/examples/suisse-id-demo.hxx
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/*! @file
|
||||||
|
|
||||||
|
@id $Id$
|
||||||
|
*/
|
||||||
|
// 1 2 3 4 5 6 7 8
|
||||||
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
|
|
||||||
|
#ifndef SUISSE_ID_DEMO_HXX
|
||||||
|
#define SUISSE_ID_DEMO_HXX
|
||||||
|
|
||||||
|
#include <suisseid.hxx>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
class TextualCycle: public suisseid::StatusCycle {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TextualCycle(mrw::Shared<suisseid::Card> card):
|
||||||
|
StatusCycle(card) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// @name slots
|
||||||
|
//@{
|
||||||
|
|
||||||
|
virtual PinPukChange pinChangeTransportPin() {
|
||||||
|
PinPukChange pinpuk;
|
||||||
|
std::cout<<"Enter Transport PIN: ";
|
||||||
|
std::cin>>pinpuk.oldpin;
|
||||||
|
std::cout<<"Enter New PIN: ";
|
||||||
|
std::cin>>pinpuk.newpin;
|
||||||
|
return pinpuk;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual PinPukChange pinChangePuk() {
|
||||||
|
PinPukChange pinpuk;
|
||||||
|
std::cout<<"Enter PUK to unlock PKCS#15 PIN: ";
|
||||||
|
std::cin>>pinpuk.oldpin;
|
||||||
|
std::cout<<"Enter New PKCS#15 PIN: ";
|
||||||
|
std::cin>>pinpuk.newpin;
|
||||||
|
return pinpuk;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void transportPinLocked() {
|
||||||
|
std::cout<<"Transport PIN is Locked!"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void pkcs15PinLocked() {
|
||||||
|
std::cout<<"PKCS#15 PIN is Locked!"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void sigGPinLocked() {
|
||||||
|
std::cout<<"SigG PIN is Locked!"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void pukLocked() {
|
||||||
|
std::cout<<"PUK is Locked!"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void certsExpireSoon() {
|
||||||
|
std::cout<<"Certificates Expire Soon!"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void certsExpired() {
|
||||||
|
std::cout<<"Certificates Expired!"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void certsRevoked() {
|
||||||
|
std::cout<<"Certificates Revoked!"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// install certificates on the card
|
||||||
|
virtual bool installCerts(bool force = true) {
|
||||||
|
std::cout<<"Installing Certificates ..."<<std::endl;
|
||||||
|
std::string pin;
|
||||||
|
std::cout<<"Enter PIN (x to abort): ";
|
||||||
|
std::cin>>pin;
|
||||||
|
if (pin=="x") {
|
||||||
|
std::cout<<std::endl<<"User aborted"<<std::endl;
|
||||||
|
return false; // user aborts
|
||||||
|
}
|
||||||
|
cryptoki::Session session(card()->slot());
|
||||||
|
try {
|
||||||
|
session.login(pin);
|
||||||
|
} catch (const cryptoki::wrong_pin& x) {
|
||||||
|
std::cout<<"**** Wrong PIN!"<<std::endl;
|
||||||
|
std::cout<<x.what()<<std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::cout<<"**** Not implemented"<<std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
477
src/cardos.hxx
477
src/cardos.hxx
@@ -16,10 +16,9 @@
|
|||||||
|
|
||||||
#ifndef CARDOS_LOG
|
#ifndef CARDOS_LOG
|
||||||
#define CARDOS_LOG(X) // no logging by default
|
#define CARDOS_LOG(X) // no logging by default
|
||||||
// use e.g. #define CARDOS_LOG(X) std::cout<<X<<std::endl
|
// use e.g. #define CARDOS_LOG(X) std::clog<<X<<std::endl
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace cardos {
|
namespace cardos {
|
||||||
|
|
||||||
/// @defgroup gcardos C++ Access to Siemens CardOS V4.4
|
/// @defgroup gcardos C++ Access to Siemens CardOS V4.4
|
||||||
@@ -42,38 +41,40 @@ namespace cardos {
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class wrong_pin: public exception {
|
class wrong_pin: public exception {
|
||||||
public:
|
public:
|
||||||
wrong_pin(const std::string& s) throw(): exception("wrong pin\n"+s) {}
|
wrong_pin(const std::string& s) throw(): exception("wrong pin "+s) {}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class user_pin_locked: public exception {
|
class user_pin_locked: public exception {
|
||||||
public:
|
public:
|
||||||
user_pin_locked(const std::string& s) throw():
|
user_pin_locked(const std::string& s) throw():
|
||||||
exception("user pin locked\n"+s) {}
|
exception("user pin locked "+s) {}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class wrong_puk: public exception {
|
class wrong_puk: public exception {
|
||||||
public:
|
public:
|
||||||
wrong_puk(const std::string& s) throw(): exception("wrong puk\n"+s) {}
|
wrong_puk(const std::string& s) throw(): exception("wrong puk "+s) {}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class wrong_result: public exception {
|
class wrong_result: public exception {
|
||||||
public:
|
public:
|
||||||
wrong_result(const std::string& reason, const std::string& data) throw():
|
wrong_result(const std::string& reason, const std::string& data) throw():
|
||||||
exception("wrong result,\n"+reason+":\n"+crypto::hex(data)) {}
|
exception("wrong result, "+reason+": "+crypto::hex(data)) {}
|
||||||
wrong_result(const std::string& reason) throw():
|
wrong_result(const std::string& reason) throw():
|
||||||
exception("wrong result,\n"+reason) {}
|
exception("wrong result, "+reason) {}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class runtime_error: public exception {
|
class runtime_error: public exception {
|
||||||
public:
|
public:
|
||||||
|
runtime_error(const std::string& reason) throw():
|
||||||
|
exception("runtime error, "+reason) {}
|
||||||
runtime_error(const std::string& reason, const std::string& data) throw():
|
runtime_error(const std::string& reason, const std::string& data) throw():
|
||||||
exception("runtime error,\n"+reason+":\n"+crypto::hex(data)) {}
|
exception("runtime error, "+reason+": "+crypto::hex(data)) {}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class unexpected_challenge_length: public exception {
|
class unexpected_challenge_length: public exception {
|
||||||
public:
|
public:
|
||||||
unexpected_challenge_length(const std::string& data) throw():
|
unexpected_challenge_length(const std::string& data) throw():
|
||||||
exception("challenge should be 8 bytes, challenge is:\n"
|
exception("challenge should be 8 bytes, challenge is: "
|
||||||
+crypto::hex(data)) {}
|
+crypto::hex(data)) {}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -81,8 +82,8 @@ namespace cardos {
|
|||||||
public:
|
public:
|
||||||
card_transmission_failed(const std::string& position,
|
card_transmission_failed(const std::string& position,
|
||||||
const std::string& reason) throw():
|
const std::string& reason) throw():
|
||||||
exception("transmission to card failed:\n"+position
|
exception("transmission to card failed: "+position
|
||||||
+"\nreason:\n"+reason) {
|
+" reason: "+reason) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -90,8 +91,8 @@ namespace cardos {
|
|||||||
public:
|
public:
|
||||||
wrong_dataformat(const std::string& data,
|
wrong_dataformat(const std::string& data,
|
||||||
const std::string& reason) throw():
|
const std::string& reason) throw():
|
||||||
exception("wrong dataformat:\n"+crypto::hex(data)
|
exception("wrong dataformat: "+crypto::hex(data)
|
||||||
+"\nreason:\n"+reason) {
|
+" reason: "+reason) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -111,66 +112,6 @@ namespace cardos {
|
|||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
/// @addtogroup cardostypes
|
|
||||||
//@{
|
|
||||||
|
|
||||||
/// Represents the Smart Card's Tag Length Value Encoded File Format.
|
|
||||||
class TagLengthValue {
|
|
||||||
public:
|
|
||||||
enum Tag {
|
|
||||||
DIRECTORY_ENTRY = 0x6F,
|
|
||||||
FILE_TYPE = 0x82,
|
|
||||||
FILE_IDENTIFIER = 0x86,
|
|
||||||
NEXT_OFFSET = 0x8A,
|
|
||||||
VERSION_INFO_CONTAINER = 0xff,
|
|
||||||
VERSION_INFO_STRING = 0x01
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
/// Initialize from a File's Content
|
|
||||||
TagLengthValue(const std::string& content):
|
|
||||||
_size(0), _content(content) {
|
|
||||||
if (_content.size()<2)
|
|
||||||
throw wrong_dataformat(_content, "not a TLV, too small");
|
|
||||||
for (std::string::size_type pos(0); pos!=_content.size();
|
|
||||||
pos+=_content[pos+1]+2) {
|
|
||||||
++_size;
|
|
||||||
if (pos+2>_content.size())
|
|
||||||
throw wrong_dataformat(_content, "not a TLV, wrong size");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Return RAW File Content
|
|
||||||
std::string raw() {
|
|
||||||
return _content;
|
|
||||||
}
|
|
||||||
TagLengthValue at(unsigned int i) {
|
|
||||||
if (i>=_size) throw array_range(i, _size);
|
|
||||||
std::string::size_type pos(0);
|
|
||||||
for (unsigned int j(0); j!=i; ++j) {
|
|
||||||
pos+=_content[pos+1]+2;
|
|
||||||
}
|
|
||||||
return TagLengthValue(_content.substr(pos, _content[pos+1]+2));
|
|
||||||
}
|
|
||||||
std::string str() {
|
|
||||||
switch ((int)_content[0]) {
|
|
||||||
case VERSION_INFO_STRING:
|
|
||||||
return _content.substr(2, (int)_content[1]);
|
|
||||||
default:
|
|
||||||
throw wrong_dataformat(_content, "not a string");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TagLengthValue tlv() {
|
|
||||||
switch ((int)_content[0]) {
|
|
||||||
case VERSION_INFO_CONTAINER:
|
|
||||||
return TagLengthValue(_content.substr(2, (int)_content[1]));
|
|
||||||
default:
|
|
||||||
throw wrong_dataformat(_content, "not a container");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
unsigned int _size;
|
|
||||||
std::string _content;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BerValue {
|
class BerValue {
|
||||||
public:
|
public:
|
||||||
enum Class {
|
enum Class {
|
||||||
@@ -360,41 +301,6 @@ namespace cardos {
|
|||||||
unsigned char _length;
|
unsigned char _length;
|
||||||
std::string _value;
|
std::string _value;
|
||||||
std::vector<BerValue> _sequence;
|
std::vector<BerValue> _sequence;
|
||||||
|
|
||||||
// BerValue(const std::string& content) {
|
|
||||||
// if (content.size()<2 ||
|
|
||||||
// content.size()<2+(std::string::size_type)content[1])
|
|
||||||
// throw wrong_dataformat(content, "not a BER, value too small");
|
|
||||||
// if (content.size()>2+(std::string::size_type)content[1]) {
|
|
||||||
// _tag = UNIVERSAL|CONSTRUCTED|SEQUENCE;
|
|
||||||
// _length = content.size()-2;
|
|
||||||
// _value = content.substr(2, _length);
|
|
||||||
// for (std::string::size_type pos(0); pos!=content.size();
|
|
||||||
// pos+=content[pos+1]+2) {
|
|
||||||
// if (pos+2>content.size() ||
|
|
||||||
// (std::string::size_type)content[pos+1]+2>content.size())
|
|
||||||
// throw wrong_dataformat(content, "not a BER, wrong size");
|
|
||||||
// _sequence.push_back
|
|
||||||
// (BerValue(content.substr(pos, content[pos+1]+2)));
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// _tag = content[0];
|
|
||||||
// _length = content[1];
|
|
||||||
// _value = content.substr(2, _length);
|
|
||||||
// if (isContainer()) {
|
|
||||||
// for (std::string::size_type pos(2); pos!=content.size();
|
|
||||||
// pos+=content[pos+1]+2) {
|
|
||||||
// if (pos+2>content.size() ||
|
|
||||||
// (std::string::size_type)content[pos+1]+2>content.size())
|
|
||||||
// throw wrong_dataformat(content, "not a BER, wrong size");
|
|
||||||
// _sequence.push_back
|
|
||||||
// (BerValue(content.substr(pos, content[pos+1]+2)));
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// _value = content.substr(2, _length);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -439,11 +345,7 @@ namespace cardos {
|
|||||||
//@{
|
//@{
|
||||||
|
|
||||||
/// Implements CardOS V4.4 commands.
|
/// Implements CardOS V4.4 commands.
|
||||||
/** Directly sends CardOS V4.4 commands to a smart card using APDUs.
|
/** Directly sends CardOS V4.4 commands to a smart card using APDUs. */
|
||||||
|
|
||||||
This class does not do any transaction handling. Please handle
|
|
||||||
transactions on a higher level, when you access these
|
|
||||||
methods. */
|
|
||||||
class Commands {
|
class Commands {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -452,9 +354,9 @@ namespace cardos {
|
|||||||
/// @name Setup Smart Card Reader
|
/// @name Setup Smart Card Reader
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
/// Uninitialized class, use @ref reader to setup assign smart card reader.
|
/// Uninitialized class
|
||||||
Commands() {
|
/** Use @ref reader to setup assign smart card reader. */
|
||||||
}
|
Commands() {}
|
||||||
|
|
||||||
/// Initialize with given smart card reader.
|
/// Initialize with given smart card reader.
|
||||||
Commands(mrw::Shared<pcsc::Connection::Reader> reader):
|
Commands(mrw::Shared<pcsc::Connection::Reader> reader):
|
||||||
@@ -484,6 +386,7 @@ namespace cardos {
|
|||||||
the security status of the current DF. The command
|
the security status of the current DF. The command
|
||||||
cannot be applied to CODE files. */
|
cannot be applied to CODE files. */
|
||||||
void activateFile() {
|
void activateFile() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x00, 0x44, 0x00, 0x00));
|
check(send(0x00, 0x44, 0x00, 0x00));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -532,13 +435,15 @@ namespace cardos {
|
|||||||
|
|
||||||
@see freeTransactionBuffer */
|
@see freeTransactionBuffer */
|
||||||
std::string allocateTransactionBuffer(unsigned short size) {
|
std::string allocateTransactionBuffer(unsigned short size) {
|
||||||
if (size>0x7FFF) throw std::runtime_error("requested buffer too large");
|
CRYPTOLOG("log");
|
||||||
|
if (size>0x7FFF) throw runtime_error("requested buffer too large");
|
||||||
return check(send(0x80, 0x12, 8|size>>8, size&0xFF));
|
return check(send(0x80, 0x12, 8|size>>8, size&0xFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Free transaction buffer
|
//! Free transaction buffer
|
||||||
/*! @see allocateTransactionBuffer */
|
/*! @see allocateTransactionBuffer */
|
||||||
void freeTransactionBuffer(unsigned char id) {
|
void freeTransactionBuffer(unsigned char id) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x80, 0x12, 0x00, id));
|
check(send(0x80, 0x12, 0x00, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -587,6 +492,7 @@ namespace cardos {
|
|||||||
referenced by the file’s AC APPEND is granted in the
|
referenced by the file’s AC APPEND is granted in the
|
||||||
security status of the current DF. */
|
security status of the current DF. */
|
||||||
void appendRecord(unsigned char efId, std::string data) {
|
void appendRecord(unsigned char efId, std::string data) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x00, 0xE2, 0x00, efId, data));
|
check(send(0x00, 0xE2, 0x00, efId, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,12 +560,14 @@ namespace cardos {
|
|||||||
@return Digital Signature */
|
@return Digital Signature */
|
||||||
std::string cardAuthenticate(bool hashInclIdentNum,
|
std::string cardAuthenticate(bool hashInclIdentNum,
|
||||||
std::string systemChallange) {
|
std::string systemChallange) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
return check(send(0x80, 0x88, hashInclIdentNum?0x01:0x02, 0x00,
|
return check(send(0x80, 0x88, hashInclIdentNum?0x01:0x02, 0x00,
|
||||||
systemChallange));
|
systemChallange));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Changes the object data of any BS object except for PIN TEST objects
|
//! Changes the object data of any BS object except for PIN TEST objects
|
||||||
void changeKeyData() {
|
void changeKeyData() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,17 +575,21 @@ namespace cardos {
|
|||||||
/** Changes a PIN. */
|
/** Changes a PIN. */
|
||||||
void changeReferenceData(unsigned char id, std::string newData,
|
void changeReferenceData(unsigned char id, std::string newData,
|
||||||
std::string oldData=std::string()) {
|
std::string oldData=std::string()) {
|
||||||
check(send(0x00, 0x24, oldData.size()?0x00:0x01, id, oldData+newData));
|
CRYPTOLOG("log");
|
||||||
|
check(send(0x00, 0x24, oldData.size()?0x00:0x01, 0x80|id,
|
||||||
|
oldData+newData));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Changes the data of a system key to the new key data
|
//! Changes the data of a system key to the new key data
|
||||||
//! provided with the command.
|
//! provided with the command.
|
||||||
void changeSystemKey() {
|
void changeSystemKey() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Creates a file (only EF or DF)
|
//! Creates a file (only EF or DF)
|
||||||
void createFile(BerValue) {
|
void createFile(BerValue) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
// check(send(0x00, 0xE0, 0x00, 0x00, BerValue(0x62h,
|
// check(send(0x00, 0xE0, 0x00, 0x00, BerValue(0x62h,
|
||||||
// data).raw()));
|
// data).raw()));
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
@@ -685,16 +597,19 @@ namespace cardos {
|
|||||||
|
|
||||||
//! Deactivates a file or a file tree
|
//! Deactivates a file or a file tree
|
||||||
void deactivateFile() {
|
void deactivateFile() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Decreases a record value
|
//! Decreases a record value
|
||||||
void decrease() {
|
void decrease() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Deletes a file (DF or EF)
|
//! Deletes a file (DF or EF)
|
||||||
void deleteFile() {
|
void deleteFile() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -702,21 +617,25 @@ namespace cardos {
|
|||||||
|
|
||||||
//! Reads file information of EFs and/or DFs in the current DF
|
//! Reads file information of EFs and/or DFs in the current DF
|
||||||
BerValue directory(FileTypes types, unsigned char offset=0) {
|
BerValue directory(FileTypes types, unsigned char offset=0) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
return BerValue(check(send(0x80, 0x16, types, offset)));
|
return BerValue(check(send(0x80, 0x16, types, offset)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Enables an already loaded and activated but disabled license package.
|
//! Enables an already loaded and activated but disabled license package.
|
||||||
void enablePackage() {
|
void enablePackage() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Erases the file system in the EEPROM.
|
//! Erases the file system in the EEPROM.
|
||||||
void eraseFiles() {
|
void eraseFiles() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Performs a challenge/response test
|
//! Performs a challenge/response test
|
||||||
void externalAuthenticate() {
|
void externalAuthenticate() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -724,26 +643,31 @@ namespace cardos {
|
|||||||
//! ADMINISTRATION after creation of the MF or changes only from
|
//! ADMINISTRATION after creation of the MF or changes only from
|
||||||
//! MANUFACTURING to INITIALIZATION.
|
//! MANUFACTURING to INITIALIZATION.
|
||||||
void format() {
|
void format() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Generates a key pair for the RSA/RSA2 algorithms within the card
|
//! Generates a key pair for the RSA/RSA2 algorithms within the card
|
||||||
void generateKeyPair() {
|
void generateKeyPair() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Generates an internal random number (i.e. SC_Challenge)
|
//! Generates an internal random number (i.e. SC_Challenge)
|
||||||
void getChallange() {
|
void getChallange() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Reads system information
|
//! Reads system information
|
||||||
std::string getData(unsigned char mode) {
|
std::string getData(unsigned char mode) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
return check(send(0x00, 0xCA, 0x01, mode));
|
return check(send(0x00, 0xCA, 0x01, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Product name, version, release date, copyright string
|
//! Product name, version, release date, copyright string
|
||||||
std::string getDataProductName() {
|
std::string getDataProductName() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
return getData(0x80);
|
return getData(0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -755,6 +679,7 @@ namespace cardos {
|
|||||||
|
|
||||||
//! Chip production data as supplied by Infineon, PROM area
|
//! Chip production data as supplied by Infineon, PROM area
|
||||||
ChipProductionData getDataChipProduction() {
|
ChipProductionData getDataChipProduction() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
std::string code(getData(0x81));
|
std::string code(getData(0x81));
|
||||||
ChipProductionData res = {
|
ChipProductionData res = {
|
||||||
code.substr(8, 8),
|
code.substr(8, 8),
|
||||||
@@ -781,6 +706,7 @@ namespace cardos {
|
|||||||
The external random number is stored in the XRAM of the
|
The external random number is stored in the XRAM of the
|
||||||
smart card. */
|
smart card. */
|
||||||
void giveRandom(std::string random) {
|
void giveRandom(std::string random) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x80, 0x86, 0x00, 0x00, random));
|
check(send(0x80, 0x86, 0x00, 0x00, random));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -793,6 +719,7 @@ namespace cardos {
|
|||||||
- bits 7-3 = ppppp, bits 2-0=0 → use SFI ppppp (11111 not allowed)
|
- bits 7-3 = ppppp, bits 2-0=0 → use SFI ppppp (11111 not allowed)
|
||||||
- other value → rfu */
|
- other value → rfu */
|
||||||
std::string increase(unsigned char efId=0, unsigned short size=1) {
|
std::string increase(unsigned char efId=0, unsigned short size=1) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
std::string data;
|
std::string data;
|
||||||
data.resize(2);
|
data.resize(2);
|
||||||
data[0] = size>>8;
|
data[0] = size>>8;
|
||||||
@@ -803,32 +730,38 @@ namespace cardos {
|
|||||||
|
|
||||||
//! Manufacturer use only
|
//! Manufacturer use only
|
||||||
void initializeEeprom() {
|
void initializeEeprom() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Manufacturer use only
|
//! Manufacturer use only
|
||||||
void initializeEnd() {
|
void initializeEnd() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Performs cryptographic algorithms for authentication
|
//! Performs cryptographic algorithms for authentication
|
||||||
void internalAuthenticate() {
|
void internalAuthenticate() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Activates a package
|
//! Activates a package
|
||||||
void loadExecutable() {
|
void loadExecutable() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Opens or closes a logical channel
|
//! Opens or closes a logical channel
|
||||||
std::string manageChannel(unsigned char mode, unsigned char channelId) {
|
std::string manageChannel(unsigned char mode, unsigned char channelId) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
return check(send(0x00, 0x70, mode, channelId));
|
return check(send(0x00, 0x70, mode, channelId));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Loads a CSE (RESTORE) or sets a component of the CSE (SET)
|
//! Loads a CSE (RESTORE) or sets a component of the CSE (SET)
|
||||||
//! and/or sets an extended headerlist
|
//! and/or sets an extended headerlist
|
||||||
void manageSecureEnvironment() {
|
void manageSecureEnvironment() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -836,21 +769,25 @@ namespace cardos {
|
|||||||
//! MAC/Signature calculation and, depending on the input, a
|
//! MAC/Signature calculation and, depending on the input, a
|
||||||
//! session key derivation.
|
//! session key derivation.
|
||||||
void mutualAuthenticate() {
|
void mutualAuthenticate() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Performs a cryptographic operation
|
//! Performs a cryptographic operation
|
||||||
void performSecurityOperation() {
|
void performSecurityOperation() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Controls the command sequence transactions
|
//! Controls the command sequence transactions
|
||||||
void performTransactonOperation() {
|
void performTransactonOperation() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Personalizer use only
|
//! Personalizer use only
|
||||||
void personalize() {
|
void personalize() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -882,16 +819,19 @@ namespace cardos {
|
|||||||
@prereq The command can be executed in the life cycle phases
|
@prereq The command can be executed in the life cycle phases
|
||||||
ADMINISTRATION and OPERATIONAL. */
|
ADMINISTRATION and OPERATIONAL. */
|
||||||
void phaseControl() {
|
void phaseControl() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x80, 0x10, 0x00, 0x00));
|
check(send(0x80, 0x10, 0x00, 0x00));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Installs / administrates / overwrites different objects
|
//! Installs / administrates / overwrites different objects
|
||||||
void putData() {
|
void putData() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Read a BINARY file
|
//! Read a BINARY file
|
||||||
std::string readBinary(unsigned short offset = 0) {
|
std::string readBinary(unsigned short offset = 0) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
return check(send(0x00, 0xB0, offset>>8, offset&0xFF));
|
return check(send(0x00, 0xB0, offset>>8, offset&0xFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -908,12 +848,15 @@ namespace cardos {
|
|||||||
std::string readRecord(unsigned char record = 0,
|
std::string readRecord(unsigned char record = 0,
|
||||||
unsigned char sfi = 0,
|
unsigned char sfi = 0,
|
||||||
ReadRecordMode mode = ABSOLUTE_RECORD) {
|
ReadRecordMode mode = ABSOLUTE_RECORD) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
return check(send(0x00, 0xB2, record, (sfi&0xF8)|mode));
|
return check(send(0x00, 0xB2, record, (sfi&0xF8)|mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read all records from a record oriented file
|
/// Read all records from a record oriented file
|
||||||
BerValues readBerFile() {
|
BerValues readBerFile() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
BerValues content;
|
BerValues content;
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
while (true) {
|
while (true) {
|
||||||
std::string res(send(0x00, 0xB2, 0, NEXT_RECORD));
|
std::string res(send(0x00, 0xB2, 0, NEXT_RECORD));
|
||||||
if (cardos::Commands::retCode(res)!=0x9000) break;
|
if (cardos::Commands::retCode(res)!=0x9000) break;
|
||||||
@@ -924,11 +867,13 @@ namespace cardos {
|
|||||||
|
|
||||||
//! Resets the error counter of a BS object to its maximum
|
//! Resets the error counter of a BS object to its maximum
|
||||||
void resetRetryCounter() {
|
void resetRetryCounter() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Resets the security status of the current DF
|
//! Resets the security status of the current DF
|
||||||
void resetSecurityCounter() {
|
void resetSecurityCounter() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -954,6 +899,7 @@ namespace cardos {
|
|||||||
= DF_OR_EF_USING_PATH_FROM_MF,
|
= DF_OR_EF_USING_PATH_FROM_MF,
|
||||||
FileSelectionReturn ret
|
FileSelectionReturn ret
|
||||||
= RETURN_NOTHING) {
|
= RETURN_NOTHING) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
return BerValue(check(send(0x00, 0xA4, mode, ret, file)));
|
return BerValue(check(send(0x00, 0xA4, mode, ret, file)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -961,32 +907,38 @@ namespace cardos {
|
|||||||
//! the effective Command Data Field Length / Response Data
|
//! the effective Command Data Field Length / Response Data
|
||||||
//! Field Length.
|
//! Field Length.
|
||||||
void setDataFieldLength() {
|
void setDataFieldLength() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Enables or disables the usage of an existing transaction buffer
|
//! Enables or disables the usage of an existing transaction buffer
|
||||||
void setTransactionState() {
|
void setTransactionState() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Signs a hashed input using a decryption key with the RSA_SIG
|
//! Signs a hashed input using a decryption key with the RSA_SIG
|
||||||
//! algorithm.
|
//! algorithm.
|
||||||
void signByDecryptionKey() {
|
void signByDecryptionKey() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Uninstalls a package of the smart card
|
//! Uninstalls a package of the smart card
|
||||||
void uninstallPackage() {
|
void uninstallPackage() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
assert(!"not implemented");
|
assert(!"not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the previously file from smart card
|
/// Read the previously file from smart card
|
||||||
std::string readBinFile() {
|
std::string readBinFile() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
return check(send(0x00, 0xB0, 0x00, 0x00));
|
return check(send(0x00, 0xB0, 0x00, 0x00));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Updates a BINARY file
|
//! Updates a BINARY file
|
||||||
void updateBinary(std::string data, unsigned short offset=0) {
|
void updateBinary(std::string data, unsigned short offset=0) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x00, 0xD6, offset>>8, offset&0xFF, data));
|
check(send(0x00, 0xD6, offset>>8, offset&0xFF, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -995,6 +947,7 @@ namespace cardos {
|
|||||||
unsigned char record = 0,
|
unsigned char record = 0,
|
||||||
unsigned char sfi = 0,
|
unsigned char sfi = 0,
|
||||||
ReadRecordMode mode = ABSOLUTE_RECORD) {
|
ReadRecordMode mode = ABSOLUTE_RECORD) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
return check(send(0x00, 0xDC, record, (sfi&0xF8)|mode, data));
|
return check(send(0x00, 0xDC, record, (sfi&0xF8)|mode, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1006,12 +959,14 @@ namespace cardos {
|
|||||||
//! Performs a PIN test (CHV test)
|
//! Performs a PIN test (CHV test)
|
||||||
void verify(std::string pin, unsigned char id,
|
void verify(std::string pin, unsigned char id,
|
||||||
VerifyMode mode = SEARCH_FROM_DF) {
|
VerifyMode mode = SEARCH_FROM_DF) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x00, 0x20, 0x00, id|mode, pin));
|
check(send(0x00, 0x20, 0x00, id|mode, pin));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Performs a PIN test (CHV test)
|
//! Performs a PIN test (CHV test)
|
||||||
/*! @return number of remaining PIN retries or -1 if PIN is locked */
|
/*! @return number of remaining PIN retries or -1 if PIN is locked */
|
||||||
int verify(unsigned char id, VerifyMode mode = SEARCH_FROM_DF) {
|
int verify(unsigned char id, VerifyMode mode = SEARCH_FROM_DF) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
std::string res(send(0x00, 0x20, 0x00, id|mode));
|
std::string res(send(0x00, 0x20, 0x00, id|mode));
|
||||||
unsigned int value((((unsigned int)(unsigned char)res[0])*256)
|
unsigned int value((((unsigned int)(unsigned char)res[0])*256)
|
||||||
+((unsigned int)(unsigned char)res[1]));
|
+((unsigned int)(unsigned char)res[1]));
|
||||||
@@ -1036,7 +991,7 @@ namespace cardos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Path to SigG (Signaturgesetz)
|
/// Path to SigG (Signaturgesetz)
|
||||||
std::string sigg() {
|
std::string sigG() {
|
||||||
return crypto::hexToBin("1fff");
|
return crypto::hexToBin("1fff");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1068,24 +1023,32 @@ namespace cardos {
|
|||||||
|
|
||||||
/// Logon with transport PIN
|
/// Logon with transport PIN
|
||||||
void logonTransport(std::string pin) {
|
void logonTransport(std::string pin) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectSigG();
|
selectSigG();
|
||||||
logon(transportPin(), pin);
|
logon(transportPin(), pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Logon with SigG (Signaturgesetz) secure PIN
|
/// Logon with SigG (Signaturgesetz) secure PIN
|
||||||
void logonSigG(std::string pin) {
|
void logonSigG(std::string pin) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectSigG();
|
selectSigG();
|
||||||
logon(sigGPin(), pin);
|
logon(sigGPin(), pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Logon with PKCS#15 user PUK to unlock user PIN
|
/// Logon with PKCS#15 user PUK to unlock user PIN
|
||||||
void logonPuk(std::string pin) {
|
void logonPuk(std::string pin) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectMF();
|
selectMF();
|
||||||
logon(puk(), pin);
|
logon(puk(), pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Logon with PKCS#15 user PIN
|
/// Logon with PKCS#15 user PIN
|
||||||
void logonPkcs15(std::string pin) {
|
void logonPkcs15(std::string pin) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectMF();
|
selectMF();
|
||||||
logon(pkcs15Pin(), pin);
|
logon(pkcs15Pin(), pin);
|
||||||
}
|
}
|
||||||
@@ -1095,18 +1058,24 @@ namespace cardos {
|
|||||||
transport PIN and then the card is unlocked and the
|
transport PIN and then the card is unlocked and the
|
||||||
transport state is unset. */
|
transport state is unset. */
|
||||||
void changeSigGPin(std::string newPin, std::string oldPin) {
|
void changeSigGPin(std::string newPin, std::string oldPin) {
|
||||||
selectSigG();
|
CRYPTOLOG("log");
|
||||||
if (transportState()) { // first time use, reset transport state
|
if (transportState()) { // first time use, reset transport state
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
logonTransport(oldPin);
|
logonTransport(oldPin);
|
||||||
changeReferenceData(sigGPin(), newPin);
|
changeReferenceData(sigGPin(), newPin);
|
||||||
unsetTransportState();
|
unsetTransportState();
|
||||||
} else { // ordinary PIN change
|
} else { // ordinary PIN change
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
|
logonSigG(oldPin);
|
||||||
|
selectSigG();
|
||||||
changeReferenceData(sigGPin(), newPin, oldPin);
|
changeReferenceData(sigGPin(), newPin, oldPin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change PKCS#15 user PIN
|
/// Change PKCS#15 user PIN
|
||||||
void changePkcs15Pin(std::string newPin, std::string oldPin) {
|
void changePkcs15Pin(std::string newPin, std::string oldPin) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectMF();
|
selectMF();
|
||||||
changeReferenceData(pkcs15Pin(), newPin, oldPin);
|
changeReferenceData(pkcs15Pin(), newPin, oldPin);
|
||||||
}
|
}
|
||||||
@@ -1116,87 +1085,110 @@ namespace cardos {
|
|||||||
state, if so, old PIN must be transport PIN. in any case,
|
state, if so, old PIN must be transport PIN. in any case,
|
||||||
change PIN on PKCS#15 and SigG from the same old PIN to the
|
change PIN on PKCS#15 and SigG from the same old PIN to the
|
||||||
same new PIN. */
|
same new PIN. */
|
||||||
void changePin(std::string newPin, std::string oldPin) {
|
void changePins(std::string newPin, std::string oldPin) {
|
||||||
try {
|
CRYPTOLOG("log");
|
||||||
changePkcs15Pin(newPin, oldPin);
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
|
if (transportState()) {
|
||||||
|
if (sigGPinRetries()!=-1) changeSigGPin(newPin, oldPin);
|
||||||
|
if (pkcs15PinRetries()!=-1) changePkcs15Pin(newPin, oldPin);
|
||||||
|
} else {
|
||||||
|
if (pkcs15PinRetries()!=-1) changePkcs15Pin(newPin, oldPin);
|
||||||
try {
|
try {
|
||||||
changeSigGPin(newPin, oldPin);
|
if (sigGPinRetries()!=-1) changeSigGPin(newPin, oldPin);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
changePkcs15Pin(oldPin, newPin); // undo PKCS#15 PIN change
|
// undo PKCS#15 PIN change
|
||||||
throw; // change SigG PIN failed
|
if (pkcs15PinRetries()!=-1) changePkcs15Pin(oldPin, newPin);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
} catch (...) {
|
|
||||||
throw; // change PKCS#15 PIN failed
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Select a file in the PKCS#15 part on the smart card
|
/// Select a file in the PKCS#15 part on the smart card
|
||||||
void selectPkcs15File(std::string file) {
|
void selectPkcs15File(std::string file) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin("3f005015"+file)));
|
check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin("3f005015"+file)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Select a file in the SigG (Signaturgesetz) part on the smart card
|
/// Select a file in the SigG (Signaturgesetz) part on the smart card
|
||||||
void selectSigGFile(std::string file) {
|
void selectSigGFile(std::string file) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin("3f001fff"+file)));
|
check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin("3f001fff"+file)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Select a file in the MF part on the smart card
|
/// Select a file in the MF part on the smart card
|
||||||
void selectMfFile(std::string file) {
|
void selectMfFile(std::string file) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin("3f00"+file)));
|
check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin("3f00"+file)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Select the PKCS#15 part on the smart card
|
/// Select the PKCS#15 part on the smart card
|
||||||
void selectPkcs15() {
|
void selectPkcs15() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin("3f005015")));
|
check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin("3f005015")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Select the SigG (Signaturgesetz) part on the smart card
|
/// Select the SigG (Signaturgesetz) part on the smart card
|
||||||
void selectSigG() {
|
void selectSigG() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin("3f001fff")));
|
check(send(0x00, 0xA4, 0x08, 0x0C, crypto::hexToBin("3f001fff")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Select the MFpart on the smart card
|
/// Select the MFpart on the smart card
|
||||||
void selectMF() {
|
void selectMF() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
check(send(0x00, 0xA4, 0x00, 0x0C));
|
check(send(0x00, 0xA4, 0x00, 0x0C));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @return binary serial number
|
/// @return binary serial number
|
||||||
std::string serial() {
|
std::string serial() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
return getDataChipProduction().serial;
|
return getDataChipProduction().serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @return @c true if card is still in transport state
|
/// @return @c true if card is still in transport state
|
||||||
bool transportState() {
|
bool transportState() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectSigGFile("fe15");
|
selectSigGFile("fe15");
|
||||||
return std::string(4, '\0')==readBinary();
|
return std::string(4, '\0')==readRecord();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark card as initiakized and no more in transport state
|
/// Mark card as initiakized and no more in transport state
|
||||||
void unsetTransportState() {
|
void unsetTransportState() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectSigGFile("fe15");
|
selectSigGFile("fe15");
|
||||||
increase();
|
increase();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! @return number of remaining transport PIN retries or -1 if locked */
|
/*! @return number of remaining transport PIN retries or -1 if locked */
|
||||||
int transportPinRetries() {
|
int transportPinRetries() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectSigG();
|
selectSigG();
|
||||||
return verify(transportPin());
|
return verify(transportPin());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! @return number of remaining PKCS#15 PIN retries or -1 if locked */
|
/*! @return number of remaining PKCS#15 PIN retries or -1 if locked */
|
||||||
int pkcs15PinRetries() {
|
int pkcs15PinRetries() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectMF();
|
selectMF();
|
||||||
return verify(pkcs15Pin());
|
return verify(pkcs15Pin());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! @return number of remaining SigG PIN retries or -1 if locked */
|
/*! @return number of remaining SigG PIN retries or -1 if locked */
|
||||||
int sigGPinRetries() {
|
int sigGPinRetries() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectSigG();
|
selectSigG();
|
||||||
return verify(sigGPin());
|
return verify(sigGPin());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! @return number of remaining PUK retries or -1 if locked */
|
/*! @return number of remaining PUK retries or -1 if locked */
|
||||||
int pukRetries() {
|
int pukRetries() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
selectMF();
|
selectMF();
|
||||||
return verify(puk());
|
return verify(puk());
|
||||||
}
|
}
|
||||||
@@ -1240,7 +1232,7 @@ namespace cardos {
|
|||||||
else if (data.size()>4)
|
else if (data.size()>4)
|
||||||
return send(data[0], data[1], data[2], data[3], data.substr(4));
|
return send(data[0], data[1], data[2], data[3], data.substr(4));
|
||||||
else
|
else
|
||||||
throw std::runtime_error("wrong APDU pass at least 4 bytes in hex");
|
throw runtime_error("wrong APDU pass at least 4 bytes in hex");
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @return error text of APDU result string
|
//! @return error text of APDU result string
|
||||||
@@ -1316,10 +1308,10 @@ namespace cardos {
|
|||||||
return "CLA invalid (Hi nibble)";
|
return "CLA invalid (Hi nibble)";
|
||||||
case 0x6f00:
|
case 0x6f00:
|
||||||
return
|
return
|
||||||
"Technical Error:\n"
|
"Technical Error: "
|
||||||
" 1 Attempt to create more than 254 records in a file.\n"
|
" 1 Attempt to create more than 254 records in a file. "
|
||||||
" 2 Package uses SDK version which is not compatible to"
|
" 2 Package uses SDK version which is not compatible to"
|
||||||
" API version\n"
|
" API version "
|
||||||
" 3 Package contains invalid statements (LOAD EXECUTABLE)";
|
" 3 Package contains invalid statements (LOAD EXECUTABLE)";
|
||||||
case 0x6f81:
|
case 0x6f81:
|
||||||
return "File is invalidated because of checksum error (prop.)";
|
return "File is invalidated because of checksum error (prop.)";
|
||||||
@@ -1342,7 +1334,7 @@ namespace cardos {
|
|||||||
return "Transaction buffer too small";
|
return "Transaction buffer too small";
|
||||||
case 0x6fff:
|
case 0x6fff:
|
||||||
return
|
return
|
||||||
"Internal assertion (invalid internal error)\n"
|
"Internal assertion (invalid internal error) "
|
||||||
"This error is no runtime error but an internal error which can"
|
"This error is no runtime error but an internal error which can"
|
||||||
" occur because of a programming error only.";
|
" occur because of a programming error only.";
|
||||||
case 0x9000:
|
case 0x9000:
|
||||||
@@ -1384,7 +1376,8 @@ namespace cardos {
|
|||||||
|
|
||||||
std::string check(std::string res) {
|
std::string check(std::string res) {
|
||||||
unsigned int value(retCode(res));
|
unsigned int value(retCode(res));
|
||||||
if (value!=0x9000) throw std::runtime_error(error(value));
|
if (value==0x6300) throw wrong_pin(error(value));
|
||||||
|
if (value!=0x9000) throw runtime_error(error(value));
|
||||||
return retData(res);
|
return retData(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1410,7 +1403,7 @@ namespace cardos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string send(char cla, char ins, char p1, char p2, std::string lc) {
|
std::string send(char cla, char ins, char p1, char p2, std::string lc) {
|
||||||
if (!_reader) throw std::runtime_error("no reader selected");
|
if (!_reader) throw runtime_error("no reader selected");
|
||||||
CARDOS_LOG("APDU: cla="<<crypto::binToHex(cla)
|
CARDOS_LOG("APDU: cla="<<crypto::binToHex(cla)
|
||||||
<<" ins="<<crypto::binToHex(ins)
|
<<" ins="<<crypto::binToHex(ins)
|
||||||
<<" p1="<<crypto::binToHex(p1)
|
<<" p1="<<crypto::binToHex(p1)
|
||||||
@@ -1418,9 +1411,9 @@ namespace cardos {
|
|||||||
<<" lc="<<crypto::binToHex(lc));
|
<<" lc="<<crypto::binToHex(lc));
|
||||||
return logResult(_reader->transmit(cla, ins, p1, p2, lc));
|
return logResult(_reader->transmit(cla, ins, p1, p2, lc));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string send(char cla, char ins, char p1, char p2) {
|
std::string send(char cla, char ins, char p1, char p2) {
|
||||||
if (!_reader) throw std::runtime_error("no reader selected");
|
if (!_reader) throw runtime_error("no reader selected");
|
||||||
CARDOS_LOG("APDU: cla="<<crypto::binToHex(cla)
|
CARDOS_LOG("APDU: cla="<<crypto::binToHex(cla)
|
||||||
<<" ins="<<crypto::binToHex(ins)
|
<<" ins="<<crypto::binToHex(ins)
|
||||||
<<" p1="<<crypto::binToHex(p1)
|
<<" p1="<<crypto::binToHex(p1)
|
||||||
@@ -1436,213 +1429,7 @@ namespace cardos {
|
|||||||
|
|
||||||
};
|
};
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
class Access {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
enum TokenVersion {PZ2007, PZ2009, PZ2010};
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Access(); // not available, reader is required
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
std::string serialNumber() {
|
|
||||||
return check(_reader->transmit(0x00, 0xCA, 0x01, 0x81),
|
|
||||||
"read serial number").substr(8, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool firstUse() {
|
|
||||||
#ifndef Q_OS_MAC
|
|
||||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
|
||||||
#endif
|
|
||||||
// SigG Part:
|
|
||||||
// 1. select file "transport protection state" /1/ #236
|
|
||||||
check(_reader->transmit(0x00, 0xA4, 0x08, 0x0C, "\x1F\xFF\xFE\x15", 4),
|
|
||||||
"select file \"transport protection state\"");
|
|
||||||
// 2. read PIN_T's current use counter value
|
|
||||||
std::string res(check(_reader->transmit(0x00, 0xB2, 0x00, 0x04),
|
|
||||||
"read PIN_T counter"));
|
|
||||||
if (res.size()!=6) throw wrong_result("cannot check for first use");
|
|
||||||
return res.substr(0, 4)==std::string("\0\0\0\0", 4); // uninitialized: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
//! get file version info
|
|
||||||
/*! @return Content of file "Version Info" or "<unknown>" if
|
|
||||||
there's no such file */
|
|
||||||
|
|
||||||
|
|
||||||
void unlock(const std::string puk, const std::string pin,
|
|
||||||
bool force=false) {
|
|
||||||
// #ifndef Q_OS_MAC
|
|
||||||
// pcsc::Connection::Reader::Transaction lock(_reader);
|
|
||||||
// #endif
|
|
||||||
// check(_reader->transmit(0x00, 0xA4, 0x00, 0x0C), "select MF");
|
|
||||||
// try {
|
|
||||||
// check(_reader->transmit(0x00, 0x20, 0x00, 0x02, puk), "verify PUK");
|
|
||||||
// } catch (std::exception& e) {
|
|
||||||
// throw wrong_puk(std::string("verify user PUK failed: ")+e.what());
|
|
||||||
// }
|
|
||||||
// if (force) { // kill old dig sig
|
|
||||||
// while (checkDigSigPin().valid())
|
|
||||||
// try {
|
|
||||||
// check(_reader->transmit(0x00, 0xA4, 0x08, 0x0C,
|
|
||||||
// "\x1F\xFF\xFE\x15", 4),
|
|
||||||
// "select SigG");
|
|
||||||
// check(_reader->transmit(0x00, 0x20, 0x00, 0x81, pin),
|
|
||||||
// "verify for correct old PIN in SigG");
|
|
||||||
// break; // ok, pin still vaild, user is a winner
|
|
||||||
// } catch (...) {} // normally ends up here, retry until broken
|
|
||||||
// } else {
|
|
||||||
// if (checkDigSigPin().valid()) try {
|
|
||||||
// check(_reader->transmit(0x00, 0xA4, 0x08, 0x0C,
|
|
||||||
// "\x1F\xFF\xFE\x15", 4),
|
|
||||||
// "select SigG");
|
|
||||||
// check(_reader->transmit(0x00, 0x20, 0x00, 0x81, pin),
|
|
||||||
// "verify for correct old PIN in SigG");
|
|
||||||
// } catch (std::exception& e) {
|
|
||||||
// throw wrong_pin(std::string("verify SigG PIN failed: ")+e.what());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// check(_reader->transmit(0x00, 0xA4, 0x00, 0x0C), "select MF");
|
|
||||||
// check(_reader->transmit(0x00, 0x24, 0x01, 0x81, pin), "reset user PIN");
|
|
||||||
}
|
|
||||||
|
|
||||||
void changePin(const std::string oldPin, const std::string newPin) {
|
|
||||||
// #ifndef Q_OS_MAC
|
|
||||||
// pcsc::Connection::Reader::Transaction lock(_reader);
|
|
||||||
// #endif
|
|
||||||
// if (version()==PZ2007||firstUse()) {
|
|
||||||
// changePinSigG(oldPin, newPin);
|
|
||||||
// changePinPkcs15(oldPin, newPin);
|
|
||||||
// } else {
|
|
||||||
// if (checkUserPin().locked())
|
|
||||||
// throw user_pin_locked("pin change is not possible");
|
|
||||||
// changePinPkcs15(oldPin, newPin);
|
|
||||||
// if (!checkDigSigPin().locked())
|
|
||||||
// changePinSigG(oldPin, newPin);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
void changePinSigG(const std::string oldPin, const std::string newPin) {
|
|
||||||
// #ifndef Q_OS_MAC
|
|
||||||
// pcsc::Connection::Reader::Transaction lock(_reader);
|
|
||||||
// #endif
|
|
||||||
// bool first(firstUse());
|
|
||||||
// // select DF SigG /1/ #236
|
|
||||||
// check(_reader->transmit(0x00, 0xA4, 0x08, 0x0C, "\x1F\xFF\xFE\x15", 4),
|
|
||||||
// "select DF SigG");
|
|
||||||
// try {
|
|
||||||
// if (first) // verify PIN_T /1/ #248 (optional!)
|
|
||||||
// check(_reader->transmit(0x00, 0x20, 0x00, 0xF1, oldPin),
|
|
||||||
// "verify PIN_T");
|
|
||||||
// else // verify PIN (not in transport state)
|
|
||||||
// check(_reader->transmit(0x00, 0x20, 0x00, 0x81, oldPin),
|
|
||||||
// "verify PIN");
|
|
||||||
// } catch (const std::exception& e) {
|
|
||||||
// throw wrong_pin(std::string("verify SigG-PIN failed: ")+e.what());
|
|
||||||
// }
|
|
||||||
// // change reference data SigG-PIN /1/ #125,81
|
|
||||||
// if (first)
|
|
||||||
// check(_reader->transmit(0x00, 0x24, 0x01, 0x81, newPin),
|
|
||||||
// "change reference data SigG-PIN first time");
|
|
||||||
// else
|
|
||||||
// check(_reader->transmit(0x00, 0x24, 0x00, 0x81, oldPin+newPin),
|
|
||||||
// "change reference data SigG-PIN");
|
|
||||||
// // mark pin as changed, no more transport state
|
|
||||||
// for (int i(0); true; ++i) try { // «bugfix» for freddy: multiple tries
|
|
||||||
// if (first)
|
|
||||||
// check(_reader->transmit(0x80, 0x32, 0x00, 0x00, "\x01", 1),
|
|
||||||
// "mark pin as changed");
|
|
||||||
// break; // jump out of the loop, all everything is ok
|
|
||||||
// } catch (...) { // retry up to 10 times
|
|
||||||
// if (i>=10) throw;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
void changePinPkcs15(const std::string oldPin, const std::string newPin) {
|
|
||||||
// #ifndef Q_OS_MAC
|
|
||||||
// pcsc::Connection::Reader::Transaction lock(_reader);
|
|
||||||
// #endif
|
|
||||||
// // select MF
|
|
||||||
// check(_reader->transmit(0x00, 0xA4, 0x08, 0x0C, "\x3F\x00", 2),
|
|
||||||
// "select MF");
|
|
||||||
// try {
|
|
||||||
// // change reference data | Use PIN ID
|
|
||||||
// check(_reader->transmit(0x00, 0x24, 0x00, 0x01, oldPin+newPin),
|
|
||||||
// "set new PIN");
|
|
||||||
// } catch (const std::exception& e) {
|
|
||||||
// throw wrong_pin(std::string("verify PKCS#15-PIN failed: ")
|
|
||||||
// +e.what());
|
|
||||||
// }
|
|
||||||
// // select DF PKCS#15
|
|
||||||
// check(_reader->transmit(0x00, 0xA4, 0x08, 0x0C, "\x50\x15", 2),
|
|
||||||
// "select DF PKCS#15");
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int retCode(const std::string& res) {
|
|
||||||
if (res.size()>=2)
|
|
||||||
return ((((unsigned int)(unsigned char)res[res.size()-2])*256)
|
|
||||||
+((unsigned int)(unsigned char)res[res.size()-1]));
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
friend class CardOsTest;
|
|
||||||
|
|
||||||
//! ANSI Padding: Fill to 8 byte blocks with @c 0x00
|
|
||||||
static std::string ansiPadding(std::string data) {
|
|
||||||
while (data.size()%8!=0) data += (char)0x00;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! ISO Padding: mark end with @c 0x80, then do @ref ansiPadding
|
|
||||||
static std::string isoPadding(std::string data) {
|
|
||||||
data += (char)0x80; // command+ISO_Padding_Byte(0x80)
|
|
||||||
return ansiPadding(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string des3enc(const std::string& data,
|
|
||||||
const openssl::CBlock8& key1,
|
|
||||||
const openssl::CBlock8& key2) {
|
|
||||||
// initial vector is always 0
|
|
||||||
return openssl::des2edeCbcEnc(isoPadding(data), key1, key2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// retail mac signature
|
|
||||||
static std::string sign(const std::string& data,
|
|
||||||
const openssl::CBlock8& key1,
|
|
||||||
const openssl::CBlock8& key2) {
|
|
||||||
// initial vector is 0 anyway...
|
|
||||||
openssl::CBlock8 ivec;
|
|
||||||
openssl::desCbcEnc(isoPadding(data), key1, ivec);
|
|
||||||
return openssl::desCbcEnc(openssl::desCbcDec(ivec, key2), key1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& check(const std::string& res,
|
|
||||||
const std::string& position) const {
|
|
||||||
// static unsigned long SUCCESS(0x9000);
|
|
||||||
// unsigned long c(retCode(res));
|
|
||||||
// if (c!=SUCCESS) throw card_transmission_failed(position,
|
|
||||||
// Commands::error(c));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
mrw::Shared<pcsc::Connection::Reader> _reader;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
@@ -17,6 +17,57 @@
|
|||||||
/*! @defgroup gcrypto Auxiliary Crypto-Functions */
|
/*! @defgroup gcrypto Auxiliary Crypto-Functions */
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
|
#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 file(__FILE__); \
|
||||||
|
std::string line(CRYPTOLOG_QUOTE(__LINE__)); \
|
||||||
|
std::string::size_type pos(file.rfind('/')); \
|
||||||
|
if (pos!=std::string::npos) file=file.substr(pos+1); \
|
||||||
|
std::string spc1(18>file.size()?std::string(18-file.size(), ' ') \
|
||||||
|
:std::string()); \
|
||||||
|
std::string spc2(4>line.size()?std::string(4-line.size(), ' ') \
|
||||||
|
:std::string()); \
|
||||||
|
std::clog<<"CRYPTO: "<<spc1<<file<<':'<<spc2<<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 file(__FILE__); \
|
||||||
|
std::string line(CRYPTOLOG_QUOTE(__LINE__)); \
|
||||||
|
std::string::size_type pos(file.rfind('/')); \
|
||||||
|
if (pos!=std::string::npos) file=file.substr(pos+1); \
|
||||||
|
std::string spc1(18>file.size()?std::string(18-file.size(), ' ') \
|
||||||
|
:std::string()); \
|
||||||
|
std::string spc2(4>line.size()?std::string(4-line.size(), ' ') \
|
||||||
|
:std::string()); \
|
||||||
|
std::clog<<"CRYPTO: "<<spc1<<file<<':'<<spc2<<line<<" -- "<<X \
|
||||||
|
<<CRYPTOLOG_END; \
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
//! @see gcrypto
|
//! @see gcrypto
|
||||||
namespace crypto {
|
namespace crypto {
|
||||||
|
|
||||||
|
@@ -24,14 +24,14 @@ typedef CK_RV (*CK_C_GetFunctionList)
|
|||||||
namespace cryptoki {
|
namespace cryptoki {
|
||||||
|
|
||||||
bool Library::Init::functionList(const std::string& library) {
|
bool Library::Init::functionList(const std::string& library) {
|
||||||
CRYPTOKI_LOG("try to load: "<<library);
|
CRYPTOLOG("try to load: "<<library);
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
_lib = dlopen(library.c_str(), RTLD_NOW);
|
_lib = dlopen(library.c_str(), RTLD_NOW);
|
||||||
#else
|
#else
|
||||||
_lib = LoadLibrary(library.c_str());
|
_lib = LoadLibrary(library.c_str());
|
||||||
#endif
|
#endif
|
||||||
if (!_lib) throw exception("open of library failed: "+library);
|
if (!_lib) throw exception("open of library failed: "+library);
|
||||||
CRYPTOKI_LOG("loaded: "<<library);
|
CRYPTOLOG("loaded: "<<library);
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
CK_C_GetFunctionList fn
|
CK_C_GetFunctionList fn
|
||||||
((CK_C_GetFunctionList)dlsym(_lib, "C_GetFunctionList"));
|
((CK_C_GetFunctionList)dlsym(_lib, "C_GetFunctionList"));
|
||||||
@@ -42,24 +42,28 @@ namespace cryptoki {
|
|||||||
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);
|
||||||
CRYPTOKI_LOG("Got C_GetFunctionList, now call it");
|
CRYPTOLOG("Got C_GetFunctionList, now call it");
|
||||||
//! calls @c C_GetFunctionList
|
//! calls @c C_GetFunctionList
|
||||||
return check(fn(&_fn), CRYPTOKI_FN_LOG("C_GetFunctionList"));
|
return check(fn(&_fn), CRYPTOKI_FN_LOG("C_GetFunctionList"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Library::Init::check(CK_RV result, const std::string& context) {
|
bool Library::Init::check(CK_RV result, const std::string& context) {
|
||||||
CRYPTOKI_LOG("log");
|
|
||||||
_res = result;
|
_res = result;
|
||||||
if (_exc && !*this)
|
if (_exc && !*this)
|
||||||
if (context.size())
|
if (context.size())
|
||||||
throw access_error(context+": "+error());
|
if (_res==CKR_PIN_INCORRECT)
|
||||||
|
throw wrong_pin(context+": "+error());
|
||||||
|
else
|
||||||
|
throw access_error(context+": "+error());
|
||||||
else
|
else
|
||||||
throw access_error(error());
|
if (_res==CKR_PIN_INCORRECT)
|
||||||
|
throw wrong_pin(error());
|
||||||
|
else
|
||||||
|
throw access_error(error());
|
||||||
return _res==CKR_OK;
|
return _res==CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Library::Init::error(CK_RV res) {
|
std::string Library::Init::error(CK_RV res) {
|
||||||
CRYPTOKI_LOG("log");
|
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case CKR_OK: return "CKR_OK";
|
case CKR_OK: return "CKR_OK";
|
||||||
case CKR_CANCEL: return "CKR_CANCEL";
|
case CKR_CANCEL: return "CKR_CANCEL";
|
||||||
@@ -168,10 +172,10 @@ namespace cryptoki {
|
|||||||
|
|
||||||
Library::Init::Init(const std::string& library, bool exc) try:
|
Library::Init::Init(const std::string& library, bool exc) try:
|
||||||
_exc(exc), _res(CKR_OK), _fn(0) {
|
_exc(exc), _res(CKR_OK), _fn(0) {
|
||||||
CRYPTOKI_LOG("library: "<<library);
|
CRYPTOLOG("library: "<<library);
|
||||||
//! calls @c functionList
|
//! calls @c functionList
|
||||||
if (!functionList(library)) return;
|
if (!functionList(library)) return;
|
||||||
CRYPTOKI_LOG("now initialize "<<library);
|
CRYPTOLOG("now initialize "<<library);
|
||||||
assert(_fn);
|
assert(_fn);
|
||||||
//! calls @c C_Initialize
|
//! calls @c C_Initialize
|
||||||
check(_fn->C_Initialize(0), //! @todo add optional argument
|
check(_fn->C_Initialize(0), //! @todo add optional argument
|
||||||
@@ -182,7 +186,7 @@ namespace cryptoki {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Library::Init::~Init() {
|
Library::Init::~Init() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
try {
|
try {
|
||||||
//! calls @c C_Finalize
|
//! calls @c C_Finalize
|
||||||
check(_fn->C_Finalize(0), CRYPTOKI_FN_LOG("C_Finalize"));
|
check(_fn->C_Finalize(0), CRYPTOKI_FN_LOG("C_Finalize"));
|
||||||
@@ -200,12 +204,10 @@ namespace cryptoki {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Library::Init::operator bool() {
|
Library::Init::operator bool() {
|
||||||
CRYPTOKI_LOG("log "<<(_res==CKR_OK?"success":"failed"));
|
|
||||||
return _res==CKR_OK;
|
return _res==CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Library::Init::error() {
|
std::string Library::Init::error() {
|
||||||
CRYPTOKI_LOG("log");
|
|
||||||
return error(_res);
|
return error(_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +221,7 @@ namespace cryptoki {
|
|||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
SlotList Library::slotList(bool tokenPresent, std::string name) {
|
SlotList Library::slotList(bool tokenPresent, std::string name) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
SlotList res;
|
SlotList res;
|
||||||
CK_ULONG count(0);
|
CK_ULONG count(0);
|
||||||
//! calls @c C_GetSlotList
|
//! calls @c C_GetSlotList
|
||||||
@@ -252,7 +254,7 @@ namespace cryptoki {
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
ObjectList Session::find(const AttributeList& attrs) {
|
ObjectList Session::find(const AttributeList& attrs) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
ObjectList res;
|
ObjectList res;
|
||||||
CK_ATTRIBUTE* a(0);
|
CK_ATTRIBUTE* a(0);
|
||||||
try {
|
try {
|
||||||
@@ -262,19 +264,19 @@ namespace cryptoki {
|
|||||||
a[i] = attrs[i];
|
a[i] = attrs[i];
|
||||||
}
|
}
|
||||||
//! calls @c C_FindObjectsInit
|
//! calls @c C_FindObjectsInit
|
||||||
if (check(_slot->_library->C_FindObjectsInit
|
if (check(_slot._library->C_FindObjectsInit
|
||||||
(_session, a, attrs.size()),
|
(_session, a, attrs.size()),
|
||||||
CRYPTOKI_FN_LOG("C_FindObjectsInit"))) {
|
CRYPTOKI_FN_LOG("C_FindObjectsInit"))) {
|
||||||
CK_OBJECT_HANDLE obj;
|
CK_OBJECT_HANDLE obj;
|
||||||
//! calls @c C_FindObjects
|
//! calls @c C_FindObjects
|
||||||
for (CK_ULONG objs(0);
|
for (CK_ULONG objs(0);
|
||||||
check(_slot->_library->C_FindObjects
|
check(_slot._library->C_FindObjects
|
||||||
(_session, &obj, 1, &objs),
|
(_session, &obj, 1, &objs),
|
||||||
CRYPTOKI_FN_LOG("C_FindObjects")) && objs;
|
CRYPTOKI_FN_LOG("C_FindObjects")) && objs;
|
||||||
res.push_back(Object(*this, obj)));
|
res.push_back(Object(*this, obj)));
|
||||||
}
|
}
|
||||||
//! calls @c C_FindObjectsFinal
|
//! calls @c C_FindObjectsFinal
|
||||||
check(_slot->_library->C_FindObjectsFinal(_session),
|
check(_slot._library->C_FindObjectsFinal(_session),
|
||||||
CRYPTOKI_FN_LOG("C_FindObjectsFinal"));
|
CRYPTOKI_FN_LOG("C_FindObjectsFinal"));
|
||||||
delete[] a;
|
delete[] a;
|
||||||
return res;
|
return res;
|
||||||
@@ -286,7 +288,7 @@ namespace cryptoki {
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
ObjectList Session::find(const Attribute& a) {
|
ObjectList Session::find(const Attribute& a) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
AttributeList al;
|
AttributeList al;
|
||||||
al.push_back(a);
|
al.push_back(a);
|
||||||
return find(al);
|
return find(al);
|
||||||
@@ -294,7 +296,7 @@ namespace cryptoki {
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
ObjectList Session::find(const Attribute& a1, const Attribute& a2) {
|
ObjectList Session::find(const Attribute& a1, const Attribute& a2) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
AttributeList al;
|
AttributeList al;
|
||||||
al.push_back(a1);
|
al.push_back(a1);
|
||||||
al.push_back(a2);
|
al.push_back(a2);
|
||||||
@@ -303,7 +305,7 @@ namespace cryptoki {
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
Object Session::create(const std::string& label, const openssl::X509& cert) {
|
Object Session::create(const std::string& label, const openssl::X509& cert) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
AttributeList attrs;
|
AttributeList attrs;
|
||||||
attrs.push_back(Attribute(CKA_CLASS)
|
attrs.push_back(Attribute(CKA_CLASS)
|
||||||
.from<CK_OBJECT_CLASS>(CKO_CERTIFICATE));
|
.from<CK_OBJECT_CLASS>(CKO_CERTIFICATE));
|
||||||
@@ -318,14 +320,14 @@ namespace cryptoki {
|
|||||||
attrs.push_back(Attribute(CKA_ISSUER, cert.issuerDER()));
|
attrs.push_back(Attribute(CKA_ISSUER, cert.issuerDER()));
|
||||||
attrs.push_back(Attribute(CKA_SERIAL_NUMBER, cert.serial()));
|
attrs.push_back(Attribute(CKA_SERIAL_NUMBER, cert.serial()));
|
||||||
attrs.push_back(Attribute(CKA_VALUE, cert.valueDER()));
|
attrs.push_back(Attribute(CKA_VALUE, cert.valueDER()));
|
||||||
CRYPTOKI_LOG("create: serial = "<<crypto::hex(cert.serial()));
|
CRYPTOLOG("create: serial = "<<crypto::hex(cert.serial()));
|
||||||
return create(attrs);
|
return create(attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object Session::create(const std::string& label,
|
Object Session::create(const std::string& label,
|
||||||
const openssl::PrivateKey& key,
|
const openssl::PrivateKey& key,
|
||||||
const openssl::X509& cert) {
|
const openssl::X509& cert) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
int usage(cert.keyUsageFlags());
|
int usage(cert.keyUsageFlags());
|
||||||
AttributeList attrs;
|
AttributeList attrs;
|
||||||
attrs.push_back(Attribute(CKA_CLASS)
|
attrs.push_back(Attribute(CKA_CLASS)
|
||||||
@@ -366,7 +368,7 @@ namespace cryptoki {
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
Object Session::create(const AttributeList& attrs) {
|
Object Session::create(const AttributeList& attrs) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
CK_ATTRIBUTE* a(0);
|
CK_ATTRIBUTE* a(0);
|
||||||
try {
|
try {
|
||||||
if (attrs.size()) {
|
if (attrs.size()) {
|
||||||
@@ -377,11 +379,11 @@ namespace cryptoki {
|
|||||||
for (AttributeList::size_type i(0); i<attrs.size(); ++i) {
|
for (AttributeList::size_type i(0); i<attrs.size(); ++i) {
|
||||||
std::string value((char*)a[i].pValue, a[i].ulValueLen);
|
std::string value((char*)a[i].pValue, a[i].ulValueLen);
|
||||||
Attribute xxx(a[i].type, value);
|
Attribute xxx(a[i].type, value);
|
||||||
CRYPTOKI_LOG("Attribute: "<<xxx.name()<<" = "<<xxx.readableValue());
|
CRYPTOLOG("Attribute: "<<xxx.name()<<" = "<<xxx.readableValue());
|
||||||
};
|
};
|
||||||
CK_OBJECT_HANDLE object;
|
CK_OBJECT_HANDLE object;
|
||||||
//! calls @c C_CreateObject
|
//! calls @c C_CreateObject
|
||||||
check(_slot->_library->C_CreateObject
|
check(_slot._library->C_CreateObject
|
||||||
(_session, a, attrs.size(), &object),
|
(_session, a, attrs.size(), &object),
|
||||||
CRYPTOKI_FN_LOG("C_CreateObject"));
|
CRYPTOKI_FN_LOG("C_CreateObject"));
|
||||||
delete[] a;
|
delete[] a;
|
||||||
|
602
src/cryptoki.hxx
602
src/cryptoki.hxx
@@ -36,10 +36,6 @@
|
|||||||
/*! @defgroup cryptokitypes Cryptoki C++ Types and Auxiliary */
|
/*! @defgroup cryptokitypes Cryptoki C++ Types and Auxiliary */
|
||||||
/*! @defgroup cryptokiexceptions Cryptoki Exceptions */
|
/*! @defgroup cryptokiexceptions Cryptoki Exceptions */
|
||||||
|
|
||||||
#ifndef CRYPTOKI_LOG
|
|
||||||
#define CRYPTOKI_LOG(X)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CRYPTOKI_FN_LOG
|
#ifndef CRYPTOKI_FN_LOG
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#if __GNUC__ >= 2
|
#if __GNUC__ >= 2
|
||||||
@@ -51,7 +47,8 @@
|
|||||||
#define CRYPTOKI_FN_LOG(X) (std::string(X " failed in ") \
|
#define CRYPTOKI_FN_LOG(X) (std::string(X " failed in ") \
|
||||||
+std::string(__PRETTY_FUNCTION__))
|
+std::string(__PRETTY_FUNCTION__))
|
||||||
#else
|
#else
|
||||||
#define CRYPTOKI_QUOTE(X) #X
|
#define CRYPTOKI_QUOTE(X) CRYPTOKI_QUOTE2(X)
|
||||||
|
#define CRYPTOKI_QUOTE2(X) #X
|
||||||
//! Cryptoki Error Message Formatting
|
//! Cryptoki Error Message Formatting
|
||||||
/*! If you want to change cryptoki error formatting, just
|
/*! If you want to change cryptoki error formatting, just
|
||||||
redefine your own CRYPTOKY_FN_LOG macro before <code>#include
|
redefine your own CRYPTOKY_FN_LOG macro before <code>#include
|
||||||
@@ -61,24 +58,6 @@
|
|||||||
" __FILE__ ":" CRYPTOKI_QUOTE(__LINE__)
|
" __FILE__ ":" CRYPTOKI_QUOTE(__LINE__)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef CRYPTOKI_LOG
|
|
||||||
#include <iostream>
|
|
||||||
#if __GNUC__ >= 2
|
|
||||||
//! Cryptoki Logging
|
|
||||||
/*! If you want to change cryptoki logging mechanism, just
|
|
||||||
redefine your own CRYPTOKI_LOG macro before <code>#include
|
|
||||||
<cryptoki.hxx></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 CRYPTOKI_LOG macro before <code>#include
|
|
||||||
<cryptoki.hxx></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
|
|
||||||
|
|
||||||
namespace pcsc {
|
namespace pcsc {
|
||||||
std::string version();
|
std::string version();
|
||||||
@@ -119,6 +98,7 @@ namespace cryptoki {
|
|||||||
public:
|
public:
|
||||||
exception(const std::string& reason) throw():
|
exception(const std::string& reason) throw():
|
||||||
_what("cryptoki: "+reason) {
|
_what("cryptoki: "+reason) {
|
||||||
|
CRYPTOLOG("ERROR: "<<what());
|
||||||
}
|
}
|
||||||
~exception() throw() {}
|
~exception() throw() {}
|
||||||
const char* what() const throw() {
|
const char* what() const throw() {
|
||||||
@@ -131,15 +111,19 @@ namespace cryptoki {
|
|||||||
class not_implemented: public exception {
|
class not_implemented: public exception {
|
||||||
public:
|
public:
|
||||||
not_implemented(const std::string& reason) throw():
|
not_implemented(const std::string& reason) throw():
|
||||||
exception("feature is not implemented:\n"+reason) {
|
exception("feature is not implemented: "+reason) {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class access_error: public exception {
|
class access_error: public exception {
|
||||||
public:
|
public:
|
||||||
access_error(const std::string& reason) throw():
|
access_error(const std::string& reason) throw():
|
||||||
exception("smardcard access error:\n"+reason) {
|
exception("smardcard access error: "+reason) {}
|
||||||
}
|
};
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
class wrong_pin: public access_error {
|
||||||
|
public:
|
||||||
|
wrong_pin(const std::string& reason) throw():
|
||||||
|
access_error("wrong pin: "+reason) {}
|
||||||
};
|
};
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
@@ -635,8 +619,9 @@ namespace cryptoki {
|
|||||||
|
|
||||||
@param library name of the shared library that supports pkcs#11
|
@param library name of the shared library that supports pkcs#11
|
||||||
@param exc wether exceptions should be thrown */
|
@param exc wether exceptions should be thrown */
|
||||||
Library(const std::string& library="opensc-pkcs11.so", bool exc=true):
|
Library(const std::string& library, bool exc=true):
|
||||||
_init(library, exc) {
|
_init(library, exc) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -740,7 +725,7 @@ namespace cryptoki {
|
|||||||
//@}
|
//@}
|
||||||
|
|
||||||
Info info() {
|
Info info() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
Info inf;
|
Info inf;
|
||||||
CK_INFO cInf;
|
CK_INFO cInf;
|
||||||
//! calls @c C_GetInfo
|
//! calls @c C_GetInfo
|
||||||
@@ -781,13 +766,19 @@ namespace cryptoki {
|
|||||||
CK_SLOT_ID _slot;
|
CK_SLOT_ID _slot;
|
||||||
CK_RV _res;
|
CK_RV _res;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
Slot(const Library& lib, CK_SLOT_ID slot):
|
Slot(const Library& lib, CK_SLOT_ID slot):
|
||||||
_library(lib), _slot(slot), _res(CKR_OK) {
|
_library(lib), _slot(slot), _res(CKR_OK) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("ID="<<_slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
Slot(const Slot& o):
|
||||||
|
_library(o._library), _slot(o._slot), _res(o._res) {
|
||||||
|
CRYPTOLOG("ID="<<_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check(CK_RV result, const std::string& context="") {
|
bool check(CK_RV result, const std::string& context="") {
|
||||||
CRYPTOKI_LOG("log");
|
|
||||||
_res = result;
|
_res = result;
|
||||||
if (_library.exc() && !*this)
|
if (_library.exc() && !*this)
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
@@ -797,21 +788,6 @@ namespace cryptoki {
|
|||||||
return _res==CKR_OK;
|
return _res==CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//! Don't use without assignment! For standard containers only!
|
|
||||||
Slot() {
|
|
||||||
CRYPTOKI_LOG("log");
|
|
||||||
}
|
|
||||||
|
|
||||||
Slot& operator=(const Slot& o) {
|
|
||||||
CRYPTOKI_LOG("log");
|
|
||||||
_library = o._library;
|
|
||||||
_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
|
||||||
@@ -822,20 +798,18 @@ namespace cryptoki {
|
|||||||
|
|
||||||
/*! @return @c true if last cryptoki on this object call was successful */
|
/*! @return @c true if last cryptoki on this object call was successful */
|
||||||
operator bool() {
|
operator bool() {
|
||||||
CRYPTOKI_LOG("log");
|
|
||||||
return _res==CKR_OK;
|
return _res==CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! @return error text of last cryptoki call */
|
/*! @return error text of last cryptoki call */
|
||||||
std::string error() {
|
std::string error() {
|
||||||
CRYPTOKI_LOG("log");
|
|
||||||
return _library.error(_res);
|
return _library.error(_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
MechanismInfo mechanisminfo(CK_MECHANISM_TYPE mechanism) {
|
MechanismInfo mechanisminfo(CK_MECHANISM_TYPE mechanism) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
MechanismInfo info(mechanism);
|
MechanismInfo info(mechanism);
|
||||||
CK_MECHANISM_INFO cInfo;
|
CK_MECHANISM_INFO cInfo;
|
||||||
//! calls @c C_GetMechanismInfo
|
//! calls @c C_GetMechanismInfo
|
||||||
@@ -848,7 +822,7 @@ namespace cryptoki {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MechanismList mechanismlist() {
|
MechanismList mechanismlist() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
MechanismList res;
|
MechanismList res;
|
||||||
CK_ULONG count(0);
|
CK_ULONG count(0);
|
||||||
//! calls @c C_GetMechanismList
|
//! calls @c C_GetMechanismList
|
||||||
@@ -873,7 +847,7 @@ namespace cryptoki {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SlotInfo slotinfo() {
|
SlotInfo slotinfo() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
SlotInfo info;
|
SlotInfo info;
|
||||||
CK_SLOT_INFO cInfo;
|
CK_SLOT_INFO cInfo;
|
||||||
//! calls @c C_GetSlotInfo
|
//! calls @c C_GetSlotInfo
|
||||||
@@ -888,7 +862,7 @@ namespace cryptoki {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TokenInfo tokeninfo() {
|
TokenInfo tokeninfo() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
TokenInfo info;
|
TokenInfo info;
|
||||||
//! calls @c C_GetTokenInfo
|
//! calls @c C_GetTokenInfo
|
||||||
CK_TOKEN_INFO cInfo;
|
CK_TOKEN_INFO cInfo;
|
||||||
@@ -918,7 +892,7 @@ namespace cryptoki {
|
|||||||
/*! @bug does not compile:
|
/*! @bug does not compile:
|
||||||
@code
|
@code
|
||||||
bool inittoken(std::string pin, FixString<32> label) {
|
bool inittoken(std::string pin, FixString<32> label) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_InitToken
|
//! calls @c C_InitToken
|
||||||
return check(_library->C_InitToken
|
return check(_library->C_InitToken
|
||||||
(_slot,
|
(_slot,
|
||||||
@@ -935,7 +909,7 @@ namespace cryptoki {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool registerforslotevent(SlotEventListener&) {
|
bool registerforslotevent(SlotEventListener&) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_WaitForSlotEvent
|
//! calls @c C_WaitForSlotEvent
|
||||||
return check(_library->C_WaitForSlotEvent(CK_FLAGS, &_slot, CK_VOID_PTR),
|
return check(_library->C_WaitForSlotEvent(CK_FLAGS, &_slot, CK_VOID_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_WaitForSlotEvent"));
|
CRYPTOKI_FN_LOG("C_WaitForSlotEvent"));
|
||||||
@@ -951,16 +925,22 @@ namespace cryptoki {
|
|||||||
friend class Login;
|
friend class Login;
|
||||||
friend class Object;
|
friend class Object;
|
||||||
|
|
||||||
mrw::Shared<Slot> _slot;
|
typedef std::multimap<CK_SLOT_ID, CK_SESSION_HANDLE> Slots;
|
||||||
|
|
||||||
|
Slot _slot;
|
||||||
CK_SESSION_HANDLE _session;
|
CK_SESSION_HANDLE _session;
|
||||||
CK_RV _res;
|
CK_RV _res;
|
||||||
|
|
||||||
|
static Slots& slots() {
|
||||||
|
static Slots _slots;
|
||||||
|
return _slots;
|
||||||
|
}
|
||||||
|
|
||||||
Session(); // forbidden
|
Session(); // forbidden
|
||||||
|
|
||||||
bool check(CK_RV result, const std::string& context="") {
|
bool check(CK_RV result, const std::string& context="") {
|
||||||
CRYPTOKI_LOG("log");
|
|
||||||
_res = result;
|
_res = result;
|
||||||
if (_slot->_library.exc() && !*this)
|
if (_slot._library.exc() && !*this)
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
throw access_error(context+": "+error());
|
throw access_error(context+": "+error());
|
||||||
else
|
else
|
||||||
@@ -968,43 +948,72 @@ namespace cryptoki {
|
|||||||
return _res==CKR_OK;
|
return _res==CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free() {
|
//! calls @c C_OpenSession if it's the first session
|
||||||
CRYPTOKI_LOG("log");
|
void open(bool rw=false) {
|
||||||
try {
|
CRYPTOLOG("references: "<<slots().count(_slot._slot));
|
||||||
//! closes login.
|
if (slots().count(_slot._slot)==0) {
|
||||||
logout();
|
check(_slot._library->C_OpenSession
|
||||||
} catch (...) { // still try to close session
|
(_slot._slot, CKF_SERIAL_SESSION|(rw?CKF_RW_SESSION:0),
|
||||||
//! calls @c C_CloseSession
|
0, 0, &_session),
|
||||||
try {
|
CRYPTOKI_FN_LOG("C_OpenSession"));
|
||||||
check(_slot->_library->C_CloseSession(_session),
|
} else {
|
||||||
CRYPTOKI_FN_LOG("C_CloseSession"));
|
_session = slots().find(_slot._slot)->second;
|
||||||
} catch (...) {} // only report first problem
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
//! calls @c C_CloseSession
|
slots().insert(std::make_pair(_slot._slot, _session));
|
||||||
check(_slot->_library->C_CloseSession(_session),
|
}
|
||||||
CRYPTOKI_FN_LOG("C_CloseSession"));
|
|
||||||
|
//! calls @c C_CloseSession if it's the last session
|
||||||
|
void close() {
|
||||||
|
CRYPTOLOG("references: "<<slots().count(_slot._slot));
|
||||||
|
if (slots().count(_slot._slot)==1) {
|
||||||
|
slots().erase(slots().find(_slot._slot));
|
||||||
|
check(_slot._library->C_CloseSession(_session),
|
||||||
|
CRYPTOKI_FN_LOG("C_CloseSession"));
|
||||||
|
} else {
|
||||||
|
slots().erase(slots().find(_slot._slot));
|
||||||
|
}
|
||||||
|
_session=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Opens a new session.
|
//! Opens a new session.
|
||||||
/*! @param slot slot to open a session on */
|
/*! @param slot slot to open a session on */
|
||||||
Session(mrw::Shared<Slot> slot, bool rw=false):
|
Session(const Slot& slot, bool rw=false):
|
||||||
_slot(slot), _session(0), _res(CKR_OK) {
|
_slot(slot), _session(0), _res(CKR_OK) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_OpenSession
|
open(rw);
|
||||||
check(_slot->_library->C_OpenSession
|
//! @todo pass parameter
|
||||||
(_slot->_slot, CKF_SERIAL_SESSION|(rw?CKF_RW_SESSION:0),
|
}
|
||||||
0, 0, &_session),
|
|
||||||
CRYPTOKI_FN_LOG("C_OpenSession"));
|
//! Opens a new session.
|
||||||
|
/*! @param slot slot to open a session on */
|
||||||
|
Session(const Session& o):
|
||||||
|
_slot(o._slot), _session(o._session), _res(CKR_OK) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
slots().insert(std::make_pair(_slot._slot, _session));
|
||||||
//! @todo pass parameter
|
//! @todo pass parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
~Session() try {
|
~Session() try {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log "<<(std::uncaught_exception()?"IN EXCEPTION":""));
|
||||||
free();
|
try {
|
||||||
|
logout();
|
||||||
|
} catch (const std::exception& x) {
|
||||||
|
CRYPTOLOG("caught: "<<x.what());
|
||||||
|
close();
|
||||||
|
if (!std::uncaught_exception()) throw;
|
||||||
|
} catch (...) {
|
||||||
|
CRYPTOLOG("caught");
|
||||||
|
close();
|
||||||
|
if (!std::uncaught_exception()) throw;
|
||||||
|
}
|
||||||
|
close();
|
||||||
|
} catch (const std::exception& x) {
|
||||||
|
CRYPTOLOG("caught: "<<x.what());
|
||||||
|
if (!std::uncaught_exception()) throw;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
CRYPTOLOG("caught");
|
||||||
if (!std::uncaught_exception()) throw;
|
if (!std::uncaught_exception()) throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1040,14 +1049,12 @@ namespace cryptoki {
|
|||||||
|
|
||||||
/*! @return @c true if last cryptoki on this object call was successful */
|
/*! @return @c true if last cryptoki on this object call was successful */
|
||||||
operator bool() {
|
operator bool() {
|
||||||
CRYPTOKI_LOG("log");
|
|
||||||
return _res==CKR_OK;
|
return _res==CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! @return error text of last cryptoki call */
|
/*! @return error text of last cryptoki call */
|
||||||
std::string error() {
|
std::string error() {
|
||||||
CRYPTOKI_LOG("log");
|
return _slot._library.error(_res);
|
||||||
return _slot->_library.error(_res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
@@ -1059,9 +1066,9 @@ namespace cryptoki {
|
|||||||
//@{
|
//@{
|
||||||
|
|
||||||
bool cancel() {
|
bool cancel() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_CancelFunction
|
//! calls @c C_CancelFunction
|
||||||
return check(_slot->_library->C_CancelFunction(_session),
|
return check(_slot._library->C_CancelFunction(_session),
|
||||||
CRYPTOKI_FN_LOG("C_CancelFunction"));
|
CRYPTOKI_FN_LOG("C_CancelFunction"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,12 +1076,12 @@ namespace cryptoki {
|
|||||||
Object create(const AttributeList& attrs);
|
Object create(const AttributeList& attrs);
|
||||||
|
|
||||||
std::string digest(std::string in) {
|
std::string digest(std::string in) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
res.resize(in.size());
|
res.resize(in.size());
|
||||||
CK_ULONG size(res.size()); //! @todo check if size is ok
|
CK_ULONG size(res.size()); //! @todo check if size is ok
|
||||||
//! calls @c C_Digest
|
//! calls @c C_Digest
|
||||||
check(_slot->_library->C_Digest
|
check(_slot._library->C_Digest
|
||||||
(_session,
|
(_session,
|
||||||
(unsigned char*)&in[0], in.size(),
|
(unsigned char*)&in[0], in.size(),
|
||||||
(unsigned char*)&res[0], &size),
|
(unsigned char*)&res[0], &size),
|
||||||
@@ -1084,12 +1091,12 @@ namespace cryptoki {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string digestencryptupdate(std::string in) {
|
std::string digestencryptupdate(std::string in) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
res.resize(in.size());
|
res.resize(in.size());
|
||||||
CK_ULONG size(res.size()); //! @todo check if size is ok
|
CK_ULONG size(res.size()); //! @todo check if size is ok
|
||||||
//! calls @c C_DigestEncryptUpdate
|
//! calls @c C_DigestEncryptUpdate
|
||||||
check(_slot->_library->C_DigestEncryptUpdate
|
check(_slot._library->C_DigestEncryptUpdate
|
||||||
(_session,
|
(_session,
|
||||||
(unsigned char*)&in[0], in.size(),
|
(unsigned char*)&in[0], in.size(),
|
||||||
(unsigned char*)&res[0], &size),
|
(unsigned char*)&res[0], &size),
|
||||||
@@ -1101,9 +1108,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool digestfinal() {
|
bool digestfinal() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_DigestFinal
|
//! calls @c C_DigestFinal
|
||||||
return check(_slot->_library->C_DigestFinal(_session, CK_BYTE_PTR, CK_ULONG_PTR),
|
return check(_slot._library->C_DigestFinal(_session, CK_BYTE_PTR, CK_ULONG_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_DigestFinal"));
|
CRYPTOKI_FN_LOG("C_DigestFinal"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -1111,9 +1118,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool digestinit() {
|
bool digestinit() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_DigestInit
|
//! calls @c C_DigestInit
|
||||||
return check(_slot->_library->C_DigestInit(_session, CK_MECHANISM_PTR),
|
return check(_slot._library->C_DigestInit(_session, CK_MECHANISM_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_DigestInit"));
|
CRYPTOKI_FN_LOG("C_DigestInit"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -1121,9 +1128,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool digestupdate() {
|
bool digestupdate() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_DigestUpdate
|
//! calls @c C_DigestUpdate
|
||||||
return check(_slot->_library->C_DigestUpdate(_session, CK_BYTE_PTR, CK_ULONG),
|
return check(_slot._library->C_DigestUpdate(_session, CK_BYTE_PTR, CK_ULONG),
|
||||||
CRYPTOKI_FN_LOG("C_DigestUpdate"));
|
CRYPTOKI_FN_LOG("C_DigestUpdate"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -1131,9 +1138,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool findobjectsfinal() {
|
bool findobjectsfinal() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_FindObjectsFinal
|
//! calls @c C_FindObjectsFinal
|
||||||
return check(_slot->_library->C_FindObjectsFinal(_session),
|
return check(_slot._library->C_FindObjectsFinal(_session),
|
||||||
CRYPTOKI_FN_LOG("C_FindObjectsFinal"));
|
CRYPTOKI_FN_LOG("C_FindObjectsFinal"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -1141,9 +1148,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool findobjectsinit() {
|
bool findobjectsinit() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_FindObjectsInit
|
//! calls @c C_FindObjectsInit
|
||||||
return check(_slot->_library->C_FindObjectsInit(_session, CK_ATTRIBUTE_PTR, CK_ULONG),
|
return check(_slot._library->C_FindObjectsInit(_session, CK_ATTRIBUTE_PTR, CK_ULONG),
|
||||||
CRYPTOKI_FN_LOG("C_FindObjectsInit"));
|
CRYPTOKI_FN_LOG("C_FindObjectsInit"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -1151,9 +1158,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool findobjects() {
|
bool findobjects() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_FindObjects
|
//! calls @c C_FindObjects
|
||||||
return check(_session->_slot->_library->C_FindObjects(_session, CK_OBJECT_HANDLE_PTR, CK_ULONG,
|
return check(_session->_slot._library->C_FindObjects(_session, CK_OBJECT_HANDLE_PTR, CK_ULONG,
|
||||||
CK_ULONG_PTR),
|
CK_ULONG_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_FindObjects"));
|
CRYPTOKI_FN_LOG("C_FindObjects"));
|
||||||
}
|
}
|
||||||
@@ -1162,9 +1169,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool generaterandom() {
|
bool generaterandom() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_GenerateRandom
|
//! calls @c C_GenerateRandom
|
||||||
return check(_slot->_library->C_GenerateRandom(_session, CK_BYTE_PTR, CK_ULONG),
|
return check(_slot._library->C_GenerateRandom(_session, CK_BYTE_PTR, CK_ULONG),
|
||||||
CRYPTOKI_FN_LOG("C_GenerateRandom"));
|
CRYPTOKI_FN_LOG("C_GenerateRandom"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -1172,9 +1179,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool getfunctionstatus() {
|
bool getfunctionstatus() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_GetFunctionStatus
|
//! calls @c C_GetFunctionStatus
|
||||||
return check(_slot->_library->C_GetFunctionStatus(_session),
|
return check(_slot._library->C_GetFunctionStatus(_session),
|
||||||
CRYPTOKI_FN_LOG("C_GetFunctionStatus"));
|
CRYPTOKI_FN_LOG("C_GetFunctionStatus"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -1182,89 +1189,133 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool getoperationstate() {
|
bool getoperationstate() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_GetOperationState
|
//! calls @c C_GetOperationState
|
||||||
return check(_slot->_library->C_GetOperationState(_session, CK_BYTE_PTR, CK_ULONG_PTR),
|
return check(_slot._library->C_GetOperationState(_session, CK_BYTE_PTR, CK_ULONG_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_GetOperationState"));
|
CRYPTOKI_FN_LOG("C_GetOperationState"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
/*! @todo Not implemented:
|
/** definition of session info:
|
||||||
|
|
||||||
@code
|
@code
|
||||||
bool getsessioninfo() {
|
struct CK_SESSION_INFO {
|
||||||
CRYPTOKI_LOG("log");
|
CK_SLOT_ID slotID;
|
||||||
|
CK_STATE state;
|
||||||
|
CK_FLAGS flags;
|
||||||
|
CK_ULONG ulDeviceError;
|
||||||
|
};
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
where:
|
||||||
|
- @c slotID ID of the slot that interfaces with the token
|
||||||
|
- @c state The state of the session
|
||||||
|
- @c 0 @c CKS_RO_PUBLIC_SESSION
|
||||||
|
- @c 1 @c CKS_RO_USER_FUNCTIONS
|
||||||
|
- @c 2 @c CKS_RW_PUBLIC_SESSION
|
||||||
|
- @c 3 @c CKS_RW_USER_FUNCTIONS
|
||||||
|
- @c 4 @c CKS_RW_SO_FUNCTIONS
|
||||||
|
- @c flags Bit flags that define the type of session; the
|
||||||
|
flags are defined as:
|
||||||
|
- @c CKF_RW_SESSION
|
||||||
|
- True if the session is read/write.
|
||||||
|
- False if the session is read only.
|
||||||
|
- @c CKF_SERIAL_SESSION Deprecated, always true.
|
||||||
|
- @c ulDeviceError An error code defined by the
|
||||||
|
cryptographic device. Used for errors not covered by
|
||||||
|
Cryptoki. */
|
||||||
|
typedef CK_SESSION_INFO Info;
|
||||||
|
|
||||||
|
/** @return session information */
|
||||||
|
Info getsessioninfo() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
CK_SESSION_INFO info;
|
||||||
//! calls @c C_GetSessionInfo
|
//! calls @c C_GetSessionInfo
|
||||||
return check(_slot->_library->C_GetSessionInfo(_session, CK_SESSION_INFO_PTR),
|
check(_slot._library->C_GetSessionInfo(_session, &info),
|
||||||
CRYPTOKI_FN_LOG("C_GetSessionInfo"));
|
CRYPTOKI_FN_LOG("C_GetSessionInfo"));
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string state(const Info& info) {
|
||||||
|
switch (info.state) {
|
||||||
|
case 0: return "CKS_RO_PUBLIC_SESSION";
|
||||||
|
case 1: return "CKS_RO_USER_FUNCTIONS";
|
||||||
|
case 2: return "CKS_RW_PUBLIC_SESSION ";
|
||||||
|
case 3: return "CKS_RW_USER_FUNCTIONS";
|
||||||
|
case 4: return "CKS_RW_SO_FUNCTIONS";
|
||||||
|
default: return "<UNKNOWN>";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@endcode */
|
|
||||||
|
|
||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool initpin() {
|
bool initpin() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_InitPIN
|
//! calls @c C_InitPIN
|
||||||
return check(_slot->_library->C_InitPIN(_session, CK_CHAR_PTR, CK_ULONG),
|
return check(_slot._library->C_InitPIN(_session, CK_CHAR_PTR, CK_ULONG),
|
||||||
CRYPTOKI_FN_LOG("C_InitPIN"));
|
CRYPTOKI_FN_LOG("C_InitPIN"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
class Login {
|
class Login {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Login(mrw::Shared<Session> session,
|
Login(Session& session,
|
||||||
const std::string& pin,
|
const std::string& pin,
|
||||||
CK_USER_TYPE userType=CKU_USER): _session(session) {
|
CK_USER_TYPE userType=CKU_USER): _session(session) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_Login
|
//! calls @c C_Login
|
||||||
_session->check(_session->_slot->_library->C_Login
|
_session.check(_session._slot._library->C_Login
|
||||||
(_session->_session, userType,
|
(_session._session, userType,
|
||||||
(CK_CHAR*)pin.c_str(),
|
(CK_CHAR*)pin.c_str(),
|
||||||
pin.size()),
|
pin.size()),
|
||||||
CRYPTOKI_FN_LOG("C_Login"));
|
CRYPTOKI_FN_LOG("C_Login"));
|
||||||
}
|
}
|
||||||
|
|
||||||
~Login() {
|
~Login() {
|
||||||
try {
|
try {
|
||||||
//! calls @c C_Logout
|
//! calls @c C_Logout
|
||||||
_session->check(_session->_slot->_library->C_Logout
|
_session.check(_session._slot._library->C_Logout
|
||||||
(_session->_session),
|
(_session._session),
|
||||||
CRYPTOKI_FN_LOG("C_Logout"));
|
CRYPTOKI_FN_LOG("C_Logout"));
|
||||||
|
} catch (const std::exception& x) {
|
||||||
|
if (!std::uncaught_exception()) throw;
|
||||||
|
CRYPTOLOG("ERROR during error cleanup: "<<x.what());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
if (!std::uncaught_exception()) throw;
|
if (!std::uncaught_exception()) throw;
|
||||||
|
CRYPTOLOG("ERROR during error cleanup.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
mrw::Shared<Session> _session;
|
Session& _session;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
void login(const std::string& pin, CK_USER_TYPE userType=CKU_USER) {
|
void login(const std::string& pin, CK_USER_TYPE userType=CKU_USER) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
_login = new Login(*this, pin, userType);
|
_login = new Login(*this, pin, userType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void logout() {
|
void logout() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
try {
|
_login.reset();
|
||||||
_login.reset();
|
}
|
||||||
} catch (...) {
|
|
||||||
_login.reset();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mrw::Shared<Login> _login;
|
mrw::Shared<Login> _login;
|
||||||
|
|
||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool seedrandom() {
|
bool seedrandom() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_SeedRandom
|
//! calls @c C_SeedRandom
|
||||||
return check(_slot->_library->C_SeedRandom(_session, CK_BYTE_PTR, CK_ULONG),
|
return check(_slot._library->C_SeedRandom(_session, CK_BYTE_PTR, CK_ULONG),
|
||||||
CRYPTOKI_FN_LOG("C_SeedRandom"));
|
CRYPTOKI_FN_LOG("C_SeedRandom"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -1272,9 +1323,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool setpin() {
|
bool setpin() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_SetPIN
|
//! calls @c C_SetPIN
|
||||||
return check(_slot->_library->C_SetPIN(_session, CK_CHAR_PTR, CK_ULONG, CK_CHAR_PTR, CK_ULONG),
|
return check(_slot._library->C_SetPIN(_session, CK_CHAR_PTR, CK_ULONG, CK_CHAR_PTR, CK_ULONG),
|
||||||
CRYPTOKI_FN_LOG("C_SetPIN"));
|
CRYPTOKI_FN_LOG("C_SetPIN"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -1287,13 +1338,12 @@ namespace cryptoki {
|
|||||||
friend class Session;
|
friend class Session;
|
||||||
|
|
||||||
CK_OBJECT_HANDLE _object;
|
CK_OBJECT_HANDLE _object;
|
||||||
mrw::Shared<Session> _session;
|
Session _session;
|
||||||
CK_RV _res;
|
CK_RV _res;
|
||||||
|
|
||||||
bool check(CK_RV result, const std::string& context="") {
|
bool check(CK_RV result, const std::string& context="") {
|
||||||
CRYPTOKI_LOG("log");
|
|
||||||
_res = result;
|
_res = result;
|
||||||
if (_session->_slot->_library.exc() && !*this)
|
if (_session._slot._library.exc() && !*this)
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
throw access_error(context+": "+error());
|
throw access_error(context+": "+error());
|
||||||
else
|
else
|
||||||
@@ -1303,9 +1353,9 @@ namespace cryptoki {
|
|||||||
|
|
||||||
Object(); // forbidden
|
Object(); // forbidden
|
||||||
|
|
||||||
Object(mrw::Shared<Session> session, CK_OBJECT_HANDLE obj):
|
Object(const Session& session, CK_OBJECT_HANDLE obj):
|
||||||
_object(obj), _session(session), _res(CKR_OK) {
|
_object(obj), _session(session), _res(CKR_OK) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -1318,30 +1368,30 @@ namespace cryptoki {
|
|||||||
|
|
||||||
std::string encrypt(const std::string& data, CK_MECHANISM_TYPE type,
|
std::string encrypt(const std::string& data, CK_MECHANISM_TYPE type,
|
||||||
const std::string& param=std::string()) {
|
const std::string& param=std::string()) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
CRYPTOKI_LOG("encryptinit");
|
CRYPTOLOG("encryptinit");
|
||||||
encryptinit(type, param);
|
encryptinit(type, param);
|
||||||
CRYPTOKI_LOG("encrypt");
|
CRYPTOLOG("encrypt");
|
||||||
return encrypt(data);
|
return encrypt(data);
|
||||||
//! @todo don't call encryptfinal()?
|
//! @todo don't call encryptfinal()?
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string decrypt(const std::string& data, CK_MECHANISM_TYPE type,
|
std::string decrypt(const std::string& data, CK_MECHANISM_TYPE type,
|
||||||
const std::string& param=std::string()) {
|
const std::string& param=std::string()) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
CRYPTOKI_LOG("decryptinit");
|
CRYPTOLOG("decryptinit");
|
||||||
decryptinit(type, param);
|
decryptinit(type, param);
|
||||||
CRYPTOKI_LOG("decrypt");
|
CRYPTOLOG("decrypt");
|
||||||
return decrypt(data);
|
return decrypt(data);
|
||||||
//! @todo don't call decryptfinal()?
|
//! @todo don't call decryptfinal()?
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sign(const std::string& data, CK_MECHANISM_TYPE type,
|
std::string sign(const std::string& data, CK_MECHANISM_TYPE type,
|
||||||
const std::string& param=std::string()) {
|
const std::string& param=std::string()) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
CRYPTOKI_LOG("signinit");
|
CRYPTOLOG("signinit");
|
||||||
signinit(type, param);
|
signinit(type, param);
|
||||||
CRYPTOKI_LOG("sign");
|
CRYPTOLOG("sign");
|
||||||
return sign(data);
|
return sign(data);
|
||||||
//! @todo don't call signfinal()?
|
//! @todo don't call signfinal()?
|
||||||
}
|
}
|
||||||
@@ -1349,10 +1399,10 @@ namespace cryptoki {
|
|||||||
bool verify(const std::string& data, const std::string& signature,
|
bool verify(const std::string& data, const std::string& signature,
|
||||||
CK_MECHANISM_TYPE type,
|
CK_MECHANISM_TYPE type,
|
||||||
const std::string& param=std::string()) {
|
const std::string& param=std::string()) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
CRYPTOKI_LOG("verifyinit");
|
CRYPTOLOG("verifyinit");
|
||||||
verifyinit(type, param);
|
verifyinit(type, param);
|
||||||
CRYPTOKI_LOG("verify");
|
CRYPTOLOG("verify");
|
||||||
return verify(data, signature);
|
return verify(data, signature);
|
||||||
//! @todo don't call verifyfinal()?
|
//! @todo don't call verifyfinal()?
|
||||||
}
|
}
|
||||||
@@ -1369,14 +1419,12 @@ namespace cryptoki {
|
|||||||
|
|
||||||
/*! @return @c true if last cryptoki on this object call was successful */
|
/*! @return @c true if last cryptoki on this object call was successful */
|
||||||
operator bool() {
|
operator bool() {
|
||||||
CRYPTOKI_LOG("log");
|
|
||||||
return _res==CKR_OK;
|
return _res==CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! @return error text of last cryptoki call */
|
/*! @return error text of last cryptoki call */
|
||||||
std::string error() {
|
std::string error() {
|
||||||
CRYPTOKI_LOG("log");
|
return _session._slot._library.error(_res);
|
||||||
return _session->_slot->_library.error(_res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
@@ -1390,58 +1438,58 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool copyobject() {
|
bool copyobject() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_CopyObject
|
//! calls @c C_CopyObject
|
||||||
return check(_session->_slot->_library->C_CopyObject(_session->_session, CK_OBJECT_HANDLE,
|
return check(_session._slot._library->C_CopyObject(_session._session, CK_OBJECT_HANDLE,
|
||||||
CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR),
|
CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_CopyObject"));
|
CRYPTOKI_FN_LOG("C_CopyObject"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
bool decryptinit(CK_MECHANISM_TYPE type, std::string param) {
|
bool decryptinit(CK_MECHANISM_TYPE type, std::string param) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
CK_MECHANISM mech = {
|
CK_MECHANISM mech = {
|
||||||
type, param.size()?¶m[0]:0, param.size()
|
type, param.size()?¶m[0]:0, param.size()
|
||||||
};
|
};
|
||||||
CRYPTOKI_LOG("decryptinit: type="<<type<<"; mech=("<<mech.mechanism
|
CRYPTOLOG("decryptinit: type="<<type<<"; mech=("<<mech.mechanism
|
||||||
<<", "<<mech.pParameter<<", "<<mech.ulParameterLen<<')');
|
<<", "<<mech.pParameter<<", "<<mech.ulParameterLen<<')');
|
||||||
//! calls @c C_DecryptInit
|
//! calls @c C_DecryptInit
|
||||||
return check(_session->_slot->_library->C_DecryptInit
|
return check(_session._slot._library->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
|
//! requires decryptinit to be called before
|
||||||
std::string decrypt(const std::string& in) {
|
std::string decrypt(const std::string& in) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
CK_ULONG size(0); // two calls, first to get minimum buffer length
|
CK_ULONG size(0); // two calls, first to get minimum buffer length
|
||||||
CRYPTOKI_LOG("get size");
|
CRYPTOLOG("get size");
|
||||||
//! calls @c C_Decrypt
|
//! calls @c C_Decrypt
|
||||||
check(_session->_slot->_library->C_Decrypt
|
check(_session._slot._library->C_Decrypt
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(), 0, &size),
|
(unsigned char*)&in[0], in.size(), 0, &size),
|
||||||
CRYPTOKI_FN_LOG("C_Decrypt"));
|
CRYPTOKI_FN_LOG("C_Decrypt"));
|
||||||
CRYPTOKI_LOG("maximum size is "<<size<<"Bytes");
|
CRYPTOLOG("maximum size is "<<size<<"Bytes");
|
||||||
res.resize(size, 0);
|
res.resize(size, 0);
|
||||||
check(_session->_slot->_library->C_Decrypt
|
check(_session._slot._library->C_Decrypt
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(),
|
(unsigned char*)&in[0], in.size(),
|
||||||
(unsigned char*)&res[0], &size),
|
(unsigned char*)&res[0], &size),
|
||||||
CRYPTOKI_FN_LOG("C_Decrypt"));
|
CRYPTOKI_FN_LOG("C_Decrypt"));
|
||||||
CRYPTOKI_LOG("exact size is "<<size<<"Bytes");
|
CRYPTOLOG("exact size is "<<size<<"Bytes");
|
||||||
res.resize(size);
|
res.resize(size);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string decryptdigestupdate(std::string in) {
|
std::string decryptdigestupdate(std::string in) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
res.resize(in.size());
|
res.resize(in.size());
|
||||||
CK_ULONG size(res.size()); //! @todo check if size is ok
|
CK_ULONG size(res.size()); //! @todo check if size is ok
|
||||||
//! calls @c C_DecryptDigestUpdate
|
//! calls @c C_DecryptDigestUpdate
|
||||||
check(_session->_slot->_library->C_DecryptDigestUpdate
|
check(_session._slot._library->C_DecryptDigestUpdate
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(),
|
(unsigned char*)&in[0], in.size(),
|
||||||
(unsigned char*)&res[0], &size),
|
(unsigned char*)&res[0], &size),
|
||||||
CRYPTOKI_FN_LOG("C_DecryptDigestUpdate"));
|
CRYPTOKI_FN_LOG("C_DecryptDigestUpdate"));
|
||||||
@@ -1450,22 +1498,22 @@ namespace cryptoki {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool decryptfinal() {
|
bool decryptfinal() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_DecryptFinal
|
//! calls @c C_DecryptFinal
|
||||||
return check(_session->_slot->_library->C_DecryptFinal
|
return check(_session._slot._library->C_DecryptFinal
|
||||||
(_session->_session, 0, 0),
|
(_session._session, 0, 0),
|
||||||
CRYPTOKI_FN_LOG("C_DecryptFinal"));
|
CRYPTOKI_FN_LOG("C_DecryptFinal"));
|
||||||
//! @todo does this work?
|
//! @todo does this work?
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string decryptupdate(std::string in) {
|
std::string decryptupdate(std::string in) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
res.resize(in.size());
|
res.resize(in.size());
|
||||||
CK_ULONG size(res.size()); //! @todo check if size is ok
|
CK_ULONG size(res.size()); //! @todo check if size is ok
|
||||||
//! calls @c C_DecryptUpdate
|
//! calls @c C_DecryptUpdate
|
||||||
check(_session->_slot->_library->C_DecryptUpdate
|
check(_session._slot._library->C_DecryptUpdate
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(),
|
(unsigned char*)&in[0], in.size(),
|
||||||
(unsigned char*)&res[0], &size),
|
(unsigned char*)&res[0], &size),
|
||||||
CRYPTOKI_FN_LOG("C_DecryptUpdate"));
|
CRYPTOKI_FN_LOG("C_DecryptUpdate"));
|
||||||
@@ -1474,13 +1522,13 @@ namespace cryptoki {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string decryptverifyupdate(std::string in) {
|
std::string decryptverifyupdate(std::string in) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
res.resize(in.size());
|
res.resize(in.size());
|
||||||
CK_ULONG size(res.size()); //! @todo check if size is ok
|
CK_ULONG size(res.size()); //! @todo check if size is ok
|
||||||
//! calls @c C_DecryptVerifyUpdate
|
//! calls @c C_DecryptVerifyUpdate
|
||||||
check(_session->_slot->_library->C_DecryptVerifyUpdate
|
check(_session._slot._library->C_DecryptVerifyUpdate
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(),
|
(unsigned char*)&in[0], in.size(),
|
||||||
(unsigned char*)&res[0], &size),
|
(unsigned char*)&res[0], &size),
|
||||||
CRYPTOKI_FN_LOG("C_DecryptVerifyUpdate"));
|
CRYPTOKI_FN_LOG("C_DecryptVerifyUpdate"));
|
||||||
@@ -1490,34 +1538,34 @@ namespace cryptoki {
|
|||||||
|
|
||||||
|
|
||||||
std::string sign(std::string in) {
|
std::string sign(std::string in) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
CK_ULONG size(0);
|
CK_ULONG size(0);
|
||||||
check(_session->_slot->_library->C_Sign
|
check(_session._slot._library->C_Sign
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(),0, &size),
|
(unsigned char*)&in[0], in.size(),0, &size),
|
||||||
CRYPTOKI_FN_LOG("C_Sign"));
|
CRYPTOKI_FN_LOG("C_Sign"));
|
||||||
CRYPTOKI_LOG("maximum size is "<<size<<"Bytes");
|
CRYPTOLOG("maximum size is "<<size<<"Bytes");
|
||||||
res.resize(size, 0);
|
res.resize(size, 0);
|
||||||
//! calls @c C_Sign
|
//! calls @c C_Sign
|
||||||
check(_session->_slot->_library->C_Sign
|
check(_session._slot._library->C_Sign
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(),
|
(unsigned char*)&in[0], in.size(),
|
||||||
(unsigned char*)&res[0], &size),
|
(unsigned char*)&res[0], &size),
|
||||||
CRYPTOKI_FN_LOG("C_Sign"));
|
CRYPTOKI_FN_LOG("C_Sign"));
|
||||||
CRYPTOKI_LOG("exact size is "<<size<<"Bytes");
|
CRYPTOLOG("exact size is "<<size<<"Bytes");
|
||||||
res.resize(size);
|
res.resize(size);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string signencryptupdate(std::string in) {
|
std::string signencryptupdate(std::string in) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
res.resize(in.size());
|
res.resize(in.size());
|
||||||
CK_ULONG size(res.size()); //! @todo check if size is ok
|
CK_ULONG size(res.size()); //! @todo check if size is ok
|
||||||
//! calls @c C_SignEncryptUpdate
|
//! calls @c C_SignEncryptUpdate
|
||||||
check(_session->_slot->_library->C_SignEncryptUpdate
|
check(_session._slot._library->C_SignEncryptUpdate
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(),
|
(unsigned char*)&in[0], in.size(),
|
||||||
(unsigned char*)&res[0], &size),
|
(unsigned char*)&res[0], &size),
|
||||||
CRYPTOKI_FN_LOG("C_SignEncryptUpdate"));
|
CRYPTOKI_FN_LOG("C_SignEncryptUpdate"));
|
||||||
@@ -1528,21 +1576,21 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool signfinal() {
|
bool signfinal() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_SignFinal
|
//! calls @c C_SignFinal
|
||||||
return check(_slot->_library->C_SignFinal(_session, CK_BYTE_PTR, CK_ULONG_PTR),
|
return check(_slot._library->C_SignFinal(_session, CK_BYTE_PTR, CK_ULONG_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_SignFinal"));
|
CRYPTOKI_FN_LOG("C_SignFinal"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
std::string signrecover(std::string in) {
|
std::string signrecover(std::string in) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
res.resize(in.size());
|
res.resize(in.size());
|
||||||
CK_ULONG size(res.size()); //! @todo check if size is ok
|
CK_ULONG size(res.size()); //! @todo check if size is ok
|
||||||
//! calls @c C_SignRecover
|
//! calls @c C_SignRecover
|
||||||
check(_session->_slot->_library->C_SignRecover
|
check(_session._slot._library->C_SignRecover
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(),
|
(unsigned char*)&in[0], in.size(),
|
||||||
(unsigned char*)&res[0], &size),
|
(unsigned char*)&res[0], &size),
|
||||||
CRYPTOKI_FN_LOG("C_SignRecover"));
|
CRYPTOKI_FN_LOG("C_SignRecover"));
|
||||||
@@ -1553,18 +1601,18 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool signupdate() {
|
bool signupdate() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_SignUpdate
|
//! calls @c C_SignUpdate
|
||||||
return check(_session->_slot->_library->C_SignUpdate(_session->_session, CK_BYTE_PTR, CK_ULONG),
|
return check(_session._slot._library->C_SignUpdate(_session._session, CK_BYTE_PTR, CK_ULONG),
|
||||||
CRYPTOKI_FN_LOG("C_SignUpdate"));
|
CRYPTOKI_FN_LOG("C_SignUpdate"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
bool verify(std::string data, std::string signature) {
|
bool verify(std::string data, std::string signature) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_Verify
|
//! calls @c C_Verify
|
||||||
return check(_session->_slot->_library->C_Verify
|
return check(_session._slot._library->C_Verify
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&data[0], data.size(),
|
(unsigned char*)&data[0], data.size(),
|
||||||
(unsigned char*)&signature[0], signature.size()),
|
(unsigned char*)&signature[0], signature.size()),
|
||||||
CRYPTOKI_FN_LOG("C_Verify"));
|
CRYPTOKI_FN_LOG("C_Verify"));
|
||||||
@@ -1573,21 +1621,21 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool verifyfinal() {
|
bool verifyfinal() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_VerifyFinal
|
//! calls @c C_VerifyFinal
|
||||||
return check(_session->_slot->_library->C_VerifyFinal(_session->_session, CK_BYTE_PTR, CK_ULONG),
|
return check(_session._slot._library->C_VerifyFinal(_session._session, CK_BYTE_PTR, CK_ULONG),
|
||||||
CRYPTOKI_FN_LOG("C_VerifyFinal"));
|
CRYPTOKI_FN_LOG("C_VerifyFinal"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
std::string verifyrecover(std::string in) {
|
std::string verifyrecover(std::string in) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
res.resize(in.size());
|
res.resize(in.size());
|
||||||
CK_ULONG size(res.size()); //! @todo check if size is ok
|
CK_ULONG size(res.size()); //! @todo check if size is ok
|
||||||
//! calls @c C_VerifyRecover
|
//! calls @c C_VerifyRecover
|
||||||
check(_session->_slot->_library->C_VerifyRecover
|
check(_session._slot._library->C_VerifyRecover
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(),
|
(unsigned char*)&in[0], in.size(),
|
||||||
(unsigned char*)&res[0], &size),
|
(unsigned char*)&res[0], &size),
|
||||||
CRYPTOKI_FN_LOG("C_VerifyRecover"));
|
CRYPTOKI_FN_LOG("C_VerifyRecover"));
|
||||||
@@ -1598,9 +1646,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool verifyupdate() {
|
bool verifyupdate() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_VerifyUpdate
|
//! calls @c C_VerifyUpdate
|
||||||
return check(_session->_slot->_library->C_VerifyUpdate(_session->_session, CK_BYTE_PTR, CK_ULONG),
|
return check(_session._slot._library->C_VerifyUpdate(_session._session, CK_BYTE_PTR, CK_ULONG),
|
||||||
CRYPTOKI_FN_LOG("C_VerifyUpdate"));
|
CRYPTOKI_FN_LOG("C_VerifyUpdate"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -1609,19 +1657,19 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool derivekey() {
|
bool derivekey() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_DeriveKey
|
//! calls @c C_DeriveKey
|
||||||
return check(_session->_slot->_library->C_DeriveKey(_session->_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE,
|
return check(_session._slot._library->C_DeriveKey(_session._session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE,
|
||||||
CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR),
|
CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_DeriveKey"));
|
CRYPTOKI_FN_LOG("C_DeriveKey"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
bool destroy() {
|
bool destroy() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_DestroyObject
|
//! calls @c C_DestroyObject
|
||||||
return check(_session->_slot->_library->C_DestroyObject
|
return check(_session._slot._library->C_DestroyObject
|
||||||
(_session->_session, _object),
|
(_session._session, _object),
|
||||||
CRYPTOKI_FN_LOG("C_DestroyObject"));
|
CRYPTOKI_FN_LOG("C_DestroyObject"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1629,40 +1677,40 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool digestkey() {
|
bool digestkey() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_DigestKey
|
//! calls @c C_DigestKey
|
||||||
return check(_session->_slot->_library->C_DigestKey(_session->_session, CK_OBJECT_HANDLE),
|
return check(_session._slot._library->C_DigestKey(_session._session, CK_OBJECT_HANDLE),
|
||||||
CRYPTOKI_FN_LOG("C_DigestKey"));
|
CRYPTOKI_FN_LOG("C_DigestKey"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
bool encryptinit(CK_MECHANISM_TYPE type, const std::string& param) {
|
bool encryptinit(CK_MECHANISM_TYPE type, const std::string& param) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
CK_MECHANISM mech = {
|
CK_MECHANISM mech = {
|
||||||
type, param.size()?(void*)¶m[0]:0, param.size()
|
type, param.size()?(void*)¶m[0]:0, param.size()
|
||||||
};
|
};
|
||||||
CRYPTOKI_LOG("encryptinit: type="<<type<<"; mech=("<<mech.mechanism
|
CRYPTOLOG("encryptinit: type="<<type<<"; mech=("<<mech.mechanism
|
||||||
<<", "<<mech.pParameter<<", "<<mech.ulParameterLen<<')');
|
<<", "<<mech.pParameter<<", "<<mech.ulParameterLen<<')');
|
||||||
//! calls @c C_EncryptInit
|
//! calls @c C_EncryptInit
|
||||||
return check(_session->_slot->_library->C_EncryptInit
|
return check(_session._slot._library->C_EncryptInit
|
||||||
(_session->_session, &mech, _object),
|
(_session._session, &mech, _object),
|
||||||
CRYPTOKI_FN_LOG("C_EncryptInit"));
|
CRYPTOKI_FN_LOG("C_EncryptInit"));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string encrypt(const std::string& in) {
|
std::string encrypt(const std::string& in) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
CK_ULONG size(0); // two calls, first to get minimum buffer length
|
CK_ULONG size(0); // two calls, first to get minimum buffer length
|
||||||
CRYPTOKI_LOG("get size");
|
CRYPTOLOG("get size");
|
||||||
//! calls @c C_Encrypt
|
//! calls @c C_Encrypt
|
||||||
check(_session->_slot->_library->C_Encrypt
|
check(_session._slot._library->C_Encrypt
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(), 0, &size),
|
(unsigned char*)&in[0], in.size(), 0, &size),
|
||||||
CRYPTOKI_FN_LOG("C_Decrypt"));
|
CRYPTOKI_FN_LOG("C_Decrypt"));
|
||||||
CRYPTOKI_LOG("maximum size is "<<size<<"Bytes");
|
CRYPTOLOG("maximum size is "<<size<<"Bytes");
|
||||||
res.resize(size, 0);
|
res.resize(size, 0);
|
||||||
check(_session->_slot->_library->C_Encrypt
|
check(_session._slot._library->C_Encrypt
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(),
|
(unsigned char*)&in[0], in.size(),
|
||||||
(unsigned char*)&res[0], &size),
|
(unsigned char*)&res[0], &size),
|
||||||
CRYPTOKI_FN_LOG("C_Encrypt"));
|
CRYPTOKI_FN_LOG("C_Encrypt"));
|
||||||
@@ -1673,21 +1721,21 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool encryptfinal() {
|
bool encryptfinal() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_EncryptFinal
|
//! calls @c C_EncryptFinal
|
||||||
return check(_session->_slot->_library->C_EncryptFinal(_session->_session, CK_BYTE_PTR, CK_ULONG_PTR),
|
return check(_session._slot._library->C_EncryptFinal(_session._session, CK_BYTE_PTR, CK_ULONG_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_EncryptFinal"));
|
CRYPTOKI_FN_LOG("C_EncryptFinal"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
std::string encryptupdate(std::string in) {
|
std::string encryptupdate(std::string in) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
res.resize(in.size());
|
res.resize(in.size());
|
||||||
CK_ULONG size(res.size()); //! @todo check if size is ok
|
CK_ULONG size(res.size()); //! @todo check if size is ok
|
||||||
//! calls @c C_EncryptUpdate
|
//! calls @c C_EncryptUpdate
|
||||||
check(_session->_slot->_library->C_EncryptUpdate
|
check(_session._slot._library->C_EncryptUpdate
|
||||||
(_session->_session,
|
(_session._session,
|
||||||
(unsigned char*)&in[0], in.size(),
|
(unsigned char*)&in[0], in.size(),
|
||||||
(unsigned char*)&res[0], &size),
|
(unsigned char*)&res[0], &size),
|
||||||
CRYPTOKI_FN_LOG("C_EncryptUpdate"));
|
CRYPTOKI_FN_LOG("C_EncryptUpdate"));
|
||||||
@@ -1698,9 +1746,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool generatekey() {
|
bool generatekey() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_GenerateKey
|
//! calls @c C_GenerateKey
|
||||||
return check(_session->_slot->_library->C_GenerateKey(_session->_session, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR,
|
return check(_session._slot._library->C_GenerateKey(_session._session, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR,
|
||||||
CK_ULONG, CK_OBJECT_HANDLE_PTR),
|
CK_ULONG, CK_OBJECT_HANDLE_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_GenerateKey"));
|
CRYPTOKI_FN_LOG("C_GenerateKey"));
|
||||||
}
|
}
|
||||||
@@ -1710,9 +1758,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool generatekeypair() {
|
bool generatekeypair() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_GenerateKeyPair
|
//! calls @c C_GenerateKeyPair
|
||||||
return check(_session->_slot->_library->C_GenerateKeyPair(_session->_session, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR,
|
return check(_session._slot._library->C_GenerateKeyPair(_session._session, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR,
|
||||||
CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG,
|
CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG,
|
||||||
CK_OBJECT_HANDLE_PTR, CK_OBJECT_HANDLE_PTR),
|
CK_OBJECT_HANDLE_PTR, CK_OBJECT_HANDLE_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_GenerateKeyPair"));
|
CRYPTOKI_FN_LOG("C_GenerateKeyPair"));
|
||||||
@@ -1722,18 +1770,18 @@ namespace cryptoki {
|
|||||||
|
|
||||||
//! Get a Single Attribute
|
//! Get a Single Attribute
|
||||||
Attribute operator[](CK_ATTRIBUTE_TYPE a) {
|
Attribute operator[](CK_ATTRIBUTE_TYPE a) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return attribute(a);
|
return attribute(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get a Single Attribute
|
//! Get a Single Attribute
|
||||||
Attribute attribute(CK_ATTRIBUTE_TYPE a) {
|
Attribute attribute(CK_ATTRIBUTE_TYPE a) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
Attribute res;
|
Attribute res;
|
||||||
CK_ATTRIBUTE attr((CK_ATTRIBUTE){a, 0, 0});
|
CK_ATTRIBUTE attr((CK_ATTRIBUTE){a, 0, 0});
|
||||||
//! calls @c C_GetAttributeValue
|
//! calls @c C_GetAttributeValue
|
||||||
if (!check(_session->_slot->_library->C_GetAttributeValue
|
if (!check(_session._slot._library->C_GetAttributeValue
|
||||||
(_session->_session, _object, &attr, 1),
|
(_session._session, _object, &attr, 1),
|
||||||
CRYPTOKI_FN_LOG("C_GetAttributeValue"))
|
CRYPTOKI_FN_LOG("C_GetAttributeValue"))
|
||||||
|| !(long)attr.ulValueLen>0l)
|
|| !(long)attr.ulValueLen>0l)
|
||||||
//! Without exception handling, size and type must be checked too.
|
//! Without exception handling, size and type must be checked too.
|
||||||
@@ -1741,8 +1789,8 @@ namespace cryptoki {
|
|||||||
try {
|
try {
|
||||||
attr.pValue = malloc(attr.ulValueLen);
|
attr.pValue = malloc(attr.ulValueLen);
|
||||||
attr.pValue = memset(attr.pValue, 0, attr.ulValueLen);
|
attr.pValue = memset(attr.pValue, 0, attr.ulValueLen);
|
||||||
if (check(_session->_slot->_library->C_GetAttributeValue
|
if (check(_session._slot._library->C_GetAttributeValue
|
||||||
(_session->_session, _object, &attr, 1),
|
(_session._session, _object, &attr, 1),
|
||||||
CRYPTOKI_FN_LOG("C_GetAttributeValue")))
|
CRYPTOKI_FN_LOG("C_GetAttributeValue")))
|
||||||
/*! @todo There's no @c CKA_WRAP_TEMPLATE in Open
|
/*! @todo There's no @c CKA_WRAP_TEMPLATE in Open
|
||||||
Cryptoki. From the Specs: «In the special case
|
Cryptoki. From the Specs: «In the special case
|
||||||
@@ -1785,7 +1833,7 @@ namespace cryptoki {
|
|||||||
is no exception in this case. */
|
is no exception in this case. */
|
||||||
AttributeMap attributes(AttributeTypeList attrs
|
AttributeMap attributes(AttributeTypeList attrs
|
||||||
= AttributeTypeList()) {
|
= AttributeTypeList()) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
AttributeMap res;
|
AttributeMap res;
|
||||||
//! Gets all attributes, if @c attrs is empty
|
//! Gets all attributes, if @c attrs is empty
|
||||||
if (attrs.empty()) {
|
if (attrs.empty()) {
|
||||||
@@ -1857,8 +1905,8 @@ namespace cryptoki {
|
|||||||
attr = (CK_ATTRIBUTE){*it, 0, 0};
|
attr = (CK_ATTRIBUTE){*it, 0, 0};
|
||||||
try {
|
try {
|
||||||
//! calls @c C_GetAttributeValue
|
//! calls @c C_GetAttributeValue
|
||||||
if (_session->_slot->_library->C_GetAttributeValue
|
if (_session._slot._library->C_GetAttributeValue
|
||||||
(_session->_session, _object, &attr, 1)
|
(_session._session, _object, &attr, 1)
|
||||||
== CKR_ATTRIBUTE_TYPE_INVALID
|
== CKR_ATTRIBUTE_TYPE_INVALID
|
||||||
|| _res == CKR_ATTRIBUTE_SENSITIVE) {
|
|| _res == CKR_ATTRIBUTE_SENSITIVE) {
|
||||||
continue; //! Ignores unsupported Attributes.
|
continue; //! Ignores unsupported Attributes.
|
||||||
@@ -1867,8 +1915,8 @@ namespace cryptoki {
|
|||||||
if ((long)attr.ulValueLen>0l) {
|
if ((long)attr.ulValueLen>0l) {
|
||||||
attr.pValue = malloc(attr.ulValueLen);
|
attr.pValue = malloc(attr.ulValueLen);
|
||||||
attr.pValue = memset(attr.pValue, 0, attr.ulValueLen);
|
attr.pValue = memset(attr.pValue, 0, attr.ulValueLen);
|
||||||
if (check(_session->_slot->_library->C_GetAttributeValue
|
if (check(_session._slot._library->C_GetAttributeValue
|
||||||
(_session->_session, _object, &attr, 1),
|
(_session._session, _object, &attr, 1),
|
||||||
CRYPTOKI_FN_LOG("C_GetAttributeValue")))
|
CRYPTOKI_FN_LOG("C_GetAttributeValue")))
|
||||||
/*! @todo There's no @c CKA_WRAP_TEMPLATE in Open
|
/*! @todo There's no @c CKA_WRAP_TEMPLATE in Open
|
||||||
Cryptoki. From the Specs: «In the special
|
Cryptoki. From the Specs: «In the special
|
||||||
@@ -1927,9 +1975,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool getobjectsize() {
|
bool getobjectsize() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_GetObjectSize
|
//! calls @c C_GetObjectSize
|
||||||
return check(_session->_slot->_library->C_GetObjectSize(_session->_session, CK_OBJECT_HANDLE, CK_ULONG_PTR),
|
return check(_session._slot._library->C_GetObjectSize(_session._session, CK_OBJECT_HANDLE, CK_ULONG_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_GetObjectSize"));
|
CRYPTOKI_FN_LOG("C_GetObjectSize"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -1938,9 +1986,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool setattributevalue() {
|
bool setattributevalue() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_SetAttributeValue
|
//! calls @c C_SetAttributeValue
|
||||||
return check(_session->_slot->_library->C_SetAttributeValue(_session->_session, CK_OBJECT_HANDLE,
|
return check(_session._slot._library->C_SetAttributeValue(_session._session, CK_OBJECT_HANDLE,
|
||||||
CK_ATTRIBUTE_PTR, CK_ULONG),
|
CK_ATTRIBUTE_PTR, CK_ULONG),
|
||||||
CRYPTOKI_FN_LOG("C_SetAttributeValue"));
|
CRYPTOKI_FN_LOG("C_SetAttributeValue"));
|
||||||
}
|
}
|
||||||
@@ -1949,33 +1997,33 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool setoperationstate() {
|
bool setoperationstate() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_SetOperationState
|
//! calls @c C_SetOperationState
|
||||||
return check(_session->_slot->_library->C_SetOperationState(_session->_session, CK_BYTE_PTR, CK_ULONG,
|
return check(_session._slot._library->C_SetOperationState(_session._session, CK_BYTE_PTR, CK_ULONG,
|
||||||
CK_OBJECT_HANDLE, CK_OBJECT_HANDLE),
|
CK_OBJECT_HANDLE, CK_OBJECT_HANDLE),
|
||||||
CRYPTOKI_FN_LOG("C_SetOperationState"));
|
CRYPTOKI_FN_LOG("C_SetOperationState"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
bool signinit(CK_MECHANISM_TYPE type, std::string param) {
|
bool signinit(CK_MECHANISM_TYPE type, std::string param) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
CK_MECHANISM mech = {
|
CK_MECHANISM mech = {
|
||||||
type, param.size()?¶m[0]:0, param.size()
|
type, param.size()?¶m[0]:0, param.size()
|
||||||
};
|
};
|
||||||
CRYPTOKI_LOG("signinit: type="<<type<<"; mech=("<<mech.mechanism
|
CRYPTOLOG("signinit: type="<<type<<"; mech=("<<mech.mechanism
|
||||||
<<", "<<mech.pParameter<<", "<<mech.ulParameterLen<<')');
|
<<", "<<mech.pParameter<<", "<<mech.ulParameterLen<<')');
|
||||||
//! calls @c C_SignInit
|
//! calls @c C_SignInit
|
||||||
return check(_session->_slot->_library->C_SignInit
|
return check(_session._slot._library->C_SignInit
|
||||||
(_session->_session, &mech, _object),
|
(_session._session, &mech, _object),
|
||||||
CRYPTOKI_FN_LOG("C_SignInit"));
|
CRYPTOKI_FN_LOG("C_SignInit"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool signrecoverinit() {
|
bool signrecoverinit() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_SignRecoverInit
|
//! calls @c C_SignRecoverInit
|
||||||
return check(_session->_slot->_library->C_SignRecoverInit(_session->_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE),
|
return check(_session._slot._library->C_SignRecoverInit(_session._session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE),
|
||||||
CRYPTOKI_FN_LOG("C_SignRecoverInit"));
|
CRYPTOKI_FN_LOG("C_SignRecoverInit"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -1983,9 +2031,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool unwrapkey() {
|
bool unwrapkey() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_UnwrapKey
|
//! calls @c C_UnwrapKey
|
||||||
return check(_session->_slot->_library->C_UnwrapKey(_session->_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE,
|
return check(_session._slot._library->C_UnwrapKey(_session._session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE,
|
||||||
CK_BYTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG,
|
CK_BYTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG,
|
||||||
CK_OBJECT_HANDLE_PTR),
|
CK_OBJECT_HANDLE_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_UnwrapKey"));
|
CRYPTOKI_FN_LOG("C_UnwrapKey"));
|
||||||
@@ -1993,24 +2041,24 @@ namespace cryptoki {
|
|||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
bool verifyinit(CK_MECHANISM_TYPE type, std::string param) {
|
bool verifyinit(CK_MECHANISM_TYPE type, std::string param) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
CK_MECHANISM mech = {
|
CK_MECHANISM mech = {
|
||||||
type, param.size()?¶m[0]:0, param.size()
|
type, param.size()?¶m[0]:0, param.size()
|
||||||
};
|
};
|
||||||
CRYPTOKI_LOG("verifyinit: type="<<type<<"; mech=("<<mech.mechanism
|
CRYPTOLOG("verifyinit: type="<<type<<"; mech=("<<mech.mechanism
|
||||||
<<", "<<mech.pParameter<<", "<<mech.ulParameterLen<<')');
|
<<", "<<mech.pParameter<<", "<<mech.ulParameterLen<<')');
|
||||||
//! calls @c C_VerifyInit
|
//! calls @c C_VerifyInit
|
||||||
return check(_session->_slot->_library->C_VerifyInit
|
return check(_session._slot._library->C_VerifyInit
|
||||||
(_session->_session, &mech, _object),
|
(_session._session, &mech, _object),
|
||||||
CRYPTOKI_FN_LOG("C_VerifyInit"));
|
CRYPTOKI_FN_LOG("C_VerifyInit"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool verifyrecoverinit() {
|
bool verifyrecoverinit() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_VerifyRecoverInit
|
//! calls @c C_VerifyRecoverInit
|
||||||
return check(_session->_slot->_library->C_VerifyRecoverInit(_session->_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE),
|
return check(_session._slot._library->C_VerifyRecoverInit(_session._session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE),
|
||||||
CRYPTOKI_FN_LOG("C_VerifyRecoverInit"));
|
CRYPTOKI_FN_LOG("C_VerifyRecoverInit"));
|
||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
@@ -2019,9 +2067,9 @@ namespace cryptoki {
|
|||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
bool wrapkey() {
|
bool wrapkey() {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! calls @c C_WrapKey
|
//! calls @c C_WrapKey
|
||||||
return check(_session->_slot->_library->C_WrapKey(_session->_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE,
|
return check(_session._slot._library->C_WrapKey(_session._session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE,
|
||||||
CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR),
|
CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR),
|
||||||
CRYPTOKI_FN_LOG("C_WrapKey"));
|
CRYPTOKI_FN_LOG("C_WrapKey"));
|
||||||
}
|
}
|
||||||
@@ -2038,13 +2086,13 @@ namespace cryptoki {
|
|||||||
//@{
|
//@{
|
||||||
inline cryptoki::AttributeList& operator<<(cryptoki::AttributeList& list,
|
inline cryptoki::AttributeList& operator<<(cryptoki::AttributeList& list,
|
||||||
const cryptoki::Attribute& attr) {
|
const cryptoki::Attribute& attr) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
list.push_back(attr);
|
list.push_back(attr);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
inline cryptoki::AttributeList operator<<(const cryptoki::AttributeList& list,
|
inline cryptoki::AttributeList operator<<(const cryptoki::AttributeList& list,
|
||||||
const cryptoki::Attribute& attr) {
|
const cryptoki::Attribute& attr) {
|
||||||
CRYPTOKI_LOG("log");
|
CRYPTOLOG("log");
|
||||||
cryptoki::AttributeList res(list);
|
cryptoki::AttributeList res(list);
|
||||||
res.push_back(attr);
|
res.push_back(attr);
|
||||||
return res;
|
return res;
|
||||||
|
@@ -5,8 +5,9 @@
|
|||||||
## 1 2 3 4 5 6 7 8
|
## 1 2 3 4 5 6 7 8
|
||||||
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
|
|
||||||
|
#MOC_FILES=moc_certimport.cxx
|
||||||
include_HEADERS = pcsc.hxx cryptoki.hxx openssl.hxx cryptaux.hxx \
|
include_HEADERS = pcsc.hxx cryptoki.hxx openssl.hxx cryptaux.hxx \
|
||||||
openssl-engine.hxx suisseid.hxx cardos.hxx
|
openssl-engine.hxx suisseid.hxx cardos.hxx certimport.hxx
|
||||||
|
|
||||||
if !MINGW32
|
if !MINGW32
|
||||||
if MAC
|
if MAC
|
||||||
@@ -29,10 +30,13 @@ EXTRA_DIST = $(pkgconfig_DATA).in ${top_srcdir}/src/*.doc
|
|||||||
|
|
||||||
lib_LTLIBRARIES = libpcscxx.la
|
lib_LTLIBRARIES = libpcscxx.la
|
||||||
|
|
||||||
libpcscxx_la_SOURCES = cryptoki.cxx cryptoki.hxx pcsc.cxx \
|
libpcscxx_la_SOURCES = cryptoki.cxx cryptoki.hxx pcsc.cxx version.cxx \
|
||||||
version.cxx openssl-engine.cxx
|
openssl-engine.cxx
|
||||||
|
#moc_certimport.cxx
|
||||||
libpcscxx_la_LDFLAGS = -version-info ${LIB_VERSION}
|
libpcscxx_la_LDFLAGS = -version-info ${LIB_VERSION}
|
||||||
|
#libpcscxx_la_CXXFLAGS = ${QT_CFLAGS}
|
||||||
libpcscxx_la_LIBADD = -lssl -lcrypto
|
libpcscxx_la_LIBADD = -lssl -lcrypto
|
||||||
|
# ${QT_LIBS}
|
||||||
if MINGW32
|
if MINGW32
|
||||||
libpcscxx_la_LIBADD += -lgdi32 -lws2_32
|
libpcscxx_la_LIBADD += -lgdi32 -lws2_32
|
||||||
else
|
else
|
||||||
@@ -45,10 +49,12 @@ endif
|
|||||||
noinst_PROGRAMS = versiontest
|
noinst_PROGRAMS = versiontest
|
||||||
versiontest_SOURCES = versiontest.cxx
|
versiontest_SOURCES = versiontest.cxx
|
||||||
|
|
||||||
|
moc_%.cxx: %.hxx
|
||||||
|
moc -o $@ $<
|
||||||
|
|
||||||
clean-local:
|
clean-local:
|
||||||
-rm -r ${QMAKE_TARGET}.app
|
-rm -r ${QMAKE_TARGET}.app
|
||||||
|
|
||||||
CLEANFILES =
|
CLEANFILES = ${MOC_FILES}
|
||||||
DISTCLEANFILES = $(pkgconfig_DATA)
|
DISTCLEANFILES = $(pkgconfig_DATA)
|
||||||
MAINTAINERCLEANFILES = makefile.in
|
MAINTAINERCLEANFILES = makefile.in
|
||||||
|
@@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
#ifndef __OPENSSL_ENGINE_HXX__
|
#ifndef __OPENSSL_ENGINE_HXX__
|
||||||
#define __OPENSSL_ENGINE_HXX__
|
#define __OPENSSL_ENGINE_HXX__
|
||||||
|
|
||||||
|
#include <cryptaux.hxx>
|
||||||
|
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
#ifndef OPENSSL_VERSION_NUMBER
|
#ifndef OPENSSL_VERSION_NUMBER
|
||||||
# error OpenSSL Version Number not Found
|
# error OpenSSL Version Number not Found
|
||||||
@@ -34,24 +37,6 @@
|
|||||||
#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());}
|
#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
|
||||||
#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
|
//! @addtogroup gopenssl
|
||||||
//@{
|
//@{
|
||||||
@@ -75,56 +60,56 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
Engine(): _e(ENGINE_new()) {
|
Engine(): _e(ENGINE_new()) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
}
|
}
|
||||||
virtual ~Engine() {
|
virtual ~Engine() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
OPENSSL_CHECK(ENGINE_free(_e));
|
OPENSSL_CHECK(ENGINE_free(_e));
|
||||||
}
|
}
|
||||||
virtual const char* id() = 0;
|
virtual const char* id() = 0;
|
||||||
virtual const char* name() = 0;
|
virtual const char* name() = 0;
|
||||||
virtual int init() {
|
virtual int init() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
virtual int finish() {
|
virtual int finish() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
virtual int ctrl(int, long, void*, void(*)()) {
|
virtual int ctrl(int, long, void*, void(*)()) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
virtual int cmd() {
|
virtual int cmd() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
virtual EVP_PKEY* pubkey(const char*, UI_METHOD*, void*) {
|
virtual EVP_PKEY* pubkey(const char*, UI_METHOD*, void*) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
virtual EVP_PKEY* privkey(const char*, UI_METHOD*, void*) {
|
virtual EVP_PKEY* privkey(const char*, UI_METHOD*, void*) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
virtual int rsaEncrypt() {
|
virtual int rsaEncrypt() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
virtual int rsaDecrypt() {
|
virtual int rsaDecrypt() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
virtual std::string rsaSign(const std::string&, unsigned int) {
|
virtual std::string rsaSign(const std::string&, unsigned int) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
throw std::runtime_error("rsaSign not implemented");
|
throw std::runtime_error("rsaSign not implemented");
|
||||||
}
|
}
|
||||||
virtual int rsaVerify() {
|
virtual int rsaVerify() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
virtual int rsaFinish() {
|
virtual int rsaFinish() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +125,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
static void add(Engine *e) {
|
static void add(Engine *e) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
_prototypes[e->id()] = e;
|
_prototypes[e->id()] = e;
|
||||||
_map[e->_e] = e;
|
_map[e->_e] = e;
|
||||||
OPENSSL_CHECK(ENGINE_set_id(e->_e, e->id()));
|
OPENSSL_CHECK(ENGINE_set_id(e->_e, e->id()));
|
||||||
@@ -176,43 +161,43 @@ namespace openssl {
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
static int destroy(ENGINE* e) {
|
static int destroy(ENGINE* e) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
static int init(ENGINE* e) {
|
static int init(ENGINE* e) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
Map::iterator it(_map.find(e));
|
Map::iterator it(_map.find(e));
|
||||||
return it!=_map.end()?it->second->init():0;
|
return it!=_map.end()?it->second->init():0;
|
||||||
}
|
}
|
||||||
static int finish(ENGINE* e) {
|
static int finish(ENGINE* e) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
Map::iterator it(_map.find(e));
|
Map::iterator it(_map.find(e));
|
||||||
return it!=_map.end()?it->second->finish():0;
|
return it!=_map.end()?it->second->finish():0;
|
||||||
}
|
}
|
||||||
static int ctrl(ENGINE* e, int cmd, long i, void* p, void(*f)()) {
|
static int ctrl(ENGINE* e, int cmd, long i, void* p, void(*f)()) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
Map::iterator it(_map.find(e));
|
Map::iterator it(_map.find(e));
|
||||||
return it!=_map.end()?it->second->ctrl(cmd, i, p, f):0;
|
return it!=_map.end()?it->second->ctrl(cmd, i, p, f):0;
|
||||||
}
|
}
|
||||||
static EVP_PKEY* pubkey(ENGINE* e, const char* c, UI_METHOD* u, void* d) {
|
static EVP_PKEY* pubkey(ENGINE* e, const char* c, UI_METHOD* u, void* d) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
Map::iterator it(_map.find(e));
|
Map::iterator it(_map.find(e));
|
||||||
return it!=_map.end()?it->second->pubkey(c, u, d):0;
|
return it!=_map.end()?it->second->pubkey(c, u, d):0;
|
||||||
}
|
}
|
||||||
static EVP_PKEY* privkey(ENGINE* e, const char* c, UI_METHOD* u, void* d) {
|
static EVP_PKEY* privkey(ENGINE* e, const char* c, UI_METHOD* u, void* d) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
Map::iterator it(_map.find(e));
|
Map::iterator it(_map.find(e));
|
||||||
return it!=_map.end()?it->second->privkey(c, u, d):0;
|
return it!=_map.end()?it->second->privkey(c, u, d):0;
|
||||||
}
|
}
|
||||||
static int rsaEncrypt(int flen,const unsigned char *from,
|
static int rsaEncrypt(int flen,const unsigned char *from,
|
||||||
unsigned char *to,
|
unsigned char *to,
|
||||||
RSA *rsa, int padding) {
|
RSA *rsa, int padding) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
Map::iterator it(_map.find(rsa->engine));
|
Map::iterator it(_map.find(rsa->engine));
|
||||||
return it!=_map.end()?it->second->rsaEncrypt():0;
|
return it!=_map.end()?it->second->rsaEncrypt():0;
|
||||||
}
|
}
|
||||||
static int rsaDecrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) {
|
static int rsaDecrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
Map::iterator it(_map.find(rsa->engine));
|
Map::iterator it(_map.find(rsa->engine));
|
||||||
return it!=_map.end()?it->second->rsaDecrypt():0;
|
return it!=_map.end()?it->second->rsaDecrypt():0;
|
||||||
}
|
}
|
||||||
@@ -221,32 +206,32 @@ namespace openssl {
|
|||||||
unsigned char *to,
|
unsigned char *to,
|
||||||
unsigned int*tlen,
|
unsigned int*tlen,
|
||||||
const RSA *rsa) {
|
const RSA *rsa) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
Map::iterator it(_map.find(rsa->engine));
|
Map::iterator it(_map.find(rsa->engine));
|
||||||
if (it==_map.end()) return 0;
|
if (it==_map.end()) return 0;
|
||||||
try {
|
try {
|
||||||
std::string res(it->second->rsaSign
|
std::string res(it->second->rsaSign
|
||||||
(std::string((const char*)from, flen),
|
(std::string((const char*)from, flen),
|
||||||
type));
|
type));
|
||||||
OPENSSL_LOG("to="<<(void*)to<<"; len="<<*tlen);
|
CRYPTOLOG("to="<<(void*)to<<"; len="<<*tlen);
|
||||||
OPENSSL_LOG("siglen="<<res.size());
|
CRYPTOLOG("siglen="<<res.size());
|
||||||
*tlen = res.size();
|
*tlen = res.size();
|
||||||
std::copy(res.begin(), res.end(), to);
|
std::copy(res.begin(), res.end(), to);
|
||||||
return 1;
|
return 1;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
OPENSSL_LOG("ERROR: "<<e.what());
|
CRYPTOLOG("ERROR: "<<e.what());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static int rsaVerify(int, const unsigned char*,
|
static int rsaVerify(int, const unsigned char*,
|
||||||
unsigned int, OPENSSL_V0_CONST unsigned char*,
|
unsigned int, OPENSSL_V0_CONST unsigned char*,
|
||||||
unsigned int, const RSA* rsa) {
|
unsigned int, const RSA* rsa) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
Map::iterator it(_map.find(rsa->engine));
|
Map::iterator it(_map.find(rsa->engine));
|
||||||
return it!=_map.end()?it->second->rsaVerify():0;
|
return it!=_map.end()?it->second->rsaVerify():0;
|
||||||
}
|
}
|
||||||
static int rsaFinish(RSA *rsa) {
|
static int rsaFinish(RSA *rsa) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
Map::iterator it(_map.find(rsa->engine));
|
Map::iterator it(_map.find(rsa->engine));
|
||||||
return it!=_map.end()?it->second->rsaFinish():0;
|
return it!=_map.end()?it->second->rsaFinish():0;
|
||||||
}
|
}
|
||||||
@@ -254,7 +239,7 @@ namespace openssl {
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
static RSA_METHOD* rsa() {
|
static RSA_METHOD* rsa() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
static RSA_METHOD ops;
|
static RSA_METHOD ops;
|
||||||
if (!ops.rsa_priv_enc) {
|
if (!ops.rsa_priv_enc) {
|
||||||
ops = *RSA_get_default_method();
|
ops = *RSA_get_default_method();
|
||||||
|
276
src/openssl.hxx
276
src/openssl.hxx
@@ -60,26 +60,6 @@ namespace pcsc {
|
|||||||
std::string version();
|
std::string version();
|
||||||
}
|
}
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
|
|
||||||
/*! @defgroup gopenssl C++ Wrapper around OpenSSL API */
|
/*! @defgroup gopenssl C++ Wrapper around OpenSSL API */
|
||||||
//@{
|
//@{
|
||||||
//! @defgroup openssllib OpenSSL C++ Library
|
//! @defgroup openssllib OpenSSL C++ Library
|
||||||
@@ -97,7 +77,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
exception(const std::string& reason) throw():
|
exception(const std::string& reason) throw():
|
||||||
_what("openssl: "+reason) {
|
_what("openssl: "+reason) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
~exception() throw() {}
|
~exception() throw() {}
|
||||||
const char* what() const throw() {
|
const char* what() const throw() {
|
||||||
@@ -110,8 +90,8 @@ namespace openssl {
|
|||||||
class openssl_error: public exception {
|
class openssl_error: public exception {
|
||||||
public:
|
public:
|
||||||
openssl_error(const std::string& reason) throw():
|
openssl_error(const std::string& reason) throw():
|
||||||
exception(reason+'\n'+ERR_error_string(ERR_get_error(), 0)) {
|
exception(reason+' '+ERR_error_string(ERR_get_error(), 0)) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -119,7 +99,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
cannot_init(const std::string& reason) throw():
|
cannot_init(const std::string& reason) throw():
|
||||||
openssl_error("openssl initialization: "+reason) {
|
openssl_error("openssl initialization: "+reason) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -127,7 +107,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
encryption_error(const std::string& reason) throw():
|
encryption_error(const std::string& reason) throw():
|
||||||
openssl_error("encryption: "+reason) {
|
openssl_error("encryption: "+reason) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -135,7 +115,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
pkcs12_error(const std::string& reason) throw():
|
pkcs12_error(const std::string& reason) throw():
|
||||||
openssl_error("pkcs12: "+reason) {
|
openssl_error("pkcs12: "+reason) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -143,7 +123,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
pkcs7_error(const std::string& reason) throw():
|
pkcs7_error(const std::string& reason) throw():
|
||||||
openssl_error("pkcs7: "+reason) {
|
openssl_error("pkcs7: "+reason) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -151,7 +131,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
x509_error(const std::string& reason) throw():
|
x509_error(const std::string& reason) throw():
|
||||||
openssl_error("x509: "+reason) {
|
openssl_error("x509: "+reason) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -159,7 +139,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
key_error(const std::string& reason) throw():
|
key_error(const std::string& reason) throw():
|
||||||
openssl_error("private key: "+reason) {
|
openssl_error("private key: "+reason) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -167,7 +147,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
tcp_error(const std::string& reason) throw():
|
tcp_error(const std::string& reason) throw():
|
||||||
openssl_error("tcp "+reason) {
|
openssl_error("tcp "+reason) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -175,7 +155,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
ssl_error(const std::string& reason) throw():
|
ssl_error(const std::string& reason) throw():
|
||||||
openssl_error("ssl: "+reason) {
|
openssl_error("ssl: "+reason) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -183,7 +163,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
cannot_encrypt(std::string reason) throw():
|
cannot_encrypt(std::string reason) throw():
|
||||||
encryption_error("cannot encrypt text: "+reason) {
|
encryption_error("cannot encrypt text: "+reason) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -191,15 +171,15 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
allocation_failed() throw():
|
allocation_failed() throw():
|
||||||
x509_error("memory allocation failed") {
|
x509_error("memory allocation failed") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class x509_decoding_failed: public x509_error {
|
class x509_decoding_failed: public x509_error {
|
||||||
public:
|
public:
|
||||||
x509_decoding_failed(const std::string& der) throw():
|
x509_decoding_failed(const std::string& der) throw():
|
||||||
x509_error("certificate decoding failed:\n"+crypto::readable(der)) {
|
x509_error("certificate decoding failed: "+crypto::readable(der)) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -207,7 +187,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
undefined_certificate() throw():
|
undefined_certificate() throw():
|
||||||
x509_error("certificate must not be 0") {
|
x509_error("certificate must not be 0") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -215,7 +195,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
x509_parsing_failed() throw():
|
x509_parsing_failed() throw():
|
||||||
x509_error("parsing DER encoded certificate failed") {
|
x509_error("parsing DER encoded certificate failed") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -223,7 +203,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
x509_copy_failed() throw():
|
x509_copy_failed() throw():
|
||||||
x509_error("certificate object copy failed") {
|
x509_error("certificate object copy failed") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -231,7 +211,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
key_copy_failed() throw():
|
key_copy_failed() throw():
|
||||||
key_error("key object copy failed") {
|
key_error("key object copy failed") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -239,7 +219,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
undefined_key() throw():
|
undefined_key() throw():
|
||||||
key_error("private key must not be 0") {
|
key_error("private key must not be 0") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -247,7 +227,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
pkcs12_reading_failed(const std::string& file) throw():
|
pkcs12_reading_failed(const std::string& file) throw():
|
||||||
pkcs12_error("reading DER encoded p12 file failed: "+file) {
|
pkcs12_error("reading DER encoded p12 file failed: "+file) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -255,21 +235,21 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
pkcs12_parsing_failed(const std::string& file) throw():
|
pkcs12_parsing_failed(const std::string& file) throw():
|
||||||
pkcs12_error("parsing DER encoded p12 file failed: "+file) {
|
pkcs12_error("parsing DER encoded p12 file failed: "+file) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class pkcs12_no_private_key: public pkcs12_error {
|
class pkcs12_no_private_key: public pkcs12_error {
|
||||||
public:
|
public:
|
||||||
pkcs12_no_private_key() throw(): pkcs12_error("no private key") {
|
pkcs12_no_private_key() throw(): pkcs12_error("no private key") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class pkcs12_no_x509: public pkcs12_error {
|
class pkcs12_no_x509: public pkcs12_error {
|
||||||
public:
|
public:
|
||||||
pkcs12_no_x509() throw(): pkcs12_error("no x509 certificate") {
|
pkcs12_no_x509() throw(): pkcs12_error("no x509 certificate") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -277,7 +257,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
pkcs7_reading_failed(const std::string& file) throw():
|
pkcs7_reading_failed(const std::string& file) throw():
|
||||||
pkcs7_error("reading DER encoded p7 file failed: "+file) {
|
pkcs7_error("reading DER encoded p7 file failed: "+file) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -285,7 +265,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
pkcs7_parsing_failed() throw():
|
pkcs7_parsing_failed() throw():
|
||||||
pkcs7_error("parsing DER encoded p7 failed") {
|
pkcs7_error("parsing DER encoded p7 failed") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
pkcs7_parsing_failed(const std::string& file) throw():
|
pkcs7_parsing_failed(const std::string& file) throw():
|
||||||
pkcs7_error("parsing DER encoded p7 file failed: "+file) {
|
pkcs7_error("parsing DER encoded p7 file failed: "+file) {
|
||||||
@@ -295,14 +275,14 @@ namespace openssl {
|
|||||||
class pkcs7_unsupported_format: public pkcs7_error {
|
class pkcs7_unsupported_format: public pkcs7_error {
|
||||||
public:
|
public:
|
||||||
pkcs7_unsupported_format() throw(): pkcs7_error("format not supported") {
|
pkcs7_unsupported_format() throw(): pkcs7_error("format not supported") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class pkcs7_no_x509: public pkcs7_error {
|
class pkcs7_no_x509: public pkcs7_error {
|
||||||
public:
|
public:
|
||||||
pkcs7_no_x509() throw(): pkcs7_error("no x509 certificate") {
|
pkcs7_no_x509() throw(): pkcs7_error("no x509 certificate") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -310,7 +290,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
cannot_open_file(const std::string& file) throw():
|
cannot_open_file(const std::string& file) throw():
|
||||||
exception("cannot open file: "+file) {
|
exception("cannot open file: "+file) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -318,7 +298,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
tcp_connection_failed(const std::string& hostPort) throw():
|
tcp_connection_failed(const std::string& hostPort) throw():
|
||||||
tcp_error("connection failed to: "+hostPort) {
|
tcp_error("connection failed to: "+hostPort) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -326,35 +306,35 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
tcp_server_not_specified() throw():
|
tcp_server_not_specified() throw():
|
||||||
tcp_error("reconnect without prior connect") {
|
tcp_error("reconnect without prior connect") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class tcp_closed_connection: public tcp_error {
|
class tcp_closed_connection: public tcp_error {
|
||||||
public:
|
public:
|
||||||
tcp_closed_connection() throw(): tcp_error("closed connection") {
|
tcp_closed_connection() throw(): tcp_error("closed connection") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class tcp_read_error: public tcp_error {
|
class tcp_read_error: public tcp_error {
|
||||||
public:
|
public:
|
||||||
tcp_read_error() throw(): tcp_error("read error") {
|
tcp_read_error() throw(): tcp_error("read error") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class tcp_write_error: public tcp_error {
|
class tcp_write_error: public tcp_error {
|
||||||
public:
|
public:
|
||||||
tcp_write_error() throw(): tcp_error("write error") {
|
tcp_write_error() throw(): tcp_error("write error") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class ssl_cannot_create_context: public ssl_error {
|
class ssl_cannot_create_context: public ssl_error {
|
||||||
public:
|
public:
|
||||||
ssl_cannot_create_context() throw(): ssl_error("cannot create context") {
|
ssl_cannot_create_context() throw(): ssl_error("cannot create context") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -362,7 +342,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
ssl_certificate_file_not_loaded(const std::string& file) throw():
|
ssl_certificate_file_not_loaded(const std::string& file) throw():
|
||||||
ssl_error("certificate file not loaded: "+file) {
|
ssl_error("certificate file not loaded: "+file) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -370,7 +350,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
ssl_certificate_folder_not_loaded(const std::string& path) throw():
|
ssl_certificate_folder_not_loaded(const std::string& path) throw():
|
||||||
ssl_error("certificate folder not loaded: "+path) {
|
ssl_error("certificate folder not loaded: "+path) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -378,7 +358,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
ssl_no_connection() throw():
|
ssl_no_connection() throw():
|
||||||
ssl_error("no ssl connection") {
|
ssl_error("no ssl connection") {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -386,7 +366,7 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
ssl_verification_failed(int num) throw():
|
ssl_verification_failed(int num) throw():
|
||||||
ssl_error("certificate verification failed: "+reason(num)) {
|
ssl_error("certificate verification failed: "+reason(num)) {
|
||||||
OPENSSL_LOG("**** exception ****");
|
CRYPTOLOG("**** exception ****");
|
||||||
}
|
}
|
||||||
static std::string reason(int num) {
|
static std::string reason(int num) {
|
||||||
switch (num) {
|
switch (num) {
|
||||||
@@ -531,7 +511,7 @@ namespace openssl {
|
|||||||
class Init {
|
class Init {
|
||||||
public:
|
public:
|
||||||
Init() {
|
Init() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
ERR_load_BIO_strings();
|
ERR_load_BIO_strings();
|
||||||
OpenSSL_add_all_algorithms();
|
OpenSSL_add_all_algorithms();
|
||||||
@@ -544,30 +524,30 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
BigNum():
|
BigNum():
|
||||||
_bn(BN_new()) {
|
_bn(BN_new()) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
}
|
}
|
||||||
BigNum(const std::string& num):
|
BigNum(const std::string& num):
|
||||||
_bn(BN_bin2bn((const unsigned char*)num.data(), num.size(), 0)) {
|
_bn(BN_bin2bn((const unsigned char*)num.data(), num.size(), 0)) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
}
|
}
|
||||||
~BigNum() {
|
~BigNum() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
BN_free(_bn);
|
BN_free(_bn);
|
||||||
}
|
}
|
||||||
int size() const {
|
int size() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return size(_bn);
|
return size(_bn);
|
||||||
}
|
}
|
||||||
static int size(BIGNUM* n) {
|
static int size(BIGNUM* n) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return BN_num_bytes(n);
|
return BN_num_bytes(n);
|
||||||
}
|
}
|
||||||
std::string string() const {
|
std::string string() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return string(_bn);
|
return string(_bn);
|
||||||
}
|
}
|
||||||
static std::string string(BIGNUM* a) {
|
static std::string string(BIGNUM* a) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res(BN_num_bytes(a), '0');
|
std::string res(BN_num_bytes(a), '0');
|
||||||
BN_bn2bin(a, (unsigned char*)res.begin().operator->());
|
BN_bn2bin(a, (unsigned char*)res.begin().operator->());
|
||||||
return res;
|
return res;
|
||||||
@@ -626,7 +606,7 @@ namespace openssl {
|
|||||||
/*! @param txt text to encrypt - size must be a multiple of 8
|
/*! @param txt text to encrypt - size must be a multiple of 8
|
||||||
@param key1 DES key for encryption */
|
@param key1 DES key for encryption */
|
||||||
inline std::string desEnc(const std::string& txt, CBlock8 key1) {
|
inline std::string desEnc(const std::string& txt, CBlock8 key1) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res(txt);
|
std::string res(txt);
|
||||||
if (txt.size()%8!=0)
|
if (txt.size()%8!=0)
|
||||||
throw cannot_encrypt("text size must be a multiple of eight");
|
throw cannot_encrypt("text size must be a multiple of eight");
|
||||||
@@ -648,7 +628,7 @@ namespace openssl {
|
|||||||
/*! @param txt text to decrypt - size must be a multiple of 8
|
/*! @param txt text to decrypt - size must be a multiple of 8
|
||||||
@param key1 DES key for decryption */
|
@param key1 DES key for decryption */
|
||||||
inline std::string desDec(const std::string& txt, CBlock8 key1) {
|
inline std::string desDec(const std::string& txt, CBlock8 key1) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res(txt);
|
std::string res(txt);
|
||||||
if (txt.size()%8!=0)
|
if (txt.size()%8!=0)
|
||||||
throw cannot_encrypt("text size must be a multiple of eight");
|
throw cannot_encrypt("text size must be a multiple of eight");
|
||||||
@@ -671,7 +651,7 @@ namespace openssl {
|
|||||||
bytes, it is zero filled. The output is always an
|
bytes, it is zero filled. The output is always an
|
||||||
integral multiple of eight bytes. */
|
integral multiple of eight bytes. */
|
||||||
inline std::string desCbcEnc(std::string txt, CBlock8 key, CBlock8& ivec) {
|
inline std::string desCbcEnc(std::string txt, CBlock8 key, CBlock8& ivec) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0);
|
if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0);
|
||||||
std::string res(txt.size(), 0);
|
std::string res(txt.size(), 0);
|
||||||
DES_key_schedule ks;
|
DES_key_schedule ks;
|
||||||
@@ -686,7 +666,7 @@ namespace openssl {
|
|||||||
bytes, it is zero filled. The output is always an
|
bytes, it is zero filled. The output is always an
|
||||||
integral multiple of eight bytes. */
|
integral multiple of eight bytes. */
|
||||||
inline std::string desCbcEnc(const std::string& txt, const CBlock8& key) {
|
inline std::string desCbcEnc(const std::string& txt, const CBlock8& key) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
CBlock8 ivec;
|
CBlock8 ivec;
|
||||||
return desCbcEnc(txt, key, ivec);
|
return desCbcEnc(txt, key, ivec);
|
||||||
}
|
}
|
||||||
@@ -696,7 +676,7 @@ namespace openssl {
|
|||||||
bytes, it is zero filled. The output is always an
|
bytes, it is zero filled. The output is always an
|
||||||
integral multiple of eight bytes. */
|
integral multiple of eight bytes. */
|
||||||
inline std::string desCbcDec(std::string txt, CBlock8 key, CBlock8& ivec) {
|
inline std::string desCbcDec(std::string txt, CBlock8 key, CBlock8& ivec) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0);
|
if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0);
|
||||||
std::string res(txt.size(), 0);
|
std::string res(txt.size(), 0);
|
||||||
DES_key_schedule ks;
|
DES_key_schedule ks;
|
||||||
@@ -711,7 +691,7 @@ namespace openssl {
|
|||||||
bytes, it is zero filled. The output is always an
|
bytes, it is zero filled. The output is always an
|
||||||
integral multiple of eight bytes. */
|
integral multiple of eight bytes. */
|
||||||
inline std::string desCbcDec(const std::string& txt, const CBlock8& key) {
|
inline std::string desCbcDec(const std::string& txt, const CBlock8& key) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
CBlock8 ivec;
|
CBlock8 ivec;
|
||||||
return desCbcDec(txt, key, ivec);
|
return desCbcDec(txt, key, ivec);
|
||||||
}
|
}
|
||||||
@@ -722,7 +702,7 @@ namespace openssl {
|
|||||||
inline std::string des2edeCbcEnc(std::string txt,
|
inline std::string des2edeCbcEnc(std::string txt,
|
||||||
CBlock8 key1, CBlock8 key2,
|
CBlock8 key1, CBlock8 key2,
|
||||||
CBlock8 ivec = CBlock8()) {
|
CBlock8 ivec = CBlock8()) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0);
|
if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0);
|
||||||
std::string res(txt.size(), 0);
|
std::string res(txt.size(), 0);
|
||||||
DES_key_schedule ks1, ks2;
|
DES_key_schedule ks1, ks2;
|
||||||
@@ -739,7 +719,7 @@ namespace openssl {
|
|||||||
inline std::string des2edeCbcDec(std::string txt,
|
inline std::string des2edeCbcDec(std::string txt,
|
||||||
CBlock8 key1, CBlock8 key2,
|
CBlock8 key1, CBlock8 key2,
|
||||||
CBlock8 ivec = CBlock8()) {
|
CBlock8 ivec = CBlock8()) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0);
|
if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0);
|
||||||
std::string res(txt.size(), 0);
|
std::string res(txt.size(), 0);
|
||||||
DES_key_schedule ks1, ks2;
|
DES_key_schedule ks1, ks2;
|
||||||
@@ -753,7 +733,7 @@ namespace openssl {
|
|||||||
//! @todo untested
|
//! @todo untested
|
||||||
inline std::string des2ecbEnc(std::string txt,
|
inline std::string des2ecbEnc(std::string txt,
|
||||||
CBlock8 key1, CBlock8 key2) {
|
CBlock8 key1, CBlock8 key2) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
if (txt.size()%8!=0)
|
if (txt.size()%8!=0)
|
||||||
throw cannot_encrypt("text size must be a multiple of eight");
|
throw cannot_encrypt("text size must be a multiple of eight");
|
||||||
@@ -771,7 +751,7 @@ namespace openssl {
|
|||||||
//! @todo untested
|
//! @todo untested
|
||||||
inline std::string des2ecbDec(std::string txt,
|
inline std::string des2ecbDec(std::string txt,
|
||||||
CBlock8 key1, CBlock8 key2) {
|
CBlock8 key1, CBlock8 key2) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
std::string res;
|
std::string res;
|
||||||
if (txt.size()%8!=0)
|
if (txt.size()%8!=0)
|
||||||
throw cannot_encrypt("text size must be a multiple of eight");
|
throw cannot_encrypt("text size must be a multiple of eight");
|
||||||
@@ -792,19 +772,19 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
//! Construct empty certificate.
|
//! Construct empty certificate.
|
||||||
X509(): _x509(X509_new()) {
|
X509(): _x509(X509_new()) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (!_x509) throw allocation_failed();
|
if (!_x509) throw allocation_failed();
|
||||||
}
|
}
|
||||||
//! Initialize from DER encoded cerificate.
|
//! Initialize from DER encoded cerificate.
|
||||||
X509(const std::string& der): _x509(0) {
|
X509(const std::string& der): _x509(0) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
V0_CONST unsigned char* c((unsigned char*)der.begin().operator->());
|
V0_CONST unsigned char* c((unsigned char*)der.begin().operator->());
|
||||||
if (!(_x509=d2i_X509(0, &c, der.size())) ||
|
if (!(_x509=d2i_X509(0, &c, der.size())) ||
|
||||||
(const char*)c!=der.begin().operator->()+der.size())
|
(const char*)c!=der.begin().operator->()+der.size())
|
||||||
throw x509_decoding_failed(der);
|
throw x509_decoding_failed(der);
|
||||||
}
|
}
|
||||||
X509(const X509& o): _x509(0) {
|
X509(const X509& o): _x509(0) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
_x509 = X509_dup(o._x509);
|
_x509 = X509_dup(o._x509);
|
||||||
// unsigned char* d(0);
|
// unsigned char* d(0);
|
||||||
// int len(i2d_X509(o._x509, &d));
|
// int len(i2d_X509(o._x509, &d));
|
||||||
@@ -816,15 +796,15 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Take over OpenSSL allocated certificate.
|
//! Take over OpenSSL allocated certificate.
|
||||||
X509(::X509 *x509): _x509(x509) {
|
X509(::X509 *x509): _x509(x509) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (!_x509) throw undefined_certificate();
|
if (!_x509) throw undefined_certificate();
|
||||||
}
|
}
|
||||||
~X509() {
|
~X509() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
X509_free(_x509);
|
X509_free(_x509);
|
||||||
}
|
}
|
||||||
X509& operator=(const X509& o) {
|
X509& operator=(const X509& o) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
X509_free(_x509);
|
X509_free(_x509);
|
||||||
_x509 = 0;
|
_x509 = 0;
|
||||||
_x509 = X509_dup(o._x509);
|
_x509 = X509_dup(o._x509);
|
||||||
@@ -843,7 +823,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Get DER encoded subject.
|
//! Get DER encoded subject.
|
||||||
std::string subjectDER() const {
|
std::string subjectDER() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
unsigned char* c(0);
|
unsigned char* c(0);
|
||||||
int len(i2d_X509_NAME(X509_get_subject_name(_x509), &c));
|
int len(i2d_X509_NAME(X509_get_subject_name(_x509), &c));
|
||||||
std::string res((char*)c, len);
|
std::string res((char*)c, len);
|
||||||
@@ -852,7 +832,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Get DER encoded issuer.
|
//! Get DER encoded issuer.
|
||||||
std::string issuerDER() const {
|
std::string issuerDER() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
unsigned char* c(0);
|
unsigned char* c(0);
|
||||||
int len(i2d_X509_NAME(X509_get_issuer_name(_x509), &c));
|
int len(i2d_X509_NAME(X509_get_issuer_name(_x509), &c));
|
||||||
std::string res((char*)c, len);
|
std::string res((char*)c, len);
|
||||||
@@ -861,7 +841,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Get DER encoded value.
|
//! Get DER encoded value.
|
||||||
std::string valueDER() const {
|
std::string valueDER() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
unsigned char* c(0);
|
unsigned char* c(0);
|
||||||
int len(i2d_X509(_x509, &c));
|
int len(i2d_X509(_x509, &c));
|
||||||
std::string res((char*)c, len);
|
std::string res((char*)c, len);
|
||||||
@@ -870,7 +850,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Get serial number.
|
//! Get serial number.
|
||||||
std::string serial() const {
|
std::string serial() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
/* @bug tcp://albistechnologies.com reports: «could be a
|
/* @bug tcp://albistechnologies.com reports: «could be a
|
||||||
failure in openSSL: len too short by 1 if serial number
|
failure in openSSL: len too short by 1 if serial number
|
||||||
starts with 00 ASN1_INTEGER* ser =
|
starts with 00 ASN1_INTEGER* ser =
|
||||||
@@ -894,7 +874,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Get id.
|
//! Get id.
|
||||||
std::string id() const {
|
std::string id() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
unsigned char c[SHA_DIGEST_LENGTH];
|
unsigned char c[SHA_DIGEST_LENGTH];
|
||||||
SHA1(_x509->cert_info->key->public_key->data,
|
SHA1(_x509->cert_info->key->public_key->data,
|
||||||
_x509->cert_info->key->public_key->length,
|
_x509->cert_info->key->public_key->length,
|
||||||
@@ -903,7 +883,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Get common name.
|
//! Get common name.
|
||||||
std::string commonName() const {
|
std::string commonName() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
X509_NAME *name(X509_get_subject_name(_x509));
|
X509_NAME *name(X509_get_subject_name(_x509));
|
||||||
ASN1_STRING* cn
|
ASN1_STRING* cn
|
||||||
(X509_NAME_ENTRY_get_data
|
(X509_NAME_ENTRY_get_data
|
||||||
@@ -914,7 +894,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Get country name.
|
//! Get country name.
|
||||||
std::string countryName() const {
|
std::string countryName() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
X509_NAME *name(X509_get_subject_name(_x509));
|
X509_NAME *name(X509_get_subject_name(_x509));
|
||||||
ASN1_STRING* cn
|
ASN1_STRING* cn
|
||||||
(X509_NAME_ENTRY_get_data
|
(X509_NAME_ENTRY_get_data
|
||||||
@@ -925,7 +905,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Get locality name.
|
//! Get locality name.
|
||||||
std::string localityName() const {
|
std::string localityName() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
X509_NAME *name(X509_get_subject_name(_x509));
|
X509_NAME *name(X509_get_subject_name(_x509));
|
||||||
ASN1_STRING* cn
|
ASN1_STRING* cn
|
||||||
(X509_NAME_ENTRY_get_data
|
(X509_NAME_ENTRY_get_data
|
||||||
@@ -936,7 +916,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Get state or province name.
|
//! Get state or province name.
|
||||||
std::string stateOrProvinceName() const {
|
std::string stateOrProvinceName() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
X509_NAME *name(X509_get_subject_name(_x509));
|
X509_NAME *name(X509_get_subject_name(_x509));
|
||||||
ASN1_STRING* cn
|
ASN1_STRING* cn
|
||||||
(X509_NAME_ENTRY_get_data
|
(X509_NAME_ENTRY_get_data
|
||||||
@@ -948,7 +928,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Get organization name.
|
//! Get organization name.
|
||||||
std::string organizationName() const {
|
std::string organizationName() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
X509_NAME *name(X509_get_subject_name(_x509));
|
X509_NAME *name(X509_get_subject_name(_x509));
|
||||||
ASN1_STRING* cn
|
ASN1_STRING* cn
|
||||||
(X509_NAME_ENTRY_get_data
|
(X509_NAME_ENTRY_get_data
|
||||||
@@ -960,7 +940,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Check whether it's a CA certificate.
|
//! Check whether it's a CA certificate.
|
||||||
bool isCa() {
|
bool isCa() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
BASIC_CONSTRAINTS* bc(0);
|
BASIC_CONSTRAINTS* bc(0);
|
||||||
int pos(X509_get_ext_by_NID(_x509, NID_basic_constraints, -1));
|
int pos(X509_get_ext_by_NID(_x509, NID_basic_constraints, -1));
|
||||||
if (pos>=0)
|
if (pos>=0)
|
||||||
@@ -969,7 +949,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Get organizational unit name.
|
//! Get organizational unit name.
|
||||||
std::string organizationalUnitName() const {
|
std::string organizationalUnitName() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
X509_NAME *name(X509_get_subject_name(_x509));
|
X509_NAME *name(X509_get_subject_name(_x509));
|
||||||
ASN1_STRING* cn
|
ASN1_STRING* cn
|
||||||
(X509_NAME_ENTRY_get_data
|
(X509_NAME_ENTRY_get_data
|
||||||
@@ -981,7 +961,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
//! Get key usage flags.
|
//! Get key usage flags.
|
||||||
int keyUsageFlags() const {
|
int keyUsageFlags() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
int res(X509v3_KU_UNDEF);
|
int res(X509v3_KU_UNDEF);
|
||||||
int pos(X509_get_ext_by_NID(_x509, NID_key_usage, -1));
|
int pos(X509_get_ext_by_NID(_x509, NID_key_usage, -1));
|
||||||
if (pos>=0) {
|
if (pos>=0) {
|
||||||
@@ -1005,61 +985,61 @@ namespace openssl {
|
|||||||
class PrivateKey {
|
class PrivateKey {
|
||||||
public:
|
public:
|
||||||
PrivateKey(): _key(EVP_PKEY_new()) {
|
PrivateKey(): _key(EVP_PKEY_new()) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (!_key) throw allocation_failed();
|
if (!_key) throw allocation_failed();
|
||||||
}
|
}
|
||||||
PrivateKey(const PrivateKey& o): _key(0) {
|
PrivateKey(const PrivateKey& o): _key(0) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
copy(o);
|
copy(o);
|
||||||
}
|
}
|
||||||
PrivateKey(EVP_PKEY* k): _key(k) {
|
PrivateKey(EVP_PKEY* k): _key(k) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (!_key) throw undefined_key();
|
if (!_key) throw undefined_key();
|
||||||
}
|
}
|
||||||
~PrivateKey() {
|
~PrivateKey() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
EVP_PKEY_free(_key);
|
EVP_PKEY_free(_key);
|
||||||
}
|
}
|
||||||
PrivateKey& operator=(const PrivateKey& o) {
|
PrivateKey& operator=(const PrivateKey& o) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
copy(o);
|
copy(o);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
std::string modulus() const {
|
std::string modulus() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return BigNum::string(rsa()->n);
|
return BigNum::string(rsa()->n);
|
||||||
}
|
}
|
||||||
std::string publicExponent() const {
|
std::string publicExponent() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return BigNum::string(rsa()->e);
|
return BigNum::string(rsa()->e);
|
||||||
}
|
}
|
||||||
std::string privateExponent() const {
|
std::string privateExponent() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return BigNum::string(rsa()->d);
|
return BigNum::string(rsa()->d);
|
||||||
}
|
}
|
||||||
std::string prime1() const {
|
std::string prime1() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return BigNum::string(rsa()->p);
|
return BigNum::string(rsa()->p);
|
||||||
}
|
}
|
||||||
std::string prime2() const {
|
std::string prime2() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return BigNum::string(rsa()->q);
|
return BigNum::string(rsa()->q);
|
||||||
}
|
}
|
||||||
std::string exponent1() const {
|
std::string exponent1() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return BigNum::string(rsa()->dmp1);
|
return BigNum::string(rsa()->dmp1);
|
||||||
}
|
}
|
||||||
std::string exponent2() const {
|
std::string exponent2() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return BigNum::string(rsa()->dmq1);
|
return BigNum::string(rsa()->dmq1);
|
||||||
}
|
}
|
||||||
std::string coefficient() const {
|
std::string coefficient() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return BigNum::string(rsa()->iqmp);
|
return BigNum::string(rsa()->iqmp);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void copy(const PrivateKey& o) {
|
void copy(const PrivateKey& o) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
EVP_PKEY_free(_key);
|
EVP_PKEY_free(_key);
|
||||||
if (!(_key=EVP_PKEY_new())) throw allocation_failed();
|
if (!(_key=EVP_PKEY_new())) throw allocation_failed();
|
||||||
rsa(o);
|
rsa(o);
|
||||||
@@ -1068,44 +1048,44 @@ namespace openssl {
|
|||||||
/*ec(o);*/
|
/*ec(o);*/
|
||||||
}
|
}
|
||||||
void rsa(const PrivateKey& o) {
|
void rsa(const PrivateKey& o) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! @todo throw exception if 0?
|
//! @todo throw exception if 0?
|
||||||
RSA* tmp(o.rsa());
|
RSA* tmp(o.rsa());
|
||||||
if (tmp&&!EVP_PKEY_set1_RSA(_key, tmp)) throw key_copy_failed();
|
if (tmp&&!EVP_PKEY_set1_RSA(_key, tmp)) throw key_copy_failed();
|
||||||
}
|
}
|
||||||
void dsa(const PrivateKey& o) {
|
void dsa(const PrivateKey& o) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
DSA* tmp(o.dsa());
|
DSA* tmp(o.dsa());
|
||||||
if (tmp&&!EVP_PKEY_set1_DSA(_key, tmp)) throw key_copy_failed();
|
if (tmp&&!EVP_PKEY_set1_DSA(_key, tmp)) throw key_copy_failed();
|
||||||
}
|
}
|
||||||
void dh(const PrivateKey& o) {
|
void dh(const PrivateKey& o) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
DH* tmp(o.dh());
|
DH* tmp(o.dh());
|
||||||
if (tmp&&!EVP_PKEY_set1_DH(_key, tmp)) throw key_copy_failed();
|
if (tmp&&!EVP_PKEY_set1_DH(_key, tmp)) throw key_copy_failed();
|
||||||
}
|
}
|
||||||
/* Not available on mac osx
|
/* Not available on mac osx
|
||||||
void ec(const PrivateKey& o) {
|
void ec(const PrivateKey& o) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
EC_KEY* tmp(o.ec());
|
EC_KEY* tmp(o.ec());
|
||||||
if (tmp&&!EVP_PKEY_set1_EC_KEY(_key, tmp)) throw key_copy_failed();
|
if (tmp&&!EVP_PKEY_set1_EC_KEY(_key, tmp)) throw key_copy_failed();
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
RSA* rsa() const {
|
RSA* rsa() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
//! @todo throw exception if 0?
|
//! @todo throw exception if 0?
|
||||||
return EVP_PKEY_get1_RSA(_key);
|
return EVP_PKEY_get1_RSA(_key);
|
||||||
}
|
}
|
||||||
DSA* dsa() const {
|
DSA* dsa() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return EVP_PKEY_get1_DSA(_key);
|
return EVP_PKEY_get1_DSA(_key);
|
||||||
}
|
}
|
||||||
DH* dh() const {
|
DH* dh() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return EVP_PKEY_get1_DH(_key);
|
return EVP_PKEY_get1_DH(_key);
|
||||||
}
|
}
|
||||||
/* Not available on mac osx
|
/* Not available on mac osx
|
||||||
EC_KEY* ec() const {
|
EC_KEY* ec() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return EVP_PKEY_get1_EC_KEY(_key);
|
return EVP_PKEY_get1_EC_KEY(_key);
|
||||||
}*/
|
}*/
|
||||||
EVP_PKEY* _key;
|
EVP_PKEY* _key;
|
||||||
@@ -1125,7 +1105,7 @@ namespace openssl {
|
|||||||
//! Read from a PKCS#12 (.p12) file.
|
//! Read from a PKCS#12 (.p12) file.
|
||||||
PKCS12(std::string filename, std::string password):
|
PKCS12(std::string filename, std::string password):
|
||||||
_key(0), _cert(0) {
|
_key(0), _cert(0) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
FILE* file(fopen(filename.c_str(), "rb"));
|
FILE* file(fopen(filename.c_str(), "rb"));
|
||||||
if (!file) throw cannot_open_file(filename);
|
if (!file) throw cannot_open_file(filename);
|
||||||
::PKCS12 *p12(d2i_PKCS12_fp(file, 0));
|
::PKCS12 *p12(d2i_PKCS12_fp(file, 0));
|
||||||
@@ -1149,7 +1129,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
~PKCS12() {
|
~PKCS12() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
delete _key;
|
delete _key;
|
||||||
delete _cert;
|
delete _cert;
|
||||||
for (X509List::iterator it(_ca.begin()); it!=_ca.end(); ++it)
|
for (X509List::iterator it(_ca.begin()); it!=_ca.end(); ++it)
|
||||||
@@ -1157,29 +1137,29 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool hasPrivateKey() const {
|
bool hasPrivateKey() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return _key;
|
return _key;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasCert() const {
|
bool hasCert() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return _cert;
|
return _cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PrivateKey& privateKey() const {
|
const PrivateKey& privateKey() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (!_key) throw pkcs12_no_private_key();
|
if (!_key) throw pkcs12_no_private_key();
|
||||||
return *_key;
|
return *_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
const X509& x509() const {
|
const X509& x509() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (!_cert) throw pkcs12_no_x509();
|
if (!_cert) throw pkcs12_no_x509();
|
||||||
return *_cert;
|
return *_cert;
|
||||||
};
|
};
|
||||||
|
|
||||||
const X509List& ca() const {
|
const X509List& ca() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return _ca;
|
return _ca;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1222,7 +1202,7 @@ namespace openssl {
|
|||||||
|
|
||||||
//! Read PKCS#7 from memory.
|
//! Read PKCS#7 from memory.
|
||||||
PKCS7(const std::string& memory) {
|
PKCS7(const std::string& memory) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
BIO* mem(BIO_new_mem_buf((void*)memory.data(), memory.size()));
|
BIO* mem(BIO_new_mem_buf((void*)memory.data(), memory.size()));
|
||||||
::PKCS7 *p7(d2i_PKCS7_bio(mem, 0));
|
::PKCS7 *p7(d2i_PKCS7_bio(mem, 0));
|
||||||
BIO_free(mem);
|
BIO_free(mem);
|
||||||
@@ -1240,13 +1220,13 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
~PKCS7() {
|
~PKCS7() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
for (X509List::iterator it(_certs.begin()); it!=_certs.end(); ++it)
|
for (X509List::iterator it(_certs.begin()); it!=_certs.end(); ++it)
|
||||||
delete *it;
|
delete *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
const X509List& certs() const {
|
const X509List& certs() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return _certs;
|
return _certs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1266,16 +1246,16 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
TCP(): _bio(0) {
|
TCP(): _bio(0) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
}
|
}
|
||||||
|
|
||||||
TCP(const std::string& hostPort): _bio(0) {
|
TCP(const std::string& hostPort): _bio(0) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
connect(hostPort);
|
connect(hostPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~TCP() {
|
virtual ~TCP() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
try {
|
try {
|
||||||
close();
|
close();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -1284,7 +1264,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual TCP& connect(const std::string& hostPort) {
|
virtual TCP& connect(const std::string& hostPort) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
close();
|
close();
|
||||||
if (!(_bio=BIO_new_connect(const_cast<char*>(hostPort.c_str()))) ||
|
if (!(_bio=BIO_new_connect(const_cast<char*>(hostPort.c_str()))) ||
|
||||||
BIO_do_connect(_bio)<=0)
|
BIO_do_connect(_bio)<=0)
|
||||||
@@ -1301,18 +1281,18 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const {
|
operator bool() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return _bio>0;
|
return _bio>0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TCP& operator>>(std::string& s) {
|
TCP& operator>>(std::string& s) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
s += read();
|
s += read();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TCP& operator<<(const std::string& s) {
|
TCP& operator<<(const std::string& s) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return write(s);
|
return write(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1321,7 +1301,7 @@ namespace openssl {
|
|||||||
server is waiting for next request, but connection is still
|
server is waiting for next request, but connection is still
|
||||||
open? */
|
open? */
|
||||||
std::string read() {
|
std::string read() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (_bio<=0) throw tcp_closed_connection();
|
if (_bio<=0) throw tcp_closed_connection();
|
||||||
const int BUFF_SZ(1024);
|
const int BUFF_SZ(1024);
|
||||||
char buff[BUFF_SZ];
|
char buff[BUFF_SZ];
|
||||||
@@ -1338,7 +1318,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TCP& write(const std::string& s) {
|
TCP& write(const std::string& s) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (_bio<=0) throw tcp_closed_connection();
|
if (_bio<=0) throw tcp_closed_connection();
|
||||||
unsigned int x(BIO_write(_bio, s.begin().operator->(), s.size()));
|
unsigned int x(BIO_write(_bio, s.begin().operator->(), s.size()));
|
||||||
if (x<=0)
|
if (x<=0)
|
||||||
@@ -1352,7 +1332,7 @@ namespace openssl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual TCP& close() {
|
virtual TCP& close() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (_bio>0) BIO_free_all(_bio);
|
if (_bio>0) BIO_free_all(_bio);
|
||||||
_bio = 0;
|
_bio = 0;
|
||||||
return *this;
|
return *this;
|
||||||
@@ -1370,10 +1350,10 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
TrustStore(const std::string& pathToPemFile):
|
TrustStore(const std::string& pathToPemFile):
|
||||||
_file(pathToPemFile) {
|
_file(pathToPemFile) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
}
|
}
|
||||||
const std::string& file() const {
|
const std::string& file() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return _file;
|
return _file;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
@@ -1384,10 +1364,10 @@ namespace openssl {
|
|||||||
public:
|
public:
|
||||||
CertificateFolder(const std::string& certificateFolder):
|
CertificateFolder(const std::string& certificateFolder):
|
||||||
_path(certificateFolder) {
|
_path(certificateFolder) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
}
|
}
|
||||||
const std::string& path() const {
|
const std::string& path() const {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
return _path;
|
return _path;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
@@ -1403,7 +1383,7 @@ namespace openssl {
|
|||||||
SSL(const TrustStore& file):
|
SSL(const TrustStore& file):
|
||||||
_ctx(SSL_CTX_new(SSLv23_client_method())),
|
_ctx(SSL_CTX_new(SSLv23_client_method())),
|
||||||
_ssl(0) {
|
_ssl(0) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (!_ctx) throw ssl_cannot_create_context();
|
if (!_ctx) throw ssl_cannot_create_context();
|
||||||
if (!SSL_CTX_load_verify_locations(_ctx, file.file().c_str(), 0))
|
if (!SSL_CTX_load_verify_locations(_ctx, file.file().c_str(), 0))
|
||||||
throw ssl_certificate_file_not_loaded(file.file());
|
throw ssl_certificate_file_not_loaded(file.file());
|
||||||
@@ -1411,18 +1391,18 @@ namespace openssl {
|
|||||||
SSL(const CertificateFolder& folder):
|
SSL(const CertificateFolder& folder):
|
||||||
_ctx(SSL_CTX_new(SSLv23_client_method())),
|
_ctx(SSL_CTX_new(SSLv23_client_method())),
|
||||||
_ssl(0) {
|
_ssl(0) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (!_ctx) throw ssl_cannot_create_context();
|
if (!_ctx) throw ssl_cannot_create_context();
|
||||||
if (!SSL_CTX_load_verify_locations(_ctx, 0, folder.path().c_str()))
|
if (!SSL_CTX_load_verify_locations(_ctx, 0, folder.path().c_str()))
|
||||||
throw ssl_certificate_folder_not_loaded(folder.path());
|
throw ssl_certificate_folder_not_loaded(folder.path());
|
||||||
}
|
}
|
||||||
~SSL() {
|
~SSL() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
close();
|
close();
|
||||||
SSL_CTX_free(_ctx);
|
SSL_CTX_free(_ctx);
|
||||||
}
|
}
|
||||||
virtual SSL& connect(const std::string& hostPort) {
|
virtual SSL& connect(const std::string& hostPort) {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
close();
|
close();
|
||||||
if (!(_bio=BIO_new_ssl_connect(_ctx)))
|
if (!(_bio=BIO_new_ssl_connect(_ctx)))
|
||||||
throw tcp_connection_failed(hostPort);
|
throw tcp_connection_failed(hostPort);
|
||||||
@@ -1436,14 +1416,14 @@ namespace openssl {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
virtual SSL& close() {
|
virtual SSL& close() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
TCP::close();
|
TCP::close();
|
||||||
_ssl = 0; //! @todo is this correct? <--
|
_ssl = 0; //! @todo is this correct? <--
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
void verify() {
|
void verify() {
|
||||||
OPENSSL_LOG("log");
|
CRYPTOLOG("log");
|
||||||
if (!_ssl) throw ssl_no_connection();
|
if (!_ssl) throw ssl_no_connection();
|
||||||
int res(SSL_get_verify_result(_ssl));
|
int res(SSL_get_verify_result(_ssl));
|
||||||
if (res!=X509_V_OK) throw ssl_verification_failed(res);
|
if (res!=X509_V_OK) throw ssl_verification_failed(res);
|
||||||
|
87
src/pcsc.hxx
87
src/pcsc.hxx
@@ -10,25 +10,6 @@
|
|||||||
#ifndef PCSC_HXX
|
#ifndef PCSC_HXX
|
||||||
#define PCSC_HXX
|
#define PCSC_HXX
|
||||||
|
|
||||||
#ifndef PCSC_LOG
|
|
||||||
//! Declare PCSC_LOG before #include in your de, 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 <cryptaux.hxx>
|
||||||
|
|
||||||
#include <mrw/shared.hxx>
|
#include <mrw/shared.hxx>
|
||||||
@@ -132,7 +113,9 @@ namespace pcsc {
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class exception: public std::exception {
|
class exception: public std::exception {
|
||||||
public:
|
public:
|
||||||
exception(const std::string& reason) throw(): _what("pcsc: "+reason) {}
|
exception(const std::string& reason) throw(): _what("pcsc: "+reason) {
|
||||||
|
CRYPTOLOG("ERROR: "<<what());
|
||||||
|
}
|
||||||
~exception() throw() {}
|
~exception() throw() {}
|
||||||
const char* what() const throw() {
|
const char* what() const throw() {
|
||||||
return _what.c_str();
|
return _what.c_str();
|
||||||
@@ -144,21 +127,28 @@ namespace pcsc {
|
|||||||
class not_implemented: public exception {
|
class not_implemented: public exception {
|
||||||
public:
|
public:
|
||||||
not_implemented(const std::string& reason) throw():
|
not_implemented(const std::string& reason) throw():
|
||||||
exception("feature is not implemented:\n"+reason) {
|
exception("feature is not implemented: "+reason) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class access_error: public exception {
|
class access_error: public exception {
|
||||||
public:
|
public:
|
||||||
access_error(const std::string& reason) throw():
|
access_error(const std::string& reason) throw():
|
||||||
exception("smardcard access error:\n"+reason) {
|
exception("smardcard access error: "+reason) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
class wrong_pin: public access_error {
|
||||||
|
public:
|
||||||
|
wrong_pin(const std::string& reason) throw():
|
||||||
|
access_error("wrong pin: "+reason) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class runtime_error: public exception {
|
class runtime_error: public exception {
|
||||||
public:
|
public:
|
||||||
runtime_error(const std::string& reason, const std::string& data) throw():
|
runtime_error(const std::string& reason, const std::string& data) throw():
|
||||||
exception("runtime error,\n"+reason+":\n"+crypto::hex(data)) {}
|
exception("runtime error, "+reason+": "+crypto::hex(data)) {}
|
||||||
};
|
};
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class neesting_error: public exception {
|
class neesting_error: public exception {
|
||||||
@@ -216,10 +206,12 @@ namespace pcsc {
|
|||||||
destructor und must therefore live longer than the
|
destructor und must therefore live longer than the
|
||||||
Transaction instance. */
|
Transaction instance. */
|
||||||
Transaction(mrw::Shared<Reader> r): _reader(r), _running(true) {
|
Transaction(mrw::Shared<Reader> r): _reader(r), _running(true) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
_reader->beginTransaction();
|
_reader->beginTransaction();
|
||||||
}
|
}
|
||||||
//! Cancels the transaction if not yet finished.
|
//! Cancels the transaction if not yet finished.
|
||||||
~Transaction() try {
|
~Transaction() try {
|
||||||
|
CRYPTOLOG("log");
|
||||||
end();
|
end();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
if (!std::uncaught_exception()) throw;
|
if (!std::uncaught_exception()) throw;
|
||||||
@@ -247,6 +239,7 @@ namespace pcsc {
|
|||||||
|
|
||||||
//! Disconnects connection.
|
//! Disconnects connection.
|
||||||
~Reader() {
|
~Reader() {
|
||||||
|
CRYPTOLOG("Disconnect Reader");
|
||||||
_state = SCardDisconnect(_id, SCARD_RESET_CARD);
|
_state = SCardDisconnect(_id, SCARD_RESET_CARD);
|
||||||
if (!std::uncaught_exception())
|
if (!std::uncaught_exception())
|
||||||
_connection->check("disconnect smartcard");
|
_connection->check("disconnect smartcard");
|
||||||
@@ -328,13 +321,13 @@ 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);
|
||||||
// don't log; could log pins
|
// log only in verbose debuggung; could log pins
|
||||||
//PCSC_LOG("SCardTransmit: "<<crypto::hex(in));
|
CRYPTOLOG_VERBOSE("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)));
|
//CRYPTOLOG(" -> "<<crypto::hex(std::string((char*)buff, len)));
|
||||||
return std::string((char*)buff, len);
|
return std::string((char*)buff, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,13 +339,13 @@ namespace pcsc {
|
|||||||
std::string in) {
|
std::string in) {
|
||||||
DWORD len(256); // arbitrary
|
DWORD len(256); // arbitrary
|
||||||
UCHAR dataBuffer[256];
|
UCHAR dataBuffer[256];
|
||||||
PCSC_LOG("SCardControl: "<<"Command: "<<controlCode);
|
CRYPTOLOG("SCardControl: "<<"Command: "<<controlCode);
|
||||||
PCSC_LOG(" -> "<<crypto::hex(in));
|
CRYPTOLOG(" -> "<<crypto::hex(in));
|
||||||
check(SCardControl(_id, controlCode,
|
check(SCardControl(_id, controlCode,
|
||||||
(unsigned char*)in.c_str(), in.size(),
|
(unsigned char*)in.c_str(), in.size(),
|
||||||
dataBuffer, sizeof(dataBuffer), &len),
|
dataBuffer, sizeof(dataBuffer), &len),
|
||||||
"smartcard control message sent");
|
"smartcard control message sent");
|
||||||
PCSC_LOG(" -> "<<crypto::hex(std::string((char*)dataBuffer, len)));
|
CRYPTOLOG(" -> "<<crypto::hex(std::string((char*)dataBuffer, len)));
|
||||||
return std::string((char*)dataBuffer, len);
|
return std::string((char*)dataBuffer, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,8 +380,10 @@ namespace pcsc {
|
|||||||
/*! Calls @c SCardBeginTransaction unless it's already inside
|
/*! Calls @c SCardBeginTransaction unless it's already inside
|
||||||
a transaction. */
|
a transaction. */
|
||||||
void beginTransaction() {
|
void beginTransaction() {
|
||||||
if (++_neesting==1)
|
if (++_neesting==1) {
|
||||||
|
CRYPTOLOG("open transaction");
|
||||||
check(SCardBeginTransaction(_id), "smartcard begin transaction");
|
check(SCardBeginTransaction(_id), "smartcard begin transaction");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Use scoped transactions with @ref Transaction
|
//! Use scoped transactions with @ref Transaction
|
||||||
@@ -397,10 +392,11 @@ namespace pcsc {
|
|||||||
@throws neesting_error if there are more calls to @c
|
@throws neesting_error if there are more calls to @c
|
||||||
endTransaction than to @c beginTransaction. */
|
endTransaction than to @c beginTransaction. */
|
||||||
void endTransaction() {
|
void endTransaction() {
|
||||||
if (--_neesting==0)
|
if (--_neesting==0) {
|
||||||
|
CRYPTOLOG("close transaction");
|
||||||
check(SCardEndTransaction(_id, SCARD_LEAVE_CARD),
|
check(SCardEndTransaction(_id, SCARD_LEAVE_CARD),
|
||||||
"smartcard end transaction");
|
"smartcard end transaction");
|
||||||
else if (_neesting<0) {
|
} else if (_neesting<0) {
|
||||||
_neesting = 0;
|
_neesting = 0;
|
||||||
throw neesting_error();
|
throw neesting_error();
|
||||||
}
|
}
|
||||||
@@ -432,6 +428,7 @@ namespace pcsc {
|
|||||||
DWORD mode=SCARD_SHARE_SHARED,
|
DWORD mode=SCARD_SHARE_SHARED,
|
||||||
DWORD protocol=SCARD_PROTOCOL_T1):
|
DWORD protocol=SCARD_PROTOCOL_T1):
|
||||||
name(nm), _connection(c) {
|
name(nm), _connection(c) {
|
||||||
|
CRYPTOLOG("Connect Reader");
|
||||||
check(SCardConnect(_connection->id(), strconv(name).c_str(),
|
check(SCardConnect(_connection->id(), strconv(name).c_str(),
|
||||||
mode, protocol,
|
mode, protocol,
|
||||||
&_id, &_protocol),
|
&_id, &_protocol),
|
||||||
@@ -513,7 +510,7 @@ 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);
|
CRYPTOLOG("size of readers: "<<num);
|
||||||
if (!num) return res;
|
if (!num) return res;
|
||||||
std::auto_ptr<char_t> nm(new char_t[num]);
|
std::auto_ptr<char_t> nm(new char_t[num]);
|
||||||
if (!check(SCardListReaders(_connectionlifetime->id(),
|
if (!check(SCardListReaders(_connectionlifetime->id(),
|
||||||
@@ -521,9 +518,9 @@ namespace pcsc {
|
|||||||
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);
|
CRYPTOLOG("got all readers, size is "<<num);
|
||||||
if (!num) return res;
|
if (!num) return res;
|
||||||
PCSC_LOG("list of readers: "
|
CRYPTOLOG("list of readers: "
|
||||||
<<crypto::readable(std::string(nm.get(), num-1)));
|
<<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)));
|
||||||
}
|
}
|
||||||
@@ -620,10 +617,12 @@ namespace pcsc {
|
|||||||
ConnectionLifetime(Scope s, bool exc):
|
ConnectionLifetime(Scope s, bool exc):
|
||||||
_exc(exc), _id(0),
|
_exc(exc), _id(0),
|
||||||
_state(SCardEstablishContext(s, 0, 0, &_id)) {
|
_state(SCardEstablishContext(s, 0, 0, &_id)) {
|
||||||
|
CRYPTOLOG("Open Connection");
|
||||||
check("establish smartcard context");
|
check("establish smartcard context");
|
||||||
}
|
}
|
||||||
//! Closes the connection (releases the smartcard context)
|
//! Closes the connection (releases the smartcard context)
|
||||||
~ConnectionLifetime() {
|
~ConnectionLifetime() {
|
||||||
|
CRYPTOLOG("Close Connection");
|
||||||
_state = SCardReleaseContext(_id);
|
_state = SCardReleaseContext(_id);
|
||||||
if (!std::uncaught_exception()) check("smartcard release context");
|
if (!std::uncaught_exception()) check("smartcard release context");
|
||||||
}
|
}
|
||||||
@@ -641,9 +640,15 @@ namespace pcsc {
|
|||||||
bool check(const std::string& context="") {
|
bool check(const std::string& context="") {
|
||||||
if (_exc&&!*this)
|
if (_exc&&!*this)
|
||||||
if (context.size())
|
if (context.size())
|
||||||
throw access_error(context+": "+error());
|
if (_state==SCARD_W_WRONG_CHV)
|
||||||
|
throw wrong_pin(context+": "+error());
|
||||||
|
else
|
||||||
|
throw access_error(context+": "+error());
|
||||||
else
|
else
|
||||||
throw access_error(error());
|
if (_state==SCARD_W_WRONG_CHV)
|
||||||
|
throw wrong_pin(error());
|
||||||
|
else
|
||||||
|
throw access_error(error());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -721,8 +726,8 @@ namespace pcsc {
|
|||||||
ss<<"The smart card resource manager has shut down.";
|
ss<<"The smart card resource manager has shut down.";
|
||||||
break;
|
break;
|
||||||
case SCARD_E_SHARING_VIOLATION:
|
case SCARD_E_SHARING_VIOLATION:
|
||||||
ss<<"The smart card cannot be accessed because of other outstanding"
|
ss<<"The smart card cannot be accessed because of other"
|
||||||
<<" connections.";
|
<<" outstanding connections.";
|
||||||
break;
|
break;
|
||||||
case SCARD_E_SYSTEM_CANCELLED:
|
case SCARD_E_SYSTEM_CANCELLED:
|
||||||
ss<<"The action was cancelled by the system, presumably to log"
|
ss<<"The action was cancelled by the system, presumably to log"
|
||||||
@@ -757,8 +762,8 @@ namespace pcsc {
|
|||||||
ss<<"No error was encountered.";
|
ss<<"No error was encountered.";
|
||||||
break;
|
break;
|
||||||
case SCARD_W_REMOVED_CARD:
|
case SCARD_W_REMOVED_CARD:
|
||||||
ss<<"The smart card has been removed, so that further communication"
|
ss<<"The smart card has been removed, so that further"
|
||||||
<<" is not possible.";
|
<<" communication is not possible.";
|
||||||
break;
|
break;
|
||||||
case SCARD_W_RESET_CARD:
|
case SCARD_W_RESET_CARD:
|
||||||
ss<<"The smart card was reset.";
|
ss<<"The smart card was reset.";
|
||||||
|
222
src/suisseid.hxx
222
src/suisseid.hxx
@@ -82,19 +82,29 @@ namespace suisseid {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Status {
|
enum CertStatus {
|
||||||
TRANSPORT
|
MISSING,
|
||||||
|
EXPIRES_SOON,
|
||||||
|
EXPIRED,
|
||||||
|
REVOKED,
|
||||||
|
VALID
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Card(mrw::Shared<pcsc::Connection::Reader> reader,
|
Card(mrw::Shared<pcsc::Connection::Reader> reader,
|
||||||
mrw::Shared<cryptoki::Slot> slot):
|
const cryptoki::Library& cryptoki):
|
||||||
cardos::Commands(reader),
|
cardos::Commands(reader),
|
||||||
_slot(slot) {
|
_cryptoki(cryptoki) {
|
||||||
}
|
}
|
||||||
virtual ~Card() {}
|
virtual ~Card() {}
|
||||||
|
|
||||||
|
cryptoki::Slot slot() {
|
||||||
|
cryptoki::SlotList slots(_cryptoki.slotList(true, name()));
|
||||||
|
if (slots.size()==1) return slots[0];
|
||||||
|
throw std::runtime_error("matching cryptoki slot not found");
|
||||||
|
}
|
||||||
|
|
||||||
virtual unsigned int minimalPinLength() = 0;
|
virtual unsigned int minimalPinLength() = 0;
|
||||||
virtual unsigned int maximalPinLength() = 0;
|
virtual unsigned int maximalPinLength() = 0;
|
||||||
|
|
||||||
@@ -108,22 +118,27 @@ namespace suisseid {
|
|||||||
return "<unknown>";
|
return "<unknown>";
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
/// status of the certificates on the card
|
||||||
|
virtual CertStatus certStatus() {
|
||||||
|
return MISSING;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
mrw::Shared<cryptoki::Slot> _slot;
|
cryptoki::Library _cryptoki;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Instance of a Post SuisseID smartcard.
|
//! Instance of a Post SuisseID smartcard.
|
||||||
/*! A SuisseID card issued by Swiss Post.
|
/*! A SuisseID card issued by Swiss Post.
|
||||||
@see http://postsuisseid.ch */
|
@see http://postsuisseid.ch */
|
||||||
class PostSuisseID: public Card {
|
class Post: public Card {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PostSuisseID(mrw::Shared<pcsc::Connection::Reader> reader,
|
Post(mrw::Shared<pcsc::Connection::Reader> reader,
|
||||||
mrw::Shared<cryptoki::Slot> slot):
|
const cryptoki::Library& cryptoki):
|
||||||
Card(reader, slot), _minPinLen(0), _maxPinLen(-1) {
|
Card(reader, cryptoki), _minPinLen(0), _maxPinLen(-1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned int minimalPinLength() {
|
virtual unsigned int minimalPinLength() {
|
||||||
@@ -136,17 +151,20 @@ namespace suisseid {
|
|||||||
return _maxPinLen;
|
return _maxPinLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string version() {
|
virtual std::string version() {
|
||||||
if (_version.size()) return _version; // cache the version
|
if (_version.size()) return _version; // cache the version
|
||||||
pcsc::Connection::Reader::Transaction lock(_reader);
|
return versionFromMFFile("5649");
|
||||||
try {
|
|
||||||
selectMfFile("5649");
|
|
||||||
return _version = cardos::BerValue(readBinary())[0].value();
|
|
||||||
} catch (...) {
|
|
||||||
return _version = "<unknown>";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual CertStatus certStatus() {
|
||||||
|
cryptoki::Session session(slot());
|
||||||
|
cryptoki::ObjectList certs
|
||||||
|
(session.find(cryptoki::Attribute(CKA_CLASS)
|
||||||
|
.from<CK_OBJECT_CLASS>(CKO_CERTIFICATE)));
|
||||||
|
if (certs.size()==0) return MISSING;
|
||||||
|
return VALID;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void evaluatePinLengths() {
|
void evaluatePinLengths() {
|
||||||
@@ -163,6 +181,16 @@ namespace suisseid {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string versionFromMFFile(const std::string& file) {
|
||||||
|
pcsc::Connection::Reader::Transaction lock(_reader);
|
||||||
|
try {
|
||||||
|
selectMfFile(file);
|
||||||
|
return _version = cardos::BerValue(readBinary())[0].value();
|
||||||
|
} catch (...) {
|
||||||
|
return _version = "<unknown>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string _version; // version is cached
|
std::string _version; // version is cached
|
||||||
@@ -221,6 +249,7 @@ namespace suisseid {
|
|||||||
/// Scan for available known SuisseID cards on the system.
|
/// Scan for available known SuisseID cards on the system.
|
||||||
/** @return List of detected SuisseID smart cards. */
|
/** @return List of detected SuisseID smart cards. */
|
||||||
Cards scan() {
|
Cards scan() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
Cards res;
|
Cards res;
|
||||||
// By now, scan only for PostSuisseID; in future use factory pattern
|
// By now, scan only for PostSuisseID; in future use factory pattern
|
||||||
pcsc::Connection::Strings readers
|
pcsc::Connection::Strings readers
|
||||||
@@ -230,7 +259,7 @@ namespace suisseid {
|
|||||||
cryptoki::SlotList slots(_cryptoki.slotList(true, *reader));
|
cryptoki::SlotList slots(_cryptoki.slotList(true, *reader));
|
||||||
if (slots.size()==1)
|
if (slots.size()==1)
|
||||||
res.push_back(dynamic_cast<Card*>
|
res.push_back(dynamic_cast<Card*>
|
||||||
(new PostSuisseID(_pcsc.reader(*reader), slots[0])));
|
(new Post(_pcsc.reader(*reader), _cryptoki)));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -241,6 +270,159 @@ namespace suisseid {
|
|||||||
cryptoki::Library _cryptoki;
|
cryptoki::Library _cryptoki;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StatusCycle {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
StatusCycle(mrw::Shared<Card> card, unsigned int maxRetries = 20):
|
||||||
|
_card(card), _maxRetries(maxRetries), _counter(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
~StatusCycle() {}
|
||||||
|
|
||||||
|
bool run() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
_counter = 0;
|
||||||
|
return start();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
mrw::Shared<Card> card() {
|
||||||
|
return _card;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @name Slots
|
||||||
|
//@{
|
||||||
|
|
||||||
|
struct PinPukChange {
|
||||||
|
std::string oldpin;
|
||||||
|
std::string newpin;
|
||||||
|
bool valid() {
|
||||||
|
return oldpin.size() && newpin.size();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual PinPukChange pinChange() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
return PinPukChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual PinPukChange pinChangeTransportPin() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
return pinChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual PinPukChange pinChangePuk() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
return pinChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void transportPinLocked() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
}
|
||||||
|
virtual void pkcs15PinLocked() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
}
|
||||||
|
virtual void sigGPinLocked() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
}
|
||||||
|
virtual void pukLocked() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void certsExpireSoon() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
}
|
||||||
|
virtual void certsExpired() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
}
|
||||||
|
virtual void certsRevoked() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// install certificates on the card
|
||||||
|
/** @param bool whether to force reinstallation of existin certificates
|
||||||
|
@return @c true on success */
|
||||||
|
virtual bool installCerts(bool = true) {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool start() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
if (++_counter>_maxRetries) return false;
|
||||||
|
if (_card->transportState())
|
||||||
|
return unlockTransportState();
|
||||||
|
else
|
||||||
|
return checkPkcs15PinStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool unlockTransportState() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
if (_card->transportPinRetries()<0)
|
||||||
|
return transportPinLocked(), false;
|
||||||
|
else
|
||||||
|
return changeTransportPin();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool changeTransportPin() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
PinPukChange pins(pinChangeTransportPin());
|
||||||
|
if (!pins.valid()) return false;
|
||||||
|
_card->changePins(pins.newpin, pins.oldpin);
|
||||||
|
_card->unsetTransportState();
|
||||||
|
return start();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkPkcs15PinStatus() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
if (_card->pkcs15PinRetries()<0)
|
||||||
|
return pkcs15PinLocked(), unlockPkcs15();
|
||||||
|
if (_card->pukRetries()<0)
|
||||||
|
return pukLocked(), false;
|
||||||
|
return checkCertificates();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkCertificates() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
switch (_card->certStatus()) {
|
||||||
|
case Card::MISSING: return installCerts() && start();
|
||||||
|
case Card::EXPIRES_SOON: certsExpireSoon(); break;
|
||||||
|
case Card::EXPIRED: return certsExpired(), false;
|
||||||
|
case Card::REVOKED: return certsRevoked(), false;
|
||||||
|
case Card::VALID: break;
|
||||||
|
}
|
||||||
|
return checkSigGPinStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkSigGPinStatus() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
if (_card->sigGPinRetries()<0)
|
||||||
|
return sigGPinLocked(), false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool unlockPkcs15() {
|
||||||
|
CRYPTOLOG("log");
|
||||||
|
if (_card->pukRetries()<0)
|
||||||
|
return pukLocked(), false;
|
||||||
|
PinPukChange pins(pinChangePuk());
|
||||||
|
if (!pins.valid()) return false;
|
||||||
|
_card->changePins(pins.newpin, pins.oldpin);
|
||||||
|
return start();
|
||||||
|
}
|
||||||
|
|
||||||
|
mrw::Shared<Card> _card;
|
||||||
|
unsigned int _maxRetries;
|
||||||
|
unsigned int _counter;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
//@}
|
//@}
|
||||||
|
Reference in New Issue
Block a user