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