added methods to get specific certificates; refs #27

master
Marc Wäckerlin 11 years ago
parent b695ce2a0c
commit 8bd825ef08
  1. 27
      doc/examples/suisse-id-demo.cxx
  2. 101
      src/suisseid.hxx

@ -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 {

@ -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

Loading…
Cancel
Save