CK_SESSION_HANDLE d_session;
CK_SLOT_ID d_slot;
CK_RV d_err{};
+ std::string d_pin;
void logError(const std::string& operation) const {
if (d_err) {
}
}
- bool Login(const std::string& pin) {
- if (d_logged_in) return true;
+ bool Login(const std::string& pin, CK_USER_TYPE userType=CKU_USER) {
+ if (userType == CKU_USER && d_logged_in) return true;
auto uPin = std::make_unique<unsigned char[]>(pin.size());
memcpy(uPin.get(), pin.c_str(), pin.size());
- d_err = d_functions->C_Login(this->d_session, CKU_USER, uPin.get(), pin.size());
- memset(uPin.get(), 0, pin.size());
+ d_err = d_functions->C_Login(this->d_session, userType, uPin.get(), pin.size());
logError("C_Login");
- if (d_err == 0) {
+ if (d_err == 0 && userType == CKU_USER) {
d_logged_in = true;
+ d_pin = pin;
}
return d_logged_in;
}
+ bool Relogin() {
+ return Login(d_pin, CKU_CONTEXT_SPECIFIC);
+ }
+
bool LoggedIn() const { return d_logged_in; }
CK_SESSION_HANDLE& Session() { return d_session; }
CK_OBJECT_HANDLE d_public_key;
CK_OBJECT_HANDLE d_private_key;
CK_KEY_TYPE d_key_type;
+ bool d_always_auth;
CK_ULONG d_bits;
std::string d_exponent;
}
d_private_key = key[0];
attr.clear();
+ attr.emplace_back(CKA_ALWAYS_AUTHENTICATE, '\0');
+ if (GetAttributeValue2(*slot, d_private_key, attr)==0) {
+ d_always_auth = attr[0].byte() != 0;
+ }
+ attr.clear();
attr.emplace_back(CKA_CLASS, (unsigned long)CKO_PUBLIC_KEY);
attr.emplace_back(CKA_LABEL, d_pub_label);
FindObjects2(*slot, attr, key, 1);
CK_ULONG buflen = sizeof buffer; // should be enough for most signatures.
auto slot = d_slot->lock();
- // perform signature
if ((d_err = slot->f()->C_SignInit(slot->Session(), mechanism, d_private_key))) { logError("C_SignInit"); return d_err; }
+ // check if we need to relogin
+ if (d_always_auth) {
+ slot->Relogin();
+ }
+ // perform signature
d_err = slot->f()->C_Sign(slot->Session(), (unsigned char*)data.c_str(), data.size(), buffer, &buflen);
if (!d_err) {
auto slot = d_slot->lock();
if ((d_err = slot->f()->C_VerifyInit(slot->Session(), mechanism, d_public_key))) { logError("C_VerifyInit"); return d_err; }
+ // check if we need to relogin
+ if (d_always_auth) {
+ slot->Relogin();
+ }
+
d_err = slot->f()->C_Verify(slot->Session(), (unsigned char*)data.c_str(), data.size(), (unsigned char*)signature.c_str(), signature.size());
logError("C_Verify");
return d_err;