Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
TOTP.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "TOTP.h"
7
8#include "openssl/evp.h"
9#include "openssl/hmac.h"
10
11#include <cstring>
12
13int base32_decode(std::string& encoded, char* result, int bufSize)
14{
15 // Base32 implementation
16 // Copyright 2010 Google Inc.
17 // Author: Markus Gutschke
18 // Licensed under the Apache License, Version 2.0
19 int buffer = 0;
20 int bitsLeft = 0;
21 int count = 0;
22 for (const char* ptr = encoded.c_str(); count < bufSize && *ptr; ++ptr)
23 {
24 char ch = *ptr;
25 if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-')
26 continue;
27 buffer <<= 5;
28
29 // Deal with commonly mistyped characters
30 if (ch == '0')
31 ch = 'O';
32 else if (ch == '1')
33 ch = 'L';
34 else if (ch == '8')
35 ch = 'B';
36
37 // Look up one base32 digit
38 if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
39 ch = (ch & 0x1F) - 1;
40 else if (ch >= '2' && ch <= '7')
41 ch -= '2' - 26;
42 else
43 return -1;
44
45 buffer |= ch;
46 bitsLeft += 5;
47 if (bitsLeft >= 8)
48 {
49 result[count++] = buffer >> (bitsLeft - 8);
50 bitsLeft -= 8;
51 }
52 }
53
54 if (count < bufSize)
55 result[count] = '\000';
56 return count;
57}
58
59#define HMAC_RES_SIZE 20
60
61namespace TOTP
62{
63 unsigned int GenerateToken(std::string& b32key)
64 {
65 size_t keySize = b32key.length();
66 int bufsize = (keySize + 7) / 8 * 5;
67 char* encoded = new char[bufsize];
68 memset(encoded, 0, bufsize);
69 unsigned int hmacResSize = HMAC_RES_SIZE;
70 unsigned char hmacRes[HMAC_RES_SIZE];
71 unsigned long timestamp = time(NULL) / 30;
72 unsigned char challenge[8];
73
74 for (int i = 8; i--; timestamp >>= 8)
75 challenge[i] = timestamp;
76
77 base32_decode(b32key, encoded, bufsize);
78 HMAC(EVP_sha1(), encoded, bufsize, challenge, 8, hmacRes, &hmacResSize);
79 unsigned int offset = hmacRes[19] & 0xF;
80 unsigned int truncHash = (hmacRes[offset] << 24) | (hmacRes[offset + 1] << 16) |
81 (hmacRes[offset + 2] << 8) | hmacRes[offset + 3];
82 truncHash &= 0x7FFFFFFF;
83
84 delete[] encoded;
85
86 return truncHash % 1000000;
87 }
88}
int base32_decode(std::string &encoded, char *result, int bufSize)
Definition TOTP.cpp:13
#define HMAC_RES_SIZE
Definition TOTP.cpp:59
Definition TOTP.cpp:62
unsigned int GenerateToken(std::string &b32key)
Definition TOTP.cpp:63