auxiliaries are now in cryptaux.hxx; some get methods for openssl::X509

master
Marc Wäckerlin 15 years ago
parent 5c60773269
commit d3793f30a2
  1. 6
      doc/examples/cryptoki-demo.cxx
  2. 64
      src/cryptaux.hxx
  3. 13
      src/cryptoki.cxx
  4. 51
      src/cryptoki.hxx
  5. 2
      src/makefile.am
  6. 64
      src/openssl.hxx
  7. 20
      src/pcsc.hxx

@ -39,7 +39,7 @@ int main(int argc, char const*const*const argv) try {
<<"label: \""<<info.label<<'"'<<std::endl <<"label: \""<<info.label<<'"'<<std::endl
<<"manufacturerID: \""<<info.manufacturerID<<'"'<<std::endl <<"manufacturerID: \""<<info.manufacturerID<<'"'<<std::endl
<<"model: \""<<info.model<<'"'<<std::endl <<"model: \""<<info.model<<'"'<<std::endl
<<"serialNumber: \""<<cryptoki::readable(info.serialNumber) <<"serialNumber: \""<<crypto::readable(info.serialNumber)
<<'"'<<std::endl <<'"'<<std::endl
<<"flags: \""<<info.flags<<'"'<<std::endl <<"flags: \""<<info.flags<<'"'<<std::endl
<<"maxSessionCount: \""<<info.maxSessionCount<<'"'<<std::endl <<"maxSessionCount: \""<<info.maxSessionCount<<'"'<<std::endl
@ -57,7 +57,7 @@ int main(int argc, char const*const*const argv) try {
<<'.'<<(int)info.hardwareVersion.minor<<'"'<<std::endl <<'.'<<(int)info.hardwareVersion.minor<<'"'<<std::endl
<<"firmwareVersion: \""<<(int)info.firmwareVersion.major <<"firmwareVersion: \""<<(int)info.firmwareVersion.major
<<'.'<<(int)info.firmwareVersion.minor<<'"'<<std::endl <<'.'<<(int)info.firmwareVersion.minor<<'"'<<std::endl
<<"utcTime: \""<<cryptoki::readable(info.utcTime) <<"utcTime: \""<<crypto::readable(info.utcTime)
<<'"'<<std::endl; <<'"'<<std::endl;
cryptoki::MechanismList mechs(it->mechanismlist()); cryptoki::MechanismList mechs(it->mechanismlist());
for (cryptoki::MechanismList::iterator it2(mechs.begin()); for (cryptoki::MechanismList::iterator it2(mechs.begin());
@ -80,7 +80,7 @@ int main(int argc, char const*const*const argv) try {
for (cryptoki::AttributeMap::iterator it(attrs.begin()); for (cryptoki::AttributeMap::iterator it(attrs.begin());
it!=attrs.end(); ++it) { it!=attrs.end(); ++it) {
std::cout<<" - attribute: "<<it->second.name()<<"=\"" std::cout<<" - attribute: "<<it->second.name()<<"=\""
<<cryptoki::readable(it->second.value)<<'"'<<std::endl; <<crypto::readable(it->second.value)<<'"'<<std::endl;
} }
} }
std::cout<<"**** Success"<<std::endl; std::cout<<"**** Success"<<std::endl;

@ -0,0 +1,64 @@
/*! @file
@id $Id$
*/
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
#ifndef __CRYPTAUX_HXX__
#define __CRYPTAUX_HXX__
#include <string>
#include <sstream>
#include <iomanip>
/*! @defgroup gcrypto Auxiliary Crypto-Functions */
//@{
//! @see gcrypto
namespace crypto {
static const std::string LETTER_CHARS
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
static const std::string NUMBER_CHARS
("0123456789");
//! Contains @c @ in addition to standard characters.
static const std::string GRAFIC_CHARS
("!\"#%&'()*+,-./:;<=>?[\\]^_{|}~@");
static const std::string BLANK_CHARS
(" ");
static const std::string VALID_CHARS
(LETTER_CHARS+NUMBER_CHARS+GRAFIC_CHARS+BLANK_CHARS);
inline std::string hex(const std::string& data,
std::string::size_type len=20) {
std::stringstream res;
std::string::size_type pos(0);
for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it) {
res<<std::hex<<std::setfill('0')<<std::setw(2)
<<(unsigned int)(unsigned char)*it;
++pos;
if (pos%len==0 || pos==data.size()) {
res<<std::string(2*(len-(pos-1)%len), ' ');
for (std::string::size_type i(pos-(pos-1)%len-1); i<pos; ++i)
res<<(VALID_CHARS.find(data[i])==std::string::npos?'.':data[i]);
if (pos!=data.size()) res<<std::endl;
}
}
return res.str();
}
inline std::string readable(const std::string& data,
std::string::size_type len=20) {
if (!data.size())
return "<empty>";
else if (data.find_first_not_of(VALID_CHARS)<data.size())
return hex(data);
else
return "\""+data+"\"";
}
}
//@}
#endif

@ -240,15 +240,24 @@ namespace cryptoki {
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Object Session::createCertificate(const std::string& derSubject, Object Session::create(const openssl::X509& cert) {
const std::string& desValue) {
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));
attrs.push_back(Attribute(CKA_CERTIFICATE_TYPE) attrs.push_back(Attribute(CKA_CERTIFICATE_TYPE)
.from<CK_CERTIFICATE_TYPE>(CKC_X_509)); .from<CK_CERTIFICATE_TYPE>(CKC_X_509));
attrs.push_back(Attribute(CKA_SUBJECT, derSubject)); attrs.push_back(Attribute(CKA_SUBJECT, derSubject));
attrs.push_back(Attribute(CKA_VALUE, desValue)); attrs.push_back(Attribute(CKA_VALUE, desValue));
*/
return create(attrs);
}
Object Session::create(const openssl::PrivateKey& key) {
AttributeList attrs;
return create(attrs);
}
Object Session::create(const openssl::PKCS12& p12) {
AttributeList attrs;
return create(attrs); return create(attrs);
} }

@ -8,6 +8,7 @@
// 45678901234567890123456789012345678901234567890123456789012345678901234567890 // 45678901234567890123456789012345678901234567890123456789012345678901234567890
// interface // interface
#include <openssl.hxx>
#include <pkcs11/apiclient.h> #include <pkcs11/apiclient.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -20,6 +21,7 @@
#include <cstring> // memset #include <cstring> // memset
#include <iomanip> #include <iomanip>
#include <memory> #include <memory>
#include <cryptaux.hxx>
#include <iostream> // debug #include <iostream> // debug
@ -45,46 +47,6 @@ namespace cryptoki {
//! @addtogroup cryptokitypes //! @addtogroup cryptokitypes
//@{ //@{
static const std::string LETTER_CHARS
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
static const std::string NUMBER_CHARS
("0123456789");
//! Contains @c @ in addition to standard characters.
static const std::string GRAFIC_CHARS
("!\"#%&'()*+,-./:;<=>?[\\]^_{|}~@");
static const std::string BLANK_CHARS
(" ");
static const std::string VALID_CHARS
(LETTER_CHARS+NUMBER_CHARS+GRAFIC_CHARS+BLANK_CHARS);
inline std::string hex(const std::string& data,
std::string::size_type len=20) {
std::stringstream res;
std::string::size_type pos(0);
for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it) {
res<<std::hex<<std::setfill('0')<<std::setw(2)
<<(unsigned int)(unsigned char)*it;
++pos;
if (pos%len==0 || pos==data.size()) {
res<<std::string(2*(len-(pos-1)%len), ' ');
for (std::string::size_type i(pos-(pos-1)%len-1); i<pos; ++i)
res<<(VALID_CHARS.find(data[i])==std::string::npos?'.':data[i]);
if (pos!=data.size()) res<<std::endl;
}
}
return res.str();
}
inline std::string readable(const std::string& data,
std::string::size_type len=20) {
if (!data.size())
return "<empty>";
else if (data.find_first_not_of(VALID_CHARS)<data.size())
return hex(data);
else
return "\""+data+"\"";
}
inline std::string string(CK_ULONG num) { inline std::string string(CK_ULONG num) {
switch (num) { switch (num) {
@ -256,7 +218,7 @@ namespace cryptoki {
case CKO_VENDOR_DEFINED: return "VENDOR_DEFINED"; case CKO_VENDOR_DEFINED: return "VENDOR_DEFINED";
default: "unknown"; default: "unknown";
} }
default: return readable(value); default: return crypto::readable(value);
} }
} }
template<typename TYPE> Attribute from(const TYPE& v) { template<typename TYPE> Attribute from(const TYPE& v) {
@ -904,8 +866,11 @@ namespace cryptoki {
ObjectList find(const AttributeList& attrs=AttributeList()); ObjectList find(const AttributeList& attrs=AttributeList());
//! Create a new Certificate Object. //! Create a new Certificate Object.
Object createCertificate(const std::string& derSubject, Object create(const openssl::X509& cert);
const std::string& desValue); //! Create a new PrivateKey Object.
Object create(const openssl::PrivateKey& key);
//! Create a new Certificate and optional PrivateKey Object.
Object create(const openssl::PKCS12& p12);
//@} //@}

@ -5,7 +5,7 @@
## 1 2 3 4 5 6 7 8 ## 1 2 3 4 5 6 7 8
## 45678901234567890123456789012345678901234567890123456789012345678901234567890 ## 45678901234567890123456789012345678901234567890123456789012345678901234567890
include_HEADERS = pcsc.hxx cryptoki.hxx openssl.hxx include_HEADERS = pcsc.hxx cryptoki.hxx openssl.hxx cryptaux.hxx
pkcs11_HEADERS = pkcs11/pkcs11.h pkcs11/pkcs11types.h pkcs11/apiclient.h pkcs11_HEADERS = pkcs11/pkcs11.h pkcs11/pkcs11types.h pkcs11/apiclient.h
pkcs11dir = ${includedir}/pkcs11 pkcs11dir = ${includedir}/pkcs11

@ -10,10 +10,12 @@
#include <openssl/pkcs12.h> #include <openssl/pkcs12.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include "openssl/bio.h" #include "openssl/bio.h"
#include "openssl/ssl.h" #include "openssl/ssl.h"
#include <openssl/err.h> #include <openssl/err.h>
#include <vector>
#include <cryptaux.hxx>
#include <cstdio> #include <cstdio>
/*! @defgroup gopenssl C++ Wrapper around OpenSSL API */ /*! @defgroup gopenssl C++ Wrapper around OpenSSL API */
@ -85,6 +87,13 @@ namespace openssl {
} }
}; };
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
class x509_decoding_failed: public x509_error {
public:
x509_decoding_failed(const std::string& der) throw():
x509_error("certificate decoding failed:\n"+crypto::readable(der)) {
}
};
//----------------------------------------------------------------------------
class undefined_certificate: public x509_error { class undefined_certificate: public x509_error {
public: public:
undefined_certificate() throw(): undefined_certificate() throw():
@ -199,6 +208,13 @@ namespace openssl {
X509(): _x509(X509_new()) { X509(): _x509(X509_new()) {
if (!_x509) throw allocation_failed(); if (!_x509) throw allocation_failed();
} }
//! Initialize from DER encoded cerificate.
X509(const std::string& der): _x509(0) {
const unsigned char* c((const unsigned char*)der.begin().operator->());
if (!(_x509=d2i_X509(0, &c, der.size())) ||
(const char*)c!=der.begin().operator->()+der.size())
throw x509_decoding_failed(der);
}
X509(const X509& o): _x509(0) { X509(const X509& o): _x509(0) {
unsigned char* d(0); unsigned char* d(0);
int len(i2d_X509(o._x509, &d)); int len(i2d_X509(o._x509, &d));
@ -222,18 +238,58 @@ namespace openssl {
int len(i2d_X509(o._x509, &d)); int len(i2d_X509(o._x509, &d));
if (!len) throw x509_copy_failed(); if (!len) throw x509_copy_failed();
const unsigned char* d2(d); const unsigned char* d2(d);
free(d);
_x509 = d2i_X509(0, &d2, len); _x509 = d2i_X509(0, &d2, len);
OPENSSL_free(d);
if (!_x509) throw x509_copy_failed(); if (!_x509) throw x509_copy_failed();
} }
//! Get DER encoded subject. //! Get DER encoded subject.
std::string subjectDER() const { std::string subjectDER() const {
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(c, len); std::string res((char*)c, len);
OPENSSL_free(c); OPENSSL_free(c);
return res; return res;
} }
//! Get DER encoded issuer.
std::string issuerDER() const {
unsigned char* c(0);
int len(i2d_X509_NAME(X509_get_issuer_name(_x509), &c));
std::string res((char*)c, len);
OPENSSL_free(c);
return res;
}
//! Get DER encoded value.
std::string valueDER() const {
unsigned char* c(0);
int len(i2d_X509(_x509, &c));
std::string res((char*)c, len);
OPENSSL_free(c);
return res;
}
//! Get serial number.
std::string serial() const {
/* @bug http://albistechnologies.com reports: «could be a
failure in openSSL: len too short by 1 if serial number
starts with 00 ASN1_INTEGER* ser =
X509_get_serialNumber(_x509);» */
ASN1_INTEGER* ser(X509_get_serialNumber(_x509));
//! @todo requires memory free?
/*! @todo ser->type?!? http://albistechnologies.com prepends
tag and length in the first two char-fields. */
return std::string((char*)ser->data, ser->length);
}
//! Get id.
std::string id() const {
unsigned char c[SHA_DIGEST_LENGTH];
SHA1(_x509->cert_info->key->public_key->data,
_x509->cert_info->key->public_key->length,
c);
return std::string((char*)c, SHA_DIGEST_LENGTH);
}
//! Get label.
std::string label() const {
return std::string();
}
private: private:
::X509* _x509; ::X509* _x509;
}; };

@ -10,6 +10,8 @@
#ifndef PCSC_HXX #ifndef PCSC_HXX
#define PCSC_HXX #define PCSC_HXX
#include <cryptaux.hxx>
#include <string> #include <string>
#ifdef WIN32 #ifdef WIN32
@ -68,25 +70,11 @@
best fits the common needs. */ best fits the common needs. */
//@{ //@{
/*! @defgroup pcsclib PCSC C++ Library */ /*! @defgroup pcsclib PCSC C++ Library */
/*! @defgroup pcsctypes PCSC Types and Auxiliary */
/*! @defgroup pcscexceptions PCSC Exceptions */ /*! @defgroup pcscexceptions PCSC Exceptions */
//! @see gpcsc //! @see gpcsc
namespace pcsc { namespace pcsc {
//! @addtogroup pcsctypes
//@{
std::string hex(const std::string& data) {
std::stringstream res;
for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it)
res<<std::hex<<std::setfill('0')<<std::setw(2)
<<(unsigned int)(unsigned char)*it;
return res.str();
}
//@}
//============================================================================ //============================================================================
//! @addtogroup pcsclib //! @addtogroup pcsclib
//@{ //@{
@ -236,7 +224,7 @@ namespace pcsc {
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 "+hex(in)); "smartcard transmit message "+crypto::hex(in));
return std::string((char*)buff, len); return std::string((char*)buff, len);
} }
@ -312,7 +300,7 @@ namespace pcsc {
check(SCardConnect(_connection._id, strconv(name).c_str(), check(SCardConnect(_connection._id, strconv(name).c_str(),
mode, protocol, mode, protocol,
&_id, &_protocol), &_id, &_protocol),
"connect smartcard \""+name+"\" ("+hex(name)+")"); "connect smartcard \""+name+"\" ("+crypto::hex(name)+")");
} }
//! forbidden //! forbidden

Loading…
Cancel
Save