now secure channel enabled
This commit is contained in:
		| @@ -30,8 +30,16 @@ namespace crypto { | ||||
|   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) { | ||||
|   inline 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(); | ||||
|   } | ||||
|    | ||||
|   inline std::string hexTxt(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) { | ||||
| @@ -53,7 +61,7 @@ namespace crypto { | ||||
|     if (!data.size()) | ||||
|       return "<empty>"; | ||||
|     else if (data.find_first_not_of(VALID_CHARS)<data.size()) | ||||
|       return hex(data); | ||||
|       return hexTxt(data); | ||||
|     else | ||||
|       return "\""+data+"\""; | ||||
|   } | ||||
|   | ||||
| @@ -239,6 +239,21 @@ namespace cryptoki { | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   //---------------------------------------------------------------------------- | ||||
|   ObjectList Session::find(const Attribute& a) { | ||||
|     AttributeList al; | ||||
|     al.push_back(a); | ||||
|     return find(al); | ||||
|   } | ||||
|    | ||||
|   //---------------------------------------------------------------------------- | ||||
|   ObjectList Session::find(const Attribute& a1, const Attribute& a2) { | ||||
|     AttributeList al; | ||||
|     al.push_back(a1); | ||||
|     al.push_back(a2); | ||||
|     return find(al); | ||||
|   } | ||||
|  | ||||
|   //---------------------------------------------------------------------------- | ||||
|   Object Session::create(const std::string& label, const openssl::X509& cert) { | ||||
|     AttributeList attrs; | ||||
|   | ||||
| @@ -1002,6 +1002,11 @@ namespace cryptoki { | ||||
|       //! Get a list of matching objects. | ||||
|       ObjectList find(const AttributeList& attrs=AttributeList()); | ||||
|  | ||||
|       //! Get a list of matching objects. | ||||
|       ObjectList find(const Attribute& a); | ||||
|       //! Get a list of matching objects. | ||||
|       ObjectList find(const Attribute& a1, const Attribute& a2); | ||||
|  | ||||
|       //! Create a new Certificate Object. | ||||
|       Object create(const std::string& label, const openssl::X509& cert); | ||||
|       //! Create a new PrivateKey Object. | ||||
|   | ||||
							
								
								
									
										204
									
								
								src/openssl.hxx
									
									
									
									
									
								
							
							
						
						
									
										204
									
								
								src/openssl.hxx
									
									
									
									
									
								
							| @@ -11,6 +11,7 @@ | ||||
| #include <openssl/pkcs12.h> | ||||
| #include <openssl/x509.h> | ||||
| #include "openssl/bio.h" | ||||
| #include "openssl/des.h" | ||||
| #include "openssl/ssl.h" | ||||
| #include <openssl/err.h> | ||||
| #include <vector> | ||||
| @@ -21,6 +22,8 @@ | ||||
| #include <cstdio> | ||||
| #include <cassert> | ||||
|  | ||||
| #include <iostream> //! @todo remove (debug only) | ||||
|  | ||||
| /*! @defgroup gopenssl C++ Wrapper around OpenSSL API */ | ||||
| //@{ | ||||
| //! @defgroup openssllib OpenSSL C++ Library | ||||
| @@ -55,6 +58,13 @@ namespace openssl { | ||||
|       } | ||||
|   }; | ||||
|   //---------------------------------------------------------------------------- | ||||
|   class encryption_error: public openssl_error { | ||||
|     public: | ||||
|       encryption_error(const std::string& reason) throw(): | ||||
|           openssl_error("encryption: "+reason) { | ||||
|       } | ||||
|   }; | ||||
|   //---------------------------------------------------------------------------- | ||||
|   class pkcs12_error: public openssl_error { | ||||
|     public: | ||||
|       pkcs12_error(const std::string& reason) throw(): | ||||
| @@ -90,6 +100,13 @@ namespace openssl { | ||||
|       } | ||||
|   }; | ||||
|   //---------------------------------------------------------------------------- | ||||
|   class cannot_encrypt: public encryption_error { | ||||
|     public: | ||||
|       cannot_encrypt(std::string reason) throw(): | ||||
|           encryption_error("cannot encrypt text: "+reason) { | ||||
|       } | ||||
|   }; | ||||
|   //---------------------------------------------------------------------------- | ||||
|   class allocation_failed: public x509_error { | ||||
|     public: | ||||
|       allocation_failed() throw(): | ||||
| @@ -225,6 +242,193 @@ namespace openssl { | ||||
|       } | ||||
|   }; | ||||
|  | ||||
|   inline std::string desEnc(const std::string& txt, DES_cblock key1) { | ||||
|     std::string res(txt); | ||||
|     if (txt.size()%8!=0) | ||||
|       throw cannot_encrypt("text size must be a multiple of eight"); | ||||
|     DES_key_schedule ks1; | ||||
|     DES_set_key_unchecked(&(DES_cblock&)key1, &ks1); | ||||
|     for (std::string::size_type pos(0); pos<txt.size(); pos+=8) { | ||||
|       union { | ||||
|           DES_cblock array; | ||||
|           const char* text; | ||||
|       } in, out; | ||||
|       in.text = txt.begin().operator->()+pos; | ||||
|       out.text = res.begin().operator->()+pos; | ||||
|       DES_ecb_encrypt(&in.array, &out.array, &ks1, DES_ENCRYPT); | ||||
|     } | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
|   inline std::string desDec(const std::string& txt, DES_cblock key1) { | ||||
|     std::string res(txt); | ||||
|     if (txt.size()%8!=0) | ||||
|       throw cannot_encrypt("text size must be a multiple of eight"); | ||||
|     DES_key_schedule ks1; | ||||
|     DES_set_key_unchecked(&(DES_cblock&)key1, &ks1); | ||||
|     for (std::string::size_type pos(0); pos<txt.size(); pos+=8) { | ||||
|       union { | ||||
|           DES_cblock array; | ||||
|           const char* text; | ||||
|       } in, out; | ||||
|       in.text = txt.begin().operator->()+pos; | ||||
|       out.text = res.begin().operator->()+pos; | ||||
|       DES_ecb_encrypt(&in.array, &out.array, &ks1, DES_DECRYPT); | ||||
|     } | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
|   class CBlock8 { | ||||
|     public: | ||||
|       CBlock8() { | ||||
|         _cb[0] = _cb[1] = _cb[2] = _cb[3] = | ||||
|           _cb[4] = _cb[5] = _cb[6] = _cb[7] = 0; | ||||
|       } | ||||
|       CBlock8(unsigned char c1, unsigned char c2, unsigned char c3, | ||||
|               unsigned char c4, unsigned char c5, unsigned char c6, | ||||
|               unsigned char c7, unsigned char c8) { | ||||
|         _cb[0] = c1; | ||||
|         _cb[1] = c2; | ||||
|         _cb[2] = c3; | ||||
|         _cb[3] = c4; | ||||
|         _cb[4] = c5; | ||||
|         _cb[5] = c6; | ||||
|         _cb[6] = c7; | ||||
|         _cb[7] = c8; | ||||
|       } | ||||
|       //! String must contain exactly 8 char. | ||||
|       CBlock8(const std::string& s) { | ||||
|         assert(s.size()==8); | ||||
|         _cb[0] = s[0]; | ||||
|         _cb[1] = s[1]; | ||||
|         _cb[2] = s[3]; | ||||
|         _cb[3] = s[4]; | ||||
|         _cb[4] = s[5]; | ||||
|         _cb[5] = s[6]; | ||||
|         _cb[6] = s[7]; | ||||
|         _cb[7] = s[8]; | ||||
|       } | ||||
|       operator DES_cblock&() { | ||||
|         return _cb; | ||||
|       } | ||||
|       operator DES_cblock*() { | ||||
|         return &_cb; | ||||
|       } | ||||
|       operator std::string() const { | ||||
|         return std::string((char*)_cb, 8); | ||||
|       } | ||||
|     private: | ||||
|       DES_cblock _cb; | ||||
|   }; | ||||
|  | ||||
|   /*! @param txt If the length is not an integral multiple of eight | ||||
|                  bytes, it is zero filled. The output is always an | ||||
|                  integral multiple of eight bytes. */ | ||||
|   inline std::string desCbcEnc(std::string txt, CBlock8 key, CBlock8& ivec) { | ||||
|     if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0); | ||||
|     std::string res(txt.size(), 0); | ||||
|     DES_key_schedule ks; | ||||
|     DES_set_key_unchecked(key, &ks); | ||||
|     DES_ncbc_encrypt((unsigned char*)&txt[0], (unsigned char*)&res[0], | ||||
|                      txt.size(), &ks, ivec, DES_ENCRYPT); | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
|   /*! @param txt If the length is not an integral multiple of eight | ||||
|                  bytes, it is zero filled. The output is always an | ||||
|                  integral multiple of eight bytes. */ | ||||
|   inline std::string desCbcEnc(const std::string& txt, const CBlock8& key) { | ||||
|     CBlock8 ivec; | ||||
|     return desCbcEnc(txt, key, ivec); | ||||
|   } | ||||
|  | ||||
|   /*! @param txt If the length is not an integral multiple of eight | ||||
|                  bytes, it is zero filled. The output is always an | ||||
|                  integral multiple of eight bytes. */ | ||||
|   inline std::string desCbcDec(std::string txt, CBlock8 key, CBlock8& ivec) { | ||||
|     if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0); | ||||
|     std::string res(txt.size(), 0); | ||||
|     DES_key_schedule ks; | ||||
|     DES_set_key_unchecked(key, &ks); | ||||
|     DES_ncbc_encrypt((unsigned char*)&txt[0], (unsigned char*)&res[0], | ||||
|                      txt.size(), &ks, ivec, DES_DECRYPT); | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
|   /*! @param txt If the length is not an integral multiple of eight | ||||
|                  bytes, it is zero filled. The output is always an | ||||
|                  integral multiple of eight bytes. */ | ||||
|   inline std::string desCbcDec(const std::string& txt, const CBlock8& key) { | ||||
|     CBlock8 ivec; | ||||
|     return desCbcDec(txt, key, ivec); | ||||
|   } | ||||
|  | ||||
|   /*! @param txt If the length is not an integral multiple of eight | ||||
|                  bytes, it is zero filled. The output is always an | ||||
|                  integral multiple of eight bytes. */ | ||||
|   inline std::string des2edeCbcEnc(std::string txt, | ||||
|                                    CBlock8 key1, CBlock8 key2, | ||||
|                                    CBlock8 ivec = CBlock8()) { | ||||
|     if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0); | ||||
|     std::string res(txt.size(), 0); | ||||
|     DES_key_schedule ks1, ks2; | ||||
|     DES_set_key_unchecked(key1, &ks1); | ||||
|     DES_set_key_unchecked(key2, &ks2); | ||||
|     DES_ede2_cbc_encrypt((unsigned char*)&txt[0], (unsigned char*)&res[0], | ||||
|                          txt.size(), &ks1, &ks2, ivec, DES_ENCRYPT); | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
|   /*! @param txt If the length is not an integral multiple of eight | ||||
|                  bytes, it is zero filled. The output is always an | ||||
|                  integral multiple of eight bytes. */ | ||||
|   inline std::string des2edeCbcDec(std::string txt, | ||||
|                                    CBlock8 key1, CBlock8 key2, | ||||
|                                    CBlock8 ivec = CBlock8()) { | ||||
|     if (txt.size()%8!=0) txt.resize((txt.size()/8+1)*8, 0); | ||||
|     std::string res(txt.size(), 0); | ||||
|     DES_key_schedule ks1, ks2; | ||||
|     DES_set_key_unchecked(key1, &ks1); | ||||
|     DES_set_key_unchecked(key2, &ks2); | ||||
|     DES_ede2_cbc_encrypt((unsigned char*)&txt[0], (unsigned char*)&res[0], | ||||
|                          txt.size(), &ks1, &ks2, ivec, DES_DECRYPT); | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
|   //! @todo untested | ||||
|   inline std::string des2ecbEnc(std::string txt, | ||||
|                                 CBlock8 key1, CBlock8 key2) { | ||||
|     std::string res; | ||||
|     if (txt.size()%8!=0) | ||||
|       throw cannot_encrypt("text size must be a multiple of eight"); | ||||
|     DES_key_schedule ks1, ks2; | ||||
|     DES_set_key_unchecked(key1, &ks1); | ||||
|     DES_set_key_unchecked(key2, &ks2); | ||||
|     for (std::string::size_type pos(0); pos<txt.size(); pos+=8) { | ||||
|       CBlock8 out, in(txt.substr(pos, 8)); | ||||
|       DES_ecb2_encrypt(in, out, &ks1, &ks2, DES_ENCRYPT); | ||||
|       res+=out; | ||||
|     } | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
|   //! @todo untested | ||||
|   inline std::string des2ecbDec(std::string txt, | ||||
|                                 CBlock8 key1, CBlock8 key2) { | ||||
|     std::string res; | ||||
|     if (txt.size()%8!=0) | ||||
|       throw cannot_encrypt("text size must be a multiple of eight"); | ||||
|     DES_key_schedule ks1, ks2; | ||||
|     DES_set_key_unchecked(key1, &ks1); | ||||
|     DES_set_key_unchecked(key2, &ks2); | ||||
|     for (std::string::size_type pos(0); pos<txt.size(); pos+=8) { | ||||
|       CBlock8 out, in(txt.substr(pos, 8)); | ||||
|       DES_ecb2_encrypt(in, out, &ks1, &ks2, DES_DECRYPT); | ||||
|       res+=out; | ||||
|     } | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
|   //============================================================================ | ||||
|   class X509 { | ||||
|     public: | ||||
|   | ||||
							
								
								
									
										34
									
								
								src/pcsc.hxx
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								src/pcsc.hxx
									
									
									
									
									
								
							| @@ -10,6 +10,25 @@ | ||||
| #ifndef PCSC_HXX | ||||
| #define PCSC_HXX | ||||
|  | ||||
| #ifndef PCSC_LOG | ||||
| //! Declare PCSC_LOG before #include in your code, 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 <string> | ||||
| @@ -220,6 +239,19 @@ namespace pcsc { | ||||
|             assert(claInsP1P2.size()==4); | ||||
|             return transmit(claInsP1P2, lc, le); | ||||
|           } | ||||
|  | ||||
|           //! Transmit data to reader. | ||||
|           /*! @note Take care: Stings may contain embedded @c 0. */ | ||||
|           std::string transmit(char cla, char ins, char p1, char p2, | ||||
|                                unsigned char le) { | ||||
|             std::string claInsP1P2; | ||||
|             claInsP1P2.push_back(cla); | ||||
|             claInsP1P2.push_back(ins); | ||||
|             claInsP1P2.push_back(p1); | ||||
|             claInsP1P2.push_back(p2); | ||||
|             assert(claInsP1P2.size()==4); | ||||
|             return transmit(claInsP1P2, std::string(), le); | ||||
|           } | ||||
|            | ||||
|           //! Transmit data to reader. | ||||
|           /*! @note Take care: Stings may contain embedded @c 0. */ | ||||
| @@ -262,10 +294,12 @@ namespace pcsc { | ||||
|             SCARD_IO_REQUEST rPci; | ||||
|             rPci.dwProtocol  = pci()->dwProtocol; | ||||
|             rPci.cbPciLength = sizeof(rPci); | ||||
|             PCSC_LOG("SCardTransmit: "<<crypto::hex(in)); | ||||
|             check(SCardTransmit(_id, &rPci, | ||||
|                                 (unsigned char*)in.c_str(), in.size(), | ||||
|                                 0, buff, &len), | ||||
|                   "smartcard transmit message "+crypto::hex(in)); | ||||
|             PCSC_LOG(" -> "<<crypto::hex(std::string((char*)buff, len))); | ||||
|             return std::string((char*)buff, len); | ||||
|           } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user