Yubico Forum
https://forum.yubico.com/

[Q] Variable response from OTP challenge w fixed config
https://forum.yubico.com/viewtopic.php?f=5&t=2610
Page 1 of 1

Author:  bmahf [ Thu Mar 23, 2017 5:28 pm ]
Post subject:  [Q] Variable response from OTP challenge w fixed config

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));
}

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/