auxiliaries are now in cryptaux.hxx; some get methods for openssl::X509
This commit is contained in:
		| @@ -39,7 +39,7 @@ int main(int argc, char const*const*const argv) try { | ||||
|                <<"label: \""<<info.label<<'"'<<std::endl | ||||
|                <<"manufacturerID: \""<<info.manufacturerID<<'"'<<std::endl | ||||
|                <<"model: \""<<info.model<<'"'<<std::endl | ||||
|                <<"serialNumber: \""<<cryptoki::readable(info.serialNumber) | ||||
|                <<"serialNumber: \""<<crypto::readable(info.serialNumber) | ||||
|                <<'"'<<std::endl | ||||
|                <<"flags: \""<<info.flags<<'"'<<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 | ||||
|                <<"firmwareVersion: \""<<(int)info.firmwareVersion.major | ||||
|                <<'.'<<(int)info.firmwareVersion.minor<<'"'<<std::endl | ||||
|                <<"utcTime: \""<<cryptoki::readable(info.utcTime) | ||||
|                <<"utcTime: \""<<crypto::readable(info.utcTime) | ||||
|                <<'"'<<std::endl; | ||||
|       cryptoki::MechanismList mechs(it->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: "<<it->second.name()<<"=\"" | ||||
|                    <<cryptoki::readable(it->second.value)<<'"'<<std::endl; | ||||
|                    <<crypto::readable(it->second.value)<<'"'<<std::endl; | ||||
|         } | ||||
|       } | ||||
|       std::cout<<"**** Success"<<std::endl; | ||||
|   | ||||
							
								
								
									
										64
									
								
								src/cryptaux.hxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/cryptaux.hxx
									
									
									
									
									
										Normal file
									
								
							| @@ -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, | ||||
|                                     const std::string& desValue) { | ||||
|   Object Session::create(const openssl::X509& cert) { | ||||
|     AttributeList attrs; | ||||
|     /* | ||||
|     attrs.push_back(Attribute(CKA_CLASS) | ||||
|                     .from<CK_OBJECT_CLASS>(CKO_CERTIFICATE)); | ||||
|     attrs.push_back(Attribute(CKA_CERTIFICATE_TYPE) | ||||
|                     .from<CK_CERTIFICATE_TYPE>(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); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -8,6 +8,7 @@ | ||||
| // 45678901234567890123456789012345678901234567890123456789012345678901234567890 | ||||
|  | ||||
| // interface | ||||
| #include <openssl.hxx> | ||||
| #include <pkcs11/apiclient.h> | ||||
| #include <string> | ||||
| #include <vector> | ||||
| @@ -20,6 +21,7 @@ | ||||
| #include <cstring> // memset | ||||
| #include <iomanip> | ||||
| #include <memory> | ||||
| #include <cryptaux.hxx> | ||||
|  | ||||
| #include <iostream> // debug | ||||
|  | ||||
| @@ -46,46 +48,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<<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) { | ||||
|     switch (num) { | ||||
|       case CK_UNAVAILABLE_INFORMATION: return "-"; | ||||
| @@ -256,7 +218,7 @@ namespace cryptoki { | ||||
|               case CKO_VENDOR_DEFINED: return "VENDOR_DEFINED"; | ||||
|               default: "unknown"; | ||||
|             } | ||||
|           default: return readable(value); | ||||
|           default: return crypto::readable(value); | ||||
|         } | ||||
|       } | ||||
|       template<typename TYPE> 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); | ||||
|        | ||||
|       //@} | ||||
|        | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -10,10 +10,12 @@ | ||||
|  | ||||
| #include <openssl/pkcs12.h> | ||||
| #include <openssl/x509.h> | ||||
|  | ||||
| #include "openssl/bio.h" | ||||
| #include "openssl/ssl.h" | ||||
| #include <openssl/err.h> | ||||
| #include <vector> | ||||
|  | ||||
| #include <cryptaux.hxx> | ||||
| #include <cstdio> | ||||
|  | ||||
| /*! @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; | ||||
|   }; | ||||
|   | ||||
							
								
								
									
										20
									
								
								src/pcsc.hxx
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								src/pcsc.hxx
									
									
									
									
									
								
							| @@ -10,6 +10,8 @@ | ||||
| #ifndef PCSC_HXX | ||||
| #define PCSC_HXX | ||||
|  | ||||
| #include <cryptaux.hxx> | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| #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<<std::hex<<std::setfill('0')<<std::setw(2) | ||||
|          <<(unsigned int)(unsigned char)*it; | ||||
|     return res.str(); | ||||
|   } | ||||
|  | ||||
|   //@} | ||||
|  | ||||
|   //============================================================================ | ||||
|   //! @addtogroup pcsclib | ||||
|   //@{ | ||||
| @@ -236,7 +224,7 @@ namespace pcsc { | ||||
|             check(SCardTransmit(_id, &rPci, | ||||
|                                 (unsigned char*)in.c_str(), in.size(), | ||||
|                                 0, buff, &len), | ||||
|                   "smartcard transmit message "+hex(in)); | ||||
|                   "smartcard transmit message "+crypto::hex(in)); | ||||
|             return std::string((char*)buff, len); | ||||
|           } | ||||
|  | ||||
| @@ -312,7 +300,7 @@ namespace pcsc { | ||||
|             check(SCardConnect(_connection._id, strconv(name).c_str(), | ||||
|                                mode, protocol, | ||||
|                                &_id, &_protocol), | ||||
|                   "connect smartcard \""+name+"\" ("+hex(name)+")"); | ||||
|                   "connect smartcard \""+name+"\" ("+crypto::hex(name)+")"); | ||||
|           } | ||||
|  | ||||
|           //! forbidden | ||||
|   | ||||
		Reference in New Issue
	
	Block a user