added methods to get specific certificates; refs #27
This commit is contained in:
		| @@ -11,6 +11,17 @@ | |||||||
| #include <QtNetwork/QSslCertificate> | #include <QtNetwork/QSslCertificate> | ||||||
| #include <QtCore/QDateTime> | #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 { | int main(int argc, char** argv) try { | ||||||
|   std::string lib("libcvP11.so"); |   std::string lib("libcvP11.so"); | ||||||
|   mrw::args::parse(argc, argv, |   mrw::args::parse(argc, argv, | ||||||
| @@ -54,6 +65,8 @@ int main(int argc, char** argv) try { | |||||||
|                <<"  p: PIN change"<<std::endl |                <<"  p: PIN change"<<std::endl | ||||||
|                <<"  i: (re-) import certificates"<<std::endl |                <<"  i: (re-) import certificates"<<std::endl | ||||||
|                <<"  z: show 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; |                <<"  q: quit"<<std::endl; | ||||||
|       std::cin>>choice; |       std::cin>>choice; | ||||||
|       try { |       try { | ||||||
| @@ -80,16 +93,12 @@ int main(int argc, char** argv) try { | |||||||
|         } else if (choice=="z") { |         } else if (choice=="z") { | ||||||
|           for (suisseid::Certificates::iterator cert(certs.begin()); |           for (suisseid::Certificates::iterator cert(certs.begin()); | ||||||
|                cert!=certs.end(); ++cert) { |                cert!=certs.end(); ++cert) { | ||||||
|             QSslCertificate c(QByteArray(cert->data(), cert->size()), |             show(*cert); | ||||||
|                               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; |  | ||||||
|           } |           } | ||||||
|  |         } else if (choice=="a") { | ||||||
|  |           show((*card)->authenticationCertificate()); | ||||||
|  |         } else if (choice=="d") { | ||||||
|  |           show((*card)->digitalSignatureCertificate()); | ||||||
|         } else if (choice=="q") { |         } else if (choice=="q") { | ||||||
|           return 0; |           return 0; | ||||||
|         } else { |         } else { | ||||||
|   | |||||||
							
								
								
									
										101
									
								
								src/suisseid.hxx
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								src/suisseid.hxx
									
									
									
									
									
								
							| @@ -25,8 +25,14 @@ | |||||||
|     @see http://www.suisseid.ch |     @see http://www.suisseid.ch | ||||||
|     @see http://postsuisseid.ch */ |     @see http://postsuisseid.ch */ | ||||||
| //@{ | //@{ | ||||||
|  | /*! @defgroup suisseidlib SuisseID Library */ | ||||||
|  | /*! @defgroup suisseidtypes SuisseID C++ Types and Auxiliary */ | ||||||
|  | /*! @defgroup suisseidexceptions SuisseID Exceptions */ | ||||||
|  | //@} | ||||||
|  |  | ||||||
| namespace suisseid { | namespace suisseid { | ||||||
|  |  | ||||||
|  |  | ||||||
|   /** @page init Initialize Card and Check Status |   /** @page init Initialize Card and Check Status | ||||||
|  |  | ||||||
|       An idea on how the smart card status could be evaluated is the |       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 |   /// List of DER encoded binary certificates | ||||||
|   typedef std::vector<std::string> Certificates; |   typedef std::vector<Certificate> Certificates; | ||||||
|  |   //@} | ||||||
|  |    | ||||||
|  |   /*! @addtogroup suisseidlib */ | ||||||
|  |   //@{ | ||||||
|    |    | ||||||
|   //! Represents a SuisseID Card |   //! Represents a SuisseID Card | ||||||
|   /*! This is the parent class for special classes for the respecive |   /*! This is the parent class for special classes for the respecive | ||||||
| @@ -146,6 +198,31 @@ namespace suisseid { | |||||||
|         return res; |         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: |     protected: | ||||||
|        |        | ||||||
|       cryptoki::Library _cryptoki; |       cryptoki::Library _cryptoki; | ||||||
| @@ -180,14 +257,25 @@ namespace suisseid { | |||||||
|       } |       } | ||||||
|        |        | ||||||
|       virtual CertStatus certStatus() { |       virtual CertStatus certStatus() { | ||||||
|         cryptoki::Session session(slot()); |  | ||||||
|         cryptoki::ObjectList certs |         cryptoki::ObjectList certs | ||||||
|           (session.find(cryptoki::Attribute(CKA_CLASS) |           (session().find(cryptoki::Attribute(CKA_CLASS) | ||||||
|                         .from<CK_OBJECT_CLASS>(CKO_CERTIFICATE))); |                         .from<CK_OBJECT_CLASS>(CKO_CERTIFICATE))); | ||||||
|         if (certs.size()==0) return MISSING; |         if (certs.size()==0) return MISSING; | ||||||
|         return VALID; |         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: |     private: | ||||||
|  |  | ||||||
|       void evaluatePinLengths() { |       void evaluatePinLengths() { | ||||||
| @@ -216,6 +304,10 @@ namespace suisseid { | |||||||
|  |  | ||||||
|     private: |     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 |       std::string _version; // version is cached | ||||||
|       unsigned int _minPinLen; // minimal PIN length is cached |       unsigned int _minPinLen; // minimal PIN length is cached | ||||||
|       unsigned int _maxPinLen; // maximal PIN length is cached |       unsigned int _maxPinLen; // maximal PIN length is cached | ||||||
| @@ -447,7 +539,8 @@ namespace suisseid { | |||||||
|        |        | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| } |  | ||||||
|   //@}   |   //@}   | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user