added methods to get specific certificates; refs #27
This commit is contained in:
		| @@ -11,6 +11,17 @@ | ||||
| #include <QtNetwork/QSslCertificate> | ||||
| #include <QtCore/QDateTime> | ||||
|  | ||||
| void show(const suisseid::Certificate& cert) { | ||||
|   QSslCertificate c(QByteArray(cert.data(), cert.size()), QSsl::Der); | ||||
|   std::cout<<"Certificate info: CN=" | ||||
|            <<QString(c.subjectInfo(QSslCertificate::CommonName) | ||||
|                      .toUtf8()).toStdString() | ||||
|                      <<std::endl | ||||
|            <<"  Valid until: " | ||||
|            <<QString(c.expiryDate().toString().toUtf8()).toStdString() | ||||
|            <<std::endl; | ||||
| } | ||||
|  | ||||
| int main(int argc, char** argv) try { | ||||
|   std::string lib("libcvP11.so"); | ||||
|   mrw::args::parse(argc, argv, | ||||
| @@ -54,6 +65,8 @@ int main(int argc, char** argv) try { | ||||
|                <<"  p: PIN change"<<std::endl | ||||
|                <<"  i: (re-) import certificates"<<std::endl | ||||
|                <<"  z: show certificates"<<std::endl | ||||
|                <<"  a: show authentication certificate"<<std::endl | ||||
|                <<"  d: show digital signature certificate"<<std::endl | ||||
|                <<"  q: quit"<<std::endl; | ||||
|       std::cin>>choice; | ||||
|       try { | ||||
| @@ -80,16 +93,12 @@ int main(int argc, char** argv) try { | ||||
|         } else if (choice=="z") { | ||||
|           for (suisseid::Certificates::iterator cert(certs.begin()); | ||||
|                cert!=certs.end(); ++cert) { | ||||
|             QSslCertificate c(QByteArray(cert->data(), cert->size()), | ||||
|                               QSsl::Der); | ||||
|             std::cout<<"Certificate info: CN=" | ||||
|                      <<QString(c.subjectInfo(QSslCertificate::CommonName) | ||||
|                                .toUtf8()).toStdString() | ||||
|                      <<std::endl | ||||
|                      <<"  Valid until: " | ||||
|                      <<QString(c.expiryDate().toString().toUtf8()).toStdString() | ||||
|                      <<std::endl; | ||||
|             show(*cert); | ||||
|           } | ||||
|         } else if (choice=="a") { | ||||
|           show((*card)->authenticationCertificate()); | ||||
|         } else if (choice=="d") { | ||||
|           show((*card)->digitalSignatureCertificate()); | ||||
|         } else if (choice=="q") { | ||||
|           return 0; | ||||
|         } else { | ||||
|   | ||||
							
								
								
									
										101
									
								
								src/suisseid.hxx
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								src/suisseid.hxx
									
									
									
									
									
								
							| @@ -25,8 +25,14 @@ | ||||
|     @see http://www.suisseid.ch | ||||
|     @see http://postsuisseid.ch */ | ||||
| //@{ | ||||
| /*! @defgroup suisseidlib SuisseID Library */ | ||||
| /*! @defgroup suisseidtypes SuisseID C++ Types and Auxiliary */ | ||||
| /*! @defgroup suisseidexceptions SuisseID Exceptions */ | ||||
| //@} | ||||
|  | ||||
| namespace suisseid { | ||||
|  | ||||
|  | ||||
|   /** @page init Initialize Card and Check Status | ||||
|  | ||||
|       An idea on how the smart card status could be evaluated is the | ||||
| @@ -75,8 +81,54 @@ namespace suisseid { | ||||
|  | ||||
|       */ | ||||
|  | ||||
|   //============================================================================ | ||||
|   /*! @addtogroup suisseidexceptions */ | ||||
|   //@{ | ||||
|    | ||||
|   //---------------------------------------------------------------------------- | ||||
|   class exception: public std::exception { | ||||
|     public: | ||||
|       exception(const std::string& reason) throw(): | ||||
|           _what("suisseid: "+reason) { | ||||
|         CRYPTOLOG("ERROR: "<<what()); | ||||
|       } | ||||
|       ~exception() throw() {} | ||||
|       const char* what() const throw() { | ||||
|         return _what.c_str(); | ||||
|       } | ||||
|     private: | ||||
|       std::string _what; | ||||
|   }; | ||||
|   //---------------------------------------------------------------------------- | ||||
|   class no_certfound: public exception { | ||||
|     public: | ||||
|       no_certfound(const std::string& label) throw(): | ||||
|           exception("no certificate with label \""+label+"\" found") {} | ||||
|   }; | ||||
|   //---------------------------------------------------------------------------- | ||||
|   class no_auth: public exception { | ||||
|     public: | ||||
|       no_auth() throw(): | ||||
|           exception("no authentication certificate found") {} | ||||
|   }; | ||||
|   //---------------------------------------------------------------------------- | ||||
|   class no_digsig: public exception { | ||||
|     public: | ||||
|       no_digsig() throw(): | ||||
|           exception("no digital signature certificate found") {} | ||||
|   }; | ||||
|   //@} | ||||
|    | ||||
|   /*! @addtogroup suisseidtypes */ | ||||
|   //@{ | ||||
|   /// DER encoded binary certificate | ||||
|   typedef std::string Certificate; | ||||
|   /// List of DER encoded binary certificates | ||||
|   typedef std::vector<std::string> Certificates; | ||||
|   typedef std::vector<Certificate> Certificates; | ||||
|   //@} | ||||
|    | ||||
|   /*! @addtogroup suisseidlib */ | ||||
|   //@{ | ||||
|    | ||||
|   //! Represents a SuisseID Card | ||||
|   /*! This is the parent class for special classes for the respecive | ||||
| @@ -146,6 +198,31 @@ namespace suisseid { | ||||
|         return res; | ||||
|       } | ||||
|        | ||||
|       virtual Certificate certificate(const std::string& keylabel) { | ||||
|         cryptoki::ObjectList keys // find keys with digsig-label | ||||
|           (session().find(cryptoki::AttributeList() | ||||
|                           <<cryptoki::Attribute(CKA_CLASS) | ||||
|                           .from<CK_OBJECT_CLASS>(CKO_PUBLIC_KEY) | ||||
|                           <<cryptoki::Attribute(CKA_LABEL, keylabel))); | ||||
|         for (cryptoki::ObjectList::iterator key(keys.begin()); | ||||
|              key!=keys.end(); ++key) { | ||||
|           cryptoki::Attribute id(key->attribute(CKA_ID)); | ||||
|           cryptoki::ObjectList certs | ||||
|             (session().find(cryptoki::AttributeList() | ||||
|                             <<cryptoki::Attribute(CKA_CLASS) | ||||
|                             .from<CK_OBJECT_CLASS>(CKO_CERTIFICATE) | ||||
|                             <<id)); | ||||
|           for (cryptoki::ObjectList::iterator cert(certs.begin()); | ||||
|                cert!=certs.end(); ++cert) { // return first matching cert | ||||
|             return cert->attribute(CKA_VALUE).value; | ||||
|           } | ||||
|         } | ||||
|         throw no_certfound(keylabel); | ||||
|       } | ||||
|  | ||||
|       virtual Certificate authenticationCertificate() = 0; | ||||
|       virtual Certificate digitalSignatureCertificate() = 0; | ||||
|  | ||||
|     protected: | ||||
|        | ||||
|       cryptoki::Library _cryptoki; | ||||
| @@ -180,14 +257,25 @@ namespace suisseid { | ||||
|       } | ||||
|        | ||||
|       virtual CertStatus certStatus() { | ||||
|         cryptoki::Session session(slot()); | ||||
|         cryptoki::ObjectList certs | ||||
|           (session.find(cryptoki::Attribute(CKA_CLASS) | ||||
|           (session().find(cryptoki::Attribute(CKA_CLASS) | ||||
|                         .from<CK_OBJECT_CLASS>(CKO_CERTIFICATE))); | ||||
|         if (certs.size()==0) return MISSING; | ||||
|         return VALID; | ||||
|       } | ||||
|        | ||||
|       virtual Certificate authenticationCertificate() try { | ||||
|           return certificate(DIG_SIG); | ||||
|       } catch (const no_certfound&) { | ||||
|         throw no_auth(); | ||||
|       } | ||||
|        | ||||
|       virtual Certificate digitalSignatureCertificate() try { | ||||
|         return certificate(NON_REP); | ||||
|       } catch (const no_certfound&) { | ||||
|         throw no_digsig(); | ||||
|       } | ||||
|        | ||||
|     private: | ||||
|  | ||||
|       void evaluatePinLengths() { | ||||
| @@ -216,6 +304,10 @@ namespace suisseid { | ||||
|  | ||||
|     private: | ||||
|  | ||||
|       const std::string NON_REP  = "SwissSign_nonRep                "; | ||||
|       const std::string DIG_SIG  = "SwissSign_digSig                "; | ||||
|       const std::string DATA_ENC = "SwissSign_dataEnc               "; | ||||
|  | ||||
|       std::string _version; // version is cached | ||||
|       unsigned int _minPinLen; // minimal PIN length is cached | ||||
|       unsigned int _maxPinLen; // maximal PIN length is cached | ||||
| @@ -447,7 +539,8 @@ namespace suisseid { | ||||
|        | ||||
|   }; | ||||
|  | ||||
|   //@}   | ||||
| } | ||||
| //@} | ||||
|  | ||||
|  | ||||
| #endif | ||||
|   | ||||
		Reference in New Issue
	
	Block a user