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.
109 lines
2.3 KiB
109 lines
2.3 KiB
14 years ago
|
|
||
|
#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;
|
||
|
}
|
||
|
|