-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch origin/oauth-client into master
- Loading branch information
Showing
13 changed files
with
1,261 additions
and
28 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
#ifndef QAESENCRYPTION_H | ||
#define QAESENCRYPTION_H | ||
|
||
#include <QObject> | ||
#include <QByteArray> | ||
|
||
#ifdef __linux__ | ||
#ifndef __LP64__ | ||
#define do_rdtsc _do_rdtsc | ||
#endif | ||
#endif | ||
|
||
class QAESEncryption : public QObject { | ||
Q_OBJECT | ||
public: | ||
enum Aes { | ||
AES_128, | ||
AES_192, | ||
AES_256 | ||
}; | ||
|
||
enum Mode { | ||
ECB, | ||
CBC, | ||
CFB, | ||
OFB | ||
}; | ||
|
||
enum Padding { | ||
ZERO, | ||
PKCS7, | ||
ISO | ||
}; | ||
|
||
static QByteArray | ||
Crypt(QAESEncryption::Aes level, QAESEncryption::Mode mode, const QByteArray &rawText, const QByteArray &key, | ||
const QByteArray &iv = NULL, QAESEncryption::Padding padding = QAESEncryption::ISO); | ||
|
||
static QByteArray | ||
Decrypt(QAESEncryption::Aes level, QAESEncryption::Mode mode, const QByteArray &rawText, const QByteArray &key, | ||
const QByteArray &iv = NULL, QAESEncryption::Padding padding = QAESEncryption::ISO); | ||
|
||
static QByteArray ExpandKey(QAESEncryption::Aes level, QAESEncryption::Mode mode, const QByteArray &key); | ||
|
||
static QByteArray RemovePadding(const QByteArray &rawText, QAESEncryption::Padding padding); | ||
|
||
QAESEncryption(QAESEncryption::Aes level, QAESEncryption::Mode mode, | ||
QAESEncryption::Padding padding = QAESEncryption::ISO); | ||
|
||
QByteArray encode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv = NULL); | ||
|
||
QByteArray decode(const QByteArray &rawText, const QByteArray &key, const QByteArray &iv = NULL); | ||
|
||
QByteArray removePadding(const QByteArray &rawText); | ||
|
||
QByteArray expandKey(const QByteArray &key); | ||
|
||
QByteArray printArray(uchar *arr, int size); | ||
|
||
signals: | ||
|
||
public slots: | ||
|
||
private: | ||
int m_nb; | ||
int m_blocklen; | ||
int m_level; | ||
int m_mode; | ||
int m_nk; | ||
int m_keyLen; | ||
int m_nr; | ||
int m_expandedKey; | ||
int m_padding; | ||
bool m_aesNIAvailable; | ||
QByteArray *m_state; | ||
|
||
struct AES256 { | ||
int nk = 8; | ||
int keylen = 32; | ||
int nr = 14; | ||
int expandedKey = 240; | ||
}; | ||
|
||
struct AES192 { | ||
int nk = 6; | ||
int keylen = 24; | ||
int nr = 12; | ||
int expandedKey = 209; | ||
}; | ||
|
||
struct AES128 { | ||
int nk = 4; | ||
int keylen = 16; | ||
int nr = 10; | ||
int expandedKey = 176; | ||
}; | ||
|
||
quint8 getSBoxValue(quint8 num) { return sbox[num]; } | ||
|
||
quint8 getSBoxInvert(quint8 num) { return rsbox[num]; } | ||
|
||
void addRoundKey(const quint8 round, const QByteArray expKey); | ||
|
||
void subBytes(); | ||
|
||
void shiftRows(); | ||
|
||
void mixColumns(); | ||
|
||
void invMixColumns(); | ||
|
||
void invSubBytes(); | ||
|
||
void invShiftRows(); | ||
|
||
QByteArray getPadding(int currSize, int alignment); | ||
|
||
QByteArray cipher(const QByteArray &expKey, const QByteArray &plainText); | ||
QByteArray invCipher(const QByteArray &expKey, const QByteArray &plainText); | ||
QByteArray byteXor(const QByteArray &in, const QByteArray &iv); | ||
|
||
const quint8 sbox[256] = { | ||
//0 1 2 3 4 5 6 7 8 9 A B C D E F | ||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, | ||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, | ||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, | ||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, | ||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, | ||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, | ||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, | ||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, | ||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, | ||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, | ||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, | ||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, | ||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, | ||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, | ||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, | ||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; | ||
|
||
const quint8 rsbox[256] = { | ||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, | ||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, | ||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, | ||
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, | ||
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, | ||
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, | ||
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, | ||
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, | ||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, | ||
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, | ||
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, | ||
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, | ||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, | ||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, | ||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, | ||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d}; | ||
|
||
// The round constant word array, Rcon[i], contains the values given by | ||
// x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8) | ||
// Only the first 14 elements are needed | ||
const quint8 Rcon[14] = { | ||
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab}; | ||
}; | ||
|
||
#endif // QAESENCRYPTION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// | ||
// Created by Angelo DeLuca on 5/1/20. | ||
// | ||
|
||
#include <QString> | ||
#include <QList> | ||
#include <QUuid> | ||
#include <QDebug> | ||
#include "AuthenticationUtilities.h" | ||
|
||
QString AuthenticationUtilities::generateClientState() { | ||
// Client state was analyzed to be formatted like so: | ||
// XXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | ||
// (20 random chars)_(36 random chars) | ||
|
||
// Both sides of client state will be stored within this list. | ||
QList<QString> clientstate; | ||
|
||
// Since GUID produces 32 characters (excluding the -'s), we must only use 20 of them. | ||
clientstate.push_back(QUuid::createUuid().toString().remove('-').remove("{").remove("}").mid(0, 20)); | ||
|
||
// Same thing but for 36 chars. | ||
clientstate.push_back( | ||
QUuid::createUuid().toString().remove('-').remove("{").remove("}") | ||
.append(QUuid::createUuid().toString().remove('-').remove("{").remove("}").mid(0, 4))); | ||
|
||
return clientstate[0] + "_" + clientstate[1]; | ||
} | ||
|
||
// Just a standard uppercase UUID | ||
QString AuthenticationUtilities::generateDeviceId() { | ||
return QUuid::createUuid().toString().remove("{").remove("}").toUpper(); | ||
} | ||
|
||
QString AuthenticationUtilities::generateChallenge() { | ||
|
||
// 76 Random Bytes. That's it. | ||
QString result; | ||
for (int i = 0; i < 3; ++i) { | ||
result.append(QUuid::createUuid().toString().remove('-').remove("{").remove("}")); | ||
} | ||
|
||
return result.mid(0, 76).toUtf8().toBase64(); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// | ||
// Created by Angelo DeLuca on 5/1/20. | ||
// | ||
|
||
#ifndef ONHUBDESKTOP_AUTHENTICATIONUTILITIES_H | ||
#define ONHUBDESKTOP_AUTHENTICATIONUTILITIES_H | ||
|
||
#include <QString> | ||
class AuthenticationUtilities { | ||
public: | ||
static QString generateClientState(); | ||
|
||
static QString generateDeviceId(); | ||
|
||
static QString generateChallenge(); | ||
}; | ||
|
||
|
||
#endif //ONHUBDESKTOP_AUTHENTICATIONUTILITIES_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
#include "authdialog.h" | ||
#include "ui_authdialog.h" | ||
#include <QtNetwork> | ||
|
||
AuthDialog::AuthDialog(QWidget *parent) : | ||
QDialog(parent), | ||
ui(new Ui::AuthDialog) { | ||
ui->setupUi(this); | ||
this->setFocus(); | ||
|
||
doLoginPageRequest(); | ||
|
||
} | ||
|
||
AuthDialog::~AuthDialog() { | ||
delete ui; | ||
} | ||
|
||
void AuthDialog::doLoginPageRequest() { | ||
// Gets the URI for the login page. | ||
QNetworkRequest request(QUrl("https://oauthaccountmanager.googleapis.com/v1/authadvice")); | ||
|
||
QJsonObject dataObject; | ||
|
||
dataObject.insert("external_browser", true); | ||
dataObject.insert("report_user_id", true); | ||
dataObject.insert("system_version", "13.4"); | ||
dataObject.insert("app_version", "2.16.4"); | ||
dataObject.insert("user_id", QJsonArray()); | ||
dataObject.insert("safari_authentication_session", true); | ||
dataObject.insert("supported_service", QJsonArray()); | ||
dataObject.insert("request_trigger", "ADD_ACCOUNT"); | ||
dataObject.insert("lib_ver", "3.3"); | ||
dataObject.insert("package_name", "com.google.OnHub"); | ||
dataObject.insert("redirect_uri", "com.google.sso.586698244315-vc96jg3mn4nap78iir799fc2ll3rk18s:/authCallback"); | ||
dataObject.insert("device_name", deviceName); | ||
dataObject.insert("client_id", "586698244315-vc96jg3mn4nap78iir799fc2ll3rk18s.apps.googleusercontent.com"); | ||
dataObject.insert("mediator_client_id", "936475272427.apps.googleusercontent.com"); | ||
dataObject.insert("device_id", deviceId); | ||
dataObject.insert("hl", "en-US"); | ||
dataObject.insert("device_challenge_request", deviceChallenge); | ||
dataObject.insert("client_state", clientState); | ||
|
||
QString data = QJsonDocument(dataObject).toJson(); | ||
|
||
qDebug() << data; | ||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); | ||
|
||
QNetworkAccessManager *manager = new QNetworkAccessManager(); | ||
connect(manager, &QNetworkAccessManager::finished, this, &AuthDialog::loginPageRequestComplete); | ||
manager->post(request, data.toUtf8()); | ||
|
||
|
||
|
||
// manager.deleteLater(); | ||
} | ||
|
||
void AuthDialog::loginPageRequestComplete(QNetworkReply *reply) { | ||
QByteArray body = reply->readAll(); | ||
QJsonObject obj = QJsonDocument::fromJson(body).object(); | ||
|
||
if (obj.contains("uri")) { | ||
|
||
// save random data from request. | ||
QString path = "./gacc"; | ||
QDir directory; | ||
|
||
// Create folder | ||
if (!directory.exists(path)) | ||
directory.mkpath(path); | ||
|
||
QFile deviceInfo(path + "/device.bin"); | ||
deviceInfo.open(QIODevice::WriteOnly); | ||
deviceInfo.write(deviceId.toUtf8()); | ||
deviceInfo.close(); | ||
launchWebEngine(obj["uri"].toString()); | ||
} | ||
} | ||
|
||
|
||
void AuthDialog::launchWebEngine(QString authUri) { | ||
ui->gridLayout->removeWidget(ui->progressBar); | ||
QWebEngineHttpRequest authRequest; | ||
|
||
// Disguise as Apple product... | ||
authRequest.setHeader("User-Agent", | ||
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko)"); | ||
|
||
authRequest.setUrl(QUrl(authUri)); | ||
ui->gridLayout->addWidget(view, 0, 0); | ||
view->load(authRequest); | ||
QWebEngineCookieStore *store = view->page()->profile()->cookieStore(); | ||
store->loadAllCookies(); | ||
connect(store, &QWebEngineCookieStore::cookieAdded, this, &AuthDialog::cookieAdded); | ||
} | ||
|
||
void AuthDialog::cookieAdded(QNetworkCookie cookie) { | ||
if (cookie.name() == "oauth_code") { | ||
view->setDisabled(true); | ||
|
||
ui->gridLayout->addWidget(ui->progressBar, 1, 0); | ||
|
||
QString oauthCode = cookie.value(); | ||
|
||
QNetworkRequest request; | ||
QString data = "client_id=936475272427.apps.googleusercontent.com&code=" + oauthCode + | ||
"&grant_type=authorization_code&scope=https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthLogin"; | ||
request.setUrl(QUrl("https://www.googleapis.com/oauth2/v4/token")); | ||
QNetworkAccessManager *manager = new QNetworkAccessManager(); | ||
connect(manager, &QNetworkAccessManager::finished, this, &AuthDialog::saveRefreshToken); | ||
manager->post(request, data.toUtf8()); | ||
|
||
|
||
} | ||
} | ||
|
||
void AuthDialog::saveRefreshToken(QNetworkReply *reply) { | ||
QByteArray body = reply->readAll(); | ||
QJsonObject obj = QJsonDocument::fromJson(body).object(); | ||
if (obj.contains("refresh_token")) { | ||
// Victory! | ||
|
||
QString refreshTkn = obj["refresh_token"].toString(); | ||
|
||
QString path = "./gacc"; | ||
QDir directory; | ||
|
||
if (!directory.exists(path)) | ||
directory.mkpath(path); | ||
|
||
// Perform encryption. | ||
QString key = QSysInfo::machineUniqueId() + | ||
QCryptographicHash::hash(QSysInfo::currentCpuArchitecture().toUtf8(), QCryptographicHash::Sha512); | ||
|
||
|
||
QString iv = QUuid::createUuid().toString(); | ||
|
||
qDebug() << "IV:" + iv; | ||
qDebug() << "key:" + key; | ||
|
||
QByteArray keyHash = QCryptographicHash::hash(key.toLocal8Bit(), QCryptographicHash::Sha256); | ||
QByteArray ivHash = QCryptographicHash::hash(iv.toLocal8Bit(), QCryptographicHash::Md5); | ||
QByteArray enc = QAESEncryption::Crypt(QAESEncryption::AES_256, QAESEncryption::CBC, | ||
refreshTkn.toLocal8Bit(), keyHash, ivHash); | ||
qDebug() << enc; | ||
QJsonObject file; | ||
|
||
file.insert("IV", QTextCodec::codecForMib(106)->toUnicode(ivHash.toBase64())); | ||
file.insert("dat", QTextCodec::codecForMib(106)->toUnicode(enc.toBase64())); | ||
|
||
// Create the new file. | ||
QFile credentials("./gacc/auth.bin"); | ||
credentials.open(QIODevice::WriteOnly); | ||
credentials.write(QJsonDocument(file).toJson()); | ||
credentials.close(); | ||
|
||
emit authComplete(refreshTkn); | ||
close(); | ||
} | ||
} |
Oops, something went wrong.