diff --git a/doc/examples/cryptoki-demo.cxx b/doc/examples/cryptoki-demo.cxx index af0347d..241f084 100644 --- a/doc/examples/cryptoki-demo.cxx +++ b/doc/examples/cryptoki-demo.cxx @@ -39,7 +39,7 @@ int main(int argc, char const*const*const argv) try { <<"label: \""<mechanismlist()); 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()); it!=attrs.end(); ++it) { std::cout<<" - attribute: "<second.name()<<"=\"" - <second.value)<<'"'<second.value)<<'"'< +#include +#include + +/*! @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<"; + else if (data.find_first_not_of(VALID_CHARS)(CKO_CERTIFICATE)); attrs.push_back(Attribute(CKA_CERTIFICATE_TYPE) .from(CKC_X_509)); attrs.push_back(Attribute(CKA_SUBJECT, derSubject)); 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); } diff --git a/src/cryptoki.hxx b/src/cryptoki.hxx index a2f3d3e..3e5ce69 100644 --- a/src/cryptoki.hxx +++ b/src/cryptoki.hxx @@ -8,6 +8,7 @@ // 45678901234567890123456789012345678901234567890123456789012345678901234567890 // interface +#include #include #include #include @@ -20,6 +21,7 @@ #include // memset #include #include +#include #include // debug @@ -45,46 +47,6 @@ namespace cryptoki { //! @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<"; - else if (data.find_first_not_of(VALID_CHARS) Attribute from(const TYPE& v) { @@ -904,8 +866,11 @@ namespace cryptoki { ObjectList find(const AttributeList& attrs=AttributeList()); //! Create a new Certificate Object. - Object createCertificate(const std::string& derSubject, - const std::string& desValue); + Object create(const openssl::X509& cert); + //! 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); //@} diff --git a/src/makefile.am b/src/makefile.am index be082d2..78d3cdc 100644 --- a/src/makefile.am +++ b/src/makefile.am @@ -5,7 +5,7 @@ ## 1 2 3 4 5 6 7 8 ## 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 pkcs11dir = ${includedir}/pkcs11 diff --git a/src/openssl.hxx b/src/openssl.hxx index 15faa1d..9166198 100644 --- a/src/openssl.hxx +++ b/src/openssl.hxx @@ -10,10 +10,12 @@ #include #include - #include "openssl/bio.h" #include "openssl/ssl.h" #include +#include + +#include #include /*! @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 { public: undefined_certificate() throw(): @@ -199,6 +208,13 @@ namespace openssl { X509(): _x509(X509_new()) { 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) { unsigned char* d(0); int len(i2d_X509(o._x509, &d)); @@ -222,18 +238,58 @@ namespace openssl { int len(i2d_X509(o._x509, &d)); if (!len) throw x509_copy_failed(); const unsigned char* d2(d); - free(d); _x509 = d2i_X509(0, &d2, len); + OPENSSL_free(d); if (!_x509) throw x509_copy_failed(); } //! Get DER encoded subject. std::string subjectDER() const { - char* c(0); + unsigned char* c(0); 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); 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: ::X509* _x509; }; diff --git a/src/pcsc.hxx b/src/pcsc.hxx index b706134..e230a80 100644 --- a/src/pcsc.hxx +++ b/src/pcsc.hxx @@ -10,6 +10,8 @@ #ifndef PCSC_HXX #define PCSC_HXX +#include + #include #ifdef WIN32 @@ -68,25 +70,11 @@ best fits the common needs. */ //@{ /*! @defgroup pcsclib PCSC C++ Library */ -/*! @defgroup pcsctypes PCSC Types and Auxiliary */ /*! @defgroup pcscexceptions PCSC Exceptions */ //! @see gpcsc 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<