towkneed
towkneed

Reputation: 11

OTP validation response shows MISSING_PARAMETER

Issue
I am trying to use a yubikey for second factor authentication via their OTP Validation Protocol Version 2.0. Despite following all the documentation meticulously (https://developers.yubico.com/OTP/OTP_Walk-Through.html and https://developers.yubico.com/OTP/Specifications/OTP_validation_protocol.html), I either get a BAD_SIGNATURE or MISSING_PARAMETER status response. I was trying to attach an HMAC-SHA-1 signature only because of the MISSING_PARAMETER response (the signature is not required). When I do try to attach a HMAC-SHA-1 signature then I get the BAD_SIGNATURE status response.
Environment
I am using Visual Studio 2019 and ASP.NET via a custom login form for authentication. Because of the deadline I am attempting to use SharePoint 2019 as a platform since it meets all the requirements OOTB except the 2FA requirement. Since there were issues in the past with AD based authentication I am using Forms auth with ASP.NET Sql Membership as a provider.
Login Code Process
The custom login form first checks the membership provider without setting any auth cookies. If the username and password are valid it proceeds to check if the user requires 2FA via yubikey. If they do I am using an HttpWebRequest to send the get and then reading the response from it (for debugging I am currently printing the response on a label):

string getUrl = "https://api2.yubico.com/wsapi/2.0/verify?id="+YUBICOID+"&otp="+otp+"&nonce="+nonce;
HttpWebRequest yubiGet = (HttpWebRequest)WebRequest.Create(getUrl);
HttpWebResponse response = (HttpWebResponse)yubiGet.GetResponse();
Stream respstr = response.GetResponseStream();
StringBuilder sb = new StringBuilder();
string temp = null;
int ct = 0;
byte[] buffer = new byte[8192];

do
{
    ct = respstr.Read(buffer, 0, buffer.Length);
    if (ct != 0)
    {
        temp = Encoding.ASCII.GetString(buffer, 0, ct);
        sb.Append(temp);
    }
}
while (ct > 0);
string responseStr = sb.ToString();
ErrorLabel.Text = "get: "+getUrl+ "<br /><br />response: " + responseStr;

Per the documentation (see the validation protocol link above) the HMAC signature is not required, however when I leave it off I get the MISSING_PARAMETER response. To build the signature I followed the documentation and reviewed the code in the old YubicoClient class (deprecated). I used the same function calls and processes to generate the signature. If the username and the creds were verified (via membership provider) and 2FA (yubikey) passed then I set the auth cookie and redirect appropriately.
What I have tried
Everything works except the yubikey response part. I have tried including all of the parameters indicated in the validation protocol documentation, both with and without the signature. With the signature I receive a BAD_SIGNATURE response and without it I receive a MISSING_PARAMETER response. I am using the Client ID from the Yubico API Key signup from https://upgrade.yubico.com/getapikey/ site for the id url parameter. When I tried with the signature I used the secret key that was generated there. I followed the same process to generate the signature that is used in the YubicoClient class (deprecated) A separate page is used to link the users to the key and is outside the scope of this issue.
I did use the yubikey manager application to reset the slot and re-registered it with the api key signup multiple times, using both slot 1 and slot 2 on the key.

It is a Yubikey 4 C FIPS. If it works we will be getting a lot of yubikey 5's. The documentation does not differentiate key generations and the yubikey manager indicates that the OTP is supported and there are no issues generating the otp.

Any guidance is greatly appreciated!

Upvotes: 0

Views: 237

Answers (1)

towkneed
towkneed

Reputation: 11

Ok. Figured it out. Reduced nonce characters from 40 to 20 and it worked. The documentation stated "from 16 to 40 character long string" I was using a random number generator to get bytes and then converting to string. Not sure if it was the url length or if the generated nonce resulted in more than 40 characters, but when I reduced it from 40 to 20 bytes it worked. I am happy now!

Upvotes: 0

Related Questions