#include "CardKey.h" #include "SecOpGuard.h" #include #include #include #include #include CardKey::CardKey(act::ITokenKey* key) : m_token_key(key) { ACT_ASSERT(key != 0); } CardKey::~CardKey() { } void CardKey::setPin(char *pin) { int plen = strlen(pin); act::Blob(pin, pin+plen).swap(m_pin); std::fill(pin, pin+plen, '*'); // Whiten out the source contents as soon as the PIN is in our domain } void CardKey::setPin(const act::Blob& pin) { m_pin = pin; } void CardKey::setPin(UI_METHOD *ui_method, void *callback_data) { int maxlen=200; std::vector buf(maxlen+1); char* buffer = &buf[0]; UI *ui; struct mycb_t { const char *password; const char *prompt_info; } *mycb; mycb = reinterpret_cast(callback_data); /* pin in the call back data, copy and use */ if (mycb != NULL && mycb->password) { act::Blob(mycb->password, mycb->password+strlen(mycb->password)).swap(m_pin); return; } /* call ui to ask for a pin */ ui = UI_new(); if (ui_method != NULL) UI_set_method(ui, ui_method); if (callback_data != NULL) UI_set_app_data(ui, callback_data); // Fall back to an own, quite meaningless, prompt if we aren't provided one. const char *prompt_info = (mycb && mycb->prompt_info) ? mycb->prompt_info : "Token PIN: "; if (!UI_add_input_string (ui, prompt_info, 0, buffer, 1, maxlen)) { fprintf(stderr, "UI_add_input_string failed\n"); UI_free(ui); return; } if (UI_process(ui)) { fprintf(stderr, "UI_process failed\n"); UI_free(ui); return; } act::Blob(buffer, buffer+strlen(buffer)).swap(m_pin); UI_free(ui); return; } bool CardKey::Authenticate(SecOpGuard& where) { // We assume to get along without a PIN. If the security operation fails we'll see early enough. if(m_pin.empty()) return true; act::ITokenPIN* token_pin = m_token_key->GetPin(); // Fall back to token's User PIN if nothing else given if(token_pin == NULL) { act::IToken* token = m_token_key->GetToken(); ACT_ASSERT(token != NULL); token_pin = token->GetUserPin(); } ACT_ASSERT(token_pin != NULL); bool result = where.Authenticate(token_pin, m_pin); // TODO: UP FOR DISCUSSION: PIN has been used up, erase it? Or keep it as long as the key itself? // m_pin.clear(); return result; }