Yubico Forum

...visit our web-store at store.yubico.com
It is currently Tue Jan 30, 2018 11:50 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Thu Mar 23, 2017 5:28 pm 
Offline

Joined: Wed Jan 18, 2017 4:56 pm
Posts: 2
I'm working on a Qt5 with Win32 project on Win7 using VS2010. I need to implement a simple OTP configuration on our YubiKeys such that they all have a fixed secret key that identifies the YubiKey as a known key. I have gotten to the point where after importing the YubiClientAPI.dll library, I am able to detect if a key is inserted, get the key's serial#, perform an OTP challenge/response, and get current buffer. The results seem to complement the results I get when I run the "Sample YubiClientAPI MFC test container" application compiled from the Samples folder.

I have a couple things that I need to figure out about using the API in order to complete my project. But the most important question I have is that, since my secret 16 byte key is constant on the YubiKey, and I keep getting back different byte strings every time I do a challenge, what do I do on the client end to get a constant expected string back that I can use for recognition. I am assuming that there is something I'm doing wrong. In the code below, you will see that I am randomizing the challenge string (see comment starting with "NOTE:"). I have also commented the randomization out so that the challenge string is all zeroes. Doesn't make a difference in the variability of the response string.

I am also not sure how the "Private Identity 6 byte Hex" field is used in the authentication process? Read the documentation, and I see when I run the "YubiKey Personalization Tool" that I can set that, but don't know how that affects the resulting response I get, and what it has to do with my client-side authentication process.

If anyone can just give me an indication of what I should be looking at to figure this out, I would be very grateful.

Code:
#include <iomanip>
#include <sstream>

// NOTE: import done in header file
//#import <YubiClientAPI.dll> no_namespace, named_guids

#define RESPONSE_LENGTH 16
#define CHALLENGE_LENGTH 6
#define CONFIG1 0
#define CONFIG2 1

TestingYubikeyAPI::TestingYubikeyAPI(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

   HRESULT hr = CoCreateInstance(CLSID_YubiClient, 0, CLSCTX_ALL, IID_IYubiClient, reinterpret_cast<void **>(&m_yubiClient));

   if (FAILED(hr))
    {
      _com_error er(hr);
        setValid(false);
   }
    else
        setValid(true);
   
    QObject::connect(ui.m_getOtpConf1PushButton, &QPushButton::clicked, this, &TestingYubikeyAPI::onGetOtpConfig1Clicked);
}

void TestingYubikeyAPI::onGetOtpConfig1Clicked()
{
    BYTE challenge[CHALLENGE_LENGTH];
    BYTE response[RESPONSE_LENGTH];
    memset(challenge, 0, sizeof(challenge));
    memset(response, 0, sizeof(response));
   
    // NOTE: randomizing challenge
    BCryptGenRandom(NULL, challenge, CHALLENGE_LENGTH, BCRYPT_USE_SYSTEM_PREFERRED_RNG);

    variant_t va;
    std::ostringstream os;
    std::stringstream os2;
    os << std::hex << std::setfill('0');
    for (DWORD i = 0; i < CHALLENGE_LENGTH; i++)
    {
        os << std::setw(2) << (int)challenge[i];
    }
    _bstr_t bstr(os.str().c_str());

    TCHAR buf[1024];
    va.bstrVal = bstr;
    va.vt = VT_BSTR;
    m_yubiClient->PutdataEncoding(ycENCODING_BYTE_ARRAY);
    m_yubiClient->PutdataBuffer(va);
    ycRETCODE ret = m_yubiClient->GetotpChallenge(CONFIG1, ycCALL_BLOCKING);
   
    if (ret == ycRETCODE_OK)
    {
        getCurrentBuffer(challenge, 64);
    }
    else
    {
        ui.m_outputTextEdit->append(QString("Got No Data: retcode = %1").arg(translateRetCode(ret)));
    }
}

void TestingYubikeyAPI::getCurrentBuffer(BYTE* pChallenge, int len)
{
    BYTE HUGEP *pb;
    long lbound, hbound;
    QString outstr;
   
    SafeArrayGetLBound(m_yubiClient->dataBuffer.parray, 1, &lbound);
    SafeArrayGetUBound(m_yubiClient->dataBuffer.parray, 1, &hbound);
    SafeArrayAccessData(m_yubiClient->dataBuffer.parray, (void **)&pb);

    for (; lbound <= hbound; lbound++)
    {
        outstr = QString("%1%2 ").arg(outstr).arg((uint)pb[lbound], 2, 16, QLatin1Char('0'));
    }
   
    SafeArrayUnaccessData(m_yubiClient->dataBuffer.parray);
    ui.m_outputTextEdit->append(QString("Got Data: %1").arg(outstr));
}


Top
 Profile  
Reply with quote  

Share On:

Share on Facebook FacebookShare on Twitter TwitterShare on Tumblr TumblrShare on Google+ Google+

Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group