You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
2.3 KiB
108 lines
2.3 KiB
|
|
#include "CardKey.h" |
|
#include "SecOpGuard.h" |
|
|
|
#include <actITokenKey.h> |
|
#include <actIToken.h> |
|
#include <actDebug.h> |
|
|
|
#include <cstring> |
|
#include <vector> |
|
|
|
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<char> buf(maxlen+1); |
|
char* buffer = &buf[0]; |
|
|
|
UI *ui; |
|
struct mycb_t { |
|
const char *password; |
|
const char *prompt_info; |
|
} *mycb; |
|
|
|
mycb = reinterpret_cast<mycb_t*>(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; |
|
} |
|
|
|
|