123 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*! @file
 | |
| 
 | |
|     @id $Id$
 | |
| */
 | |
| //       1         2         3         4         5         6         7         8
 | |
| // 45678901234567890123456789012345678901234567890123456789012345678901234567890
 | |
| 
 | |
| #include <mrw/args.hxx>
 | |
| #include <mrw/vector.hxx>
 | |
| #include <cryptoki.hxx>
 | |
| 
 | |
| #include <string>
 | |
| #include <map>
 | |
| #include <iostream>
 | |
| #include <iomanip>
 | |
| #include <algorithm>
 | |
| #include <sstream>
 | |
| #include <fstream>
 | |
| #include <streambuf>
 | |
| #ifndef MRW__OLD_PRE11_COMPILER
 | |
| #include <chrono>
 | |
| #endif
 | |
| 
 | |
| 
 | |
| int main(int argc, char** argv) try {
 | |
| 
 | |
|   // options
 | |
|   unsigned long r(1);
 | |
|   std::string txt("This is an example.");
 | |
|   std::string lib("libcvP11.so");
 | |
|   std::string slot;
 | |
|   std::string cert;
 | |
| 
 | |
|   mrw::args::parse(argc, argv,
 | |
|                    "Sign a text (optionally several times for performance"
 | |
|                    " measurements).",
 | |
|                    mrw::args::list()
 | |
|                    <<mrw::args::decl("h", "help", "show help",
 | |
|                                      mrw::args::decl::param_list()
 | |
|                                      <<mrw::args::help()
 | |
|                                      <<mrw::args::exit())
 | |
|                    <<mrw::args::decl("r", "repeat", "number of repetitions",
 | |
|                                      mrw::args::decl::param_list()
 | |
|                                      <<mrw::args::param(r, "number"))
 | |
|                    <<mrw::args::decl("t", "text", "text to sign",
 | |
|                                      mrw::args::decl::param_list()
 | |
|                                      <<mrw::args::param(txt, "text"))
 | |
|                    <<mrw::args::decl("l", "library", "cryptoki lirary to load",
 | |
|                                      mrw::args::decl::param_list()
 | |
|                                      <<mrw::args::param(lib, "lib"))
 | |
|                    <<mrw::args::decl("s", "slot", "name of slot",
 | |
|                                      mrw::args::decl::param_list()
 | |
|                                      <<mrw::args::param(slot, "name"))
 | |
|                    <<mrw::args::decl("c","cert", "name of certificate",
 | |
|                                      mrw::args::decl::param_list()
 | |
|                                      <<mrw::args::param(cert, "name")));
 | |
|   
 | |
|   std::cout<<"Sign text "<<r<<" times:"<<std::endl
 | |
|            <<"-----------------------------------------------------"<<std::endl
 | |
|            <<txt<<std::endl
 | |
|            <<"-----------------------------------------------------"<<std::endl;
 | |
|   cryptoki::Library c(lib);
 | |
|   cryptoki::SlotList sl(c.slotList());
 | |
|   for (cryptoki::SlotList::iterator s(sl.begin()); s!=sl.end(); ++s) {
 | |
|     cryptoki::SlotInfo si(s->slotinfo());
 | |
|     if (slot.size()&&slot!=si.slotDescription) continue;
 | |
|     std::cout<<"Found Slot: "<<si.slotDescription<<std::endl;
 | |
|     cryptoki::TokenInfo ti(s->tokeninfo());
 | |
|     std::cout<<"Found token: "<<ti.label<<std::endl;
 | |
|     cryptoki::Session session(*s);
 | |
|     cryptoki::ObjectList certs
 | |
|       (session.find(cryptoki::Attribute(CKA_CLASS)
 | |
|                     .from<CK_OBJECT_CLASS>(CKO_CERTIFICATE)));
 | |
|     for (cryptoki::ObjectList::iterator it(certs.begin());
 | |
|          it!=certs.end(); ++it) {
 | |
|       std::string label(it->attribute(CKA_LABEL).value);
 | |
|       if (cert.size()&&cert!=label) continue;
 | |
|       cryptoki::Attribute id(it->attribute(CKA_ID));
 | |
|       cryptoki::ObjectList keys
 | |
|         (session.find(cryptoki::Attribute(CKA_CLASS)
 | |
|                       .from<CK_OBJECT_CLASS>(CKO_PUBLIC_KEY),
 | |
|                       id));
 | |
|       if (!keys.size()) continue;
 | |
|       std::cout<<"Found Certificate: "
 | |
|                    <<it->attribute(CKA_LABEL).value<<std::endl;
 | |
|       if (!cert.size()) continue;
 | |
|       std::cout<<"Pin: ";
 | |
|       std::string pin;
 | |
|       std::cin>>pin;
 | |
|       session.login(pin);
 | |
|       keys = session.find(cryptoki::Attribute(CKA_CLASS)
 | |
|                           .from<CK_OBJECT_CLASS>(CKO_PRIVATE_KEY),
 | |
|                           id);
 | |
|       if (keys.size()!=1) {
 | |
|         std::cerr<<"**** ERROR: No private key: "<<keys.size()<<std::endl;
 | |
|         return 1;
 | |
|       }
 | |
|       std::cout<<"Signing ..."<<std::endl;
 | |
| #ifndef MRW__OLD_PRE11_COMPILER
 | |
|       auto start = std::chrono::system_clock::now();
 | |
| #endif
 | |
|       for (unsigned int i(0); i<r; ++i)
 | |
|         std::cout<<"Text:"<<std::endl
 | |
|                  <<crypto::readable(txt)<<std::endl
 | |
|                  <<"Signature:"<<std::endl
 | |
|                  <<crypto::readable(keys[0].sign(txt, CKM_RSA_PKCS))
 | |
|                  <<std::endl;
 | |
| #ifndef MRW__OLD_PRE11_COMPILER
 | |
|       auto end = std::chrono::system_clock::now();
 | |
|       auto elapsed(std::chrono::duration_cast<std::chrono::milliseconds>
 | |
|                    (end-start));
 | |
|       std::cout<<"Done in "<<elapsed.count()<<"ms"<<std::endl;
 | |
| #else
 | |
|       std::cout<<"Done."<<std::endl;
 | |
| #endif
 | |
|     }
 | |
|   }
 | |
|   return 0;
 | |
|  } catch (std::exception& x) {
 | |
|   std::cerr<<"**** ERROR: "<<x.what()<<std::endl;
 | |
|   return 1;
 | |
|  }
 |