PRCYCoin  2.0.0.7rc1
P2P Digital Currency
qgoogleauth.cpp
Go to the documentation of this file.
1 #include "qgoogleauth.h"
2 #include <QtEndian>
3 #include <QDateTime>
4 #include <QCryptographicHash>
5 #include <QSettings>
6 
8 {
9 }
10 
11 QByteArray QGoogleAuth::hmacSha1(QByteArray key, QByteArray baseString)
12 {
13  int blockSize = 64; // HMAC-SHA-1 block size, defined in SHA-1 standard
14  if (key.length() > blockSize) { // if key is longer than block size (64), reduce key length with SHA-1 compression
15  key = QCryptographicHash::hash(key, QCryptographicHash::Sha1);
16  }
17 
18  QByteArray innerPadding(blockSize, char(0x36)); // initialize inner padding with char "6"
19  QByteArray outerPadding(blockSize, char(0x5c)); // initialize outer padding with char "\"
20  // ascii characters 0x36 ("6") and 0x5c ("\") are selected because they have large
21  // Hamming distance (http://en.wikipedia.org/wiki/Hamming_distance)
22 
23  for (int i = 0; i < key.length(); i++) {
24  innerPadding[i] = innerPadding[i] ^ key.at(i); // XOR operation between every byte in key and innerpadding, of key length
25  outerPadding[i] = outerPadding[i] ^ key.at(i); // XOR operation between every byte in key and outerpadding, of key length
26  }
27 
28  // result = hash ( outerPadding CONCAT hash ( innerPadding CONCAT baseString ) ).toBase64
29  QByteArray total = outerPadding;
30  QByteArray part = innerPadding;
31  part.append(baseString);
32  total.append(QCryptographicHash::hash(part, QCryptographicHash::Sha1));
33  QByteArray hashed = QCryptographicHash::hash(total, QCryptographicHash::Sha1);
34  return hashed;
35 }
36 
37 int QGoogleAuth::base32_decode(const quint8 *encoded, quint8 *result, int bufSize)
38 {
39  int buffer = 0;
40  int bitsLeft = 0;
41  int count = 0;
42 
43  for (const quint8 *ptr = encoded; count < bufSize && *ptr; ++ptr) {
44  quint8 ch = *ptr;
45 
46  if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-') {
47  continue;
48  }
49 
50  buffer <<= 5;
51 
52  // Deal with commonly mistyped characters
53  if (ch == '0') {
54  ch = 'O';
55  } else if (ch == '1') {
56  ch = 'L';
57  } else if (ch == '8') {
58  ch = 'B';
59  }
60 
61  // Look up one base32 digit
62  if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
63  ch = (ch & 0x1F) - 1;
64  } else if (ch >= '2' && ch <= '7') {
65  ch -= '2' - 26;
66  } else {
67  return -1;
68  }
69 
70  buffer |= ch;
71  bitsLeft += 5;
72 
73  if (bitsLeft >= 8) {
74  result[count++] = buffer >> (bitsLeft - 8);
75  bitsLeft -= 8;
76  }
77  }
78 
79  if (count < bufSize) {
80  result[count] = '\000';
81  }
82 
83  return count;
84 }
85 
86 QString QGoogleAuth::generatePin(const QByteArray key)
87 {
88  quint64 time = QDateTime::currentDateTime().toTime_t();
89  quint64 current = qToBigEndian(time / 30);
90 
91  int secretLen = (key.length() + 7) / 8 * 5;
92  quint8 secret[100];
93  int res = base32_decode(reinterpret_cast<const quint8 *>(key.constData()), secret, secretLen);
94  QByteArray hmac = hmacSha1(QByteArray(reinterpret_cast<const char *>(secret), res), QByteArray((char*)&current, sizeof(current)));
95 
96  int offset = (hmac[hmac.length() - 1] & 0xf);
97  int binary =
98  ((hmac[offset] & 0x7f) << 24)
99  | ((hmac[offset + 1] & 0xff) << 16)
100  | ((hmac[offset + 2] & 0xff) << 8)
101  | (hmac[offset + 3] & 0xff);
102  QSettings settings;
103  int digits = settings.value("2fadigits").toInt();
104  int password;
105  if (digits == 8) {
106  password = binary % 100000000;
107  return QString("%1").arg(password, 8, 10, QChar('0'));
108  } else if (digits == 6) {
109  password = binary % 1000000;
110  return QString("%1").arg(password, 6, 10, QChar('0'));
111  }
112 }
QGoogleAuth::QGoogleAuth
QGoogleAuth()
Definition: qgoogleauth.cpp:7
QGoogleAuth::base32_decode
static int base32_decode(const quint8 *encoded, quint8 *result, int bufSize)
Definition: qgoogleauth.cpp:37
QGoogleAuth::hmacSha1
static QByteArray hmacSha1(QByteArray key, QByteArray baseString)
Definition: qgoogleauth.cpp:11
key
CKey key
Definition: bip38tooldialog.cpp:173
QGoogleAuth::generatePin
static QString generatePin(const QByteArray key)
Definition: qgoogleauth.cpp:86
qgoogleauth.h