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