can finally log in
This commit is contained in:
parent
1374b0a668
commit
245eb9d85d
@ -45,12 +45,12 @@ void AWSClient::login(const QString &username, const QString &password)
|
||||
request.setRawHeader("X-Amz-Target", "AWSCognitoIdentityProviderService.InitiateAuth");
|
||||
|
||||
QVariantMap params;
|
||||
params.insert("AuthFlow", "USER_SRP_AUTH");
|
||||
params.insert("AuthFlow", "USER_PASSWORD_AUTH");
|
||||
params.insert("ClientId", clientId);
|
||||
|
||||
QVariantMap authParams;
|
||||
authParams.insert("USERNAME", username);
|
||||
authParams.insert("SRP_A", QByteArray((char*)bytes_A, len_A).toHex());
|
||||
authParams.insert("PASSWORD", password);
|
||||
|
||||
params.insert("AuthParameters", authParams);
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromVariant(params);
|
||||
@ -81,43 +81,37 @@ void AWSClient::initiateAuthReply()
|
||||
qWarning() << "Failed to parse AWS login response" << error.errorString();
|
||||
return;
|
||||
}
|
||||
QVariantMap srpChallenge = jsonDoc.toVariant().toMap();
|
||||
QByteArray challengeName = srpChallenge.value("ChallengeName").toByteArray();
|
||||
QVariantMap challengeParams = srpChallenge.value("ChallengeParameters").toMap();
|
||||
QByteArray secretBlock = challengeParams.value("SECRET_BLOCK").toByteArray();
|
||||
QByteArray srpB = challengeParams.value("SRP_B").toByteArray();
|
||||
QByteArray username = challengeParams.value("USERNAME").toByteArray();
|
||||
char *bytes_M;
|
||||
int len_M;
|
||||
srp_user_process_challenge(m_srpUser, (const unsigned char*)secretBlock.data(), secretBlock.length(), (const unsigned char*)srpB.data(), srpB.length(), (const unsigned char**)&bytes_M, &len_M);
|
||||
|
||||
QUrl url("https://cognito-idp.eu-west-1.amazonaws.com/");
|
||||
QVariantMap authenticationResult = jsonDoc.toVariant().toMap().value("AuthenticationResult").toMap();
|
||||
QByteArray accessToken = authenticationResult.value("AccessToken").toByteArray();
|
||||
QByteArray idToken = authenticationResult.value("IdToken").toByteArray();
|
||||
|
||||
qDebug() << "Have acess token:" << accessToken;
|
||||
qDebug() << "have idToken:" << idToken;
|
||||
|
||||
QUrl url("https://cognito-identity.eu-west-1.amazonaws.com/");
|
||||
|
||||
QUrlQuery query;
|
||||
query.addQueryItem("Action", "RespondToAuthChallenge");
|
||||
query.addQueryItem("Version", "2016-04-18");
|
||||
query.addQueryItem("Action", "GetId");
|
||||
query.addQueryItem("Version", "2016-06-30");
|
||||
url.setQuery(query);
|
||||
|
||||
QNetworkRequest request(url);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-amz-json-1.0");
|
||||
request.setRawHeader("Host", "cognito-idp.eu-west-1.amazonaws.com");
|
||||
request.setRawHeader("X-Amz-Target", "AWSCognitoIdentityProviderService.RespondToAuthChallenge");
|
||||
request.setRawHeader("Host", "cognito-identity.eu-west-1.amazonaws.com");
|
||||
request.setRawHeader("X-Amz-Target", "AWSCognitoIdentityService.GetId");
|
||||
|
||||
QVariantMap logins;
|
||||
logins.insert("cognito-idp.eu-west-1.amazonaws.com/eu-west-1_6eX6YjmXr", idToken);
|
||||
|
||||
QVariantMap params;
|
||||
params.insert("ChallengeName", challengeName.data());
|
||||
|
||||
QVariantMap challengeResponses;
|
||||
challengeResponses.insert("PASSWORD_CLAIM_SIGNATURE", QByteArray(bytes_M, len_M).toHex());
|
||||
challengeResponses.insert("PASSWORD_CLAIM_SECRET_BLOCK", secretBlock.data());
|
||||
challengeResponses.insert("USERNAME", username);
|
||||
challengeResponses.insert("TIMESTAMP", QLocale("en").toString(QDateTime::currentDateTime().toUTC(), "ddd MMM d HH:mm:ss UTC yyyy"));
|
||||
params.insert("ChallengeResponses", challengeResponses);
|
||||
|
||||
params.insert("ClientId", clientId);
|
||||
params.insert("IdentityPoolId", "eu-west-1:108a174c-5786-40f9-966a-1a0cd33d6801");
|
||||
params.insert("Logins", logins);
|
||||
|
||||
jsonDoc = QJsonDocument::fromVariant(params);
|
||||
QByteArray payload = jsonDoc.toJson(QJsonDocument::Compact);
|
||||
|
||||
|
||||
qDebug() << "Posting:\nURL:" << request.url().toString();
|
||||
qDebug() << "HEADERS:";
|
||||
foreach (const QByteArray &headerName, request.rawHeaderList()) {
|
||||
@ -126,75 +120,16 @@ void AWSClient::initiateAuthReply()
|
||||
qDebug().noquote() << "Payload:" << payload;
|
||||
|
||||
reply = m_nam->post(request, payload);
|
||||
connect(reply, &QNetworkReply::finished, this, &AWSClient::respondToAuthChallengeReply);
|
||||
connect(reply, &QNetworkReply::finished, this, &AWSClient::getIdReply);
|
||||
}
|
||||
|
||||
void AWSClient::respondToAuthChallengeReply()
|
||||
void AWSClient::getIdReply()
|
||||
{
|
||||
QNetworkReply* reply = static_cast<QNetworkReply*>(sender());
|
||||
reply->deleteLater();
|
||||
QByteArray data = reply->readAll();
|
||||
qDebug() << "RespondToAuthChallenge reply" << reply->error() << reply->errorString() << qUtf8Printable(data);
|
||||
|
||||
|
||||
// QM
|
||||
}
|
||||
|
||||
QByteArray AWSClient::createClaim(const QByteArray &secretBlock, const QByteArray &srpB, const QByteArray &salt)
|
||||
{
|
||||
// byte[] authSecretBlock = System.Convert.FromBase64String(secretBlock);
|
||||
QByteArray authSecretBlock = QByteArray::fromBase64(secretBlock);
|
||||
|
||||
// BigInteger B = new BigInteger(srp_b, 16);
|
||||
// if (B.Mod(AuthenticationHelper.N).Equals(BigInteger.Zero))
|
||||
// {
|
||||
// throw new Exception("B cannot be zero");
|
||||
// }
|
||||
bool ok;
|
||||
qlonglong b = srpB.toLongLong(&ok, 16);
|
||||
if (!ok) {
|
||||
qWarning() << "Error converting srpB to number";
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
// BigInteger salt = new BigInteger(saltString, 16);
|
||||
qlonglong saltNumber = salt.toLongLong(&ok, 16);
|
||||
if (!ok) {
|
||||
qWarning() << "Error converting salt to number";
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
// We need to generate the key to hash the response based on our A and what AWS sent back
|
||||
byte[] key = getPasswordAuthenticationKey(username, password, poolName, TupleAa, B, salt);
|
||||
|
||||
// HMAC our data with key (HKDF(S)) (the shared secret)
|
||||
byte[] hmac;
|
||||
try
|
||||
{
|
||||
HMAC mac = HMAC.Create("HMACSHA256");
|
||||
mac.Key = key;
|
||||
|
||||
//bytes bytes bytes....
|
||||
byte[] poolNameByte = Encoding.UTF8.GetBytes(poolName);
|
||||
byte[] name = Encoding.UTF8.GetBytes(username);
|
||||
//secretBlock here
|
||||
byte[] timeByte = Encoding.UTF8.GetBytes(formattedTimestamp);
|
||||
byte[] content = new byte[poolNameByte.Length + name.Length + authSecretBlock.Length + timeByte.Length];
|
||||
|
||||
Buffer.BlockCopy(poolNameByte, 0, content, 0, poolNameByte.Length);
|
||||
Buffer.BlockCopy(name, 0, content, poolNameByte.Length, name.Length);
|
||||
Buffer.BlockCopy(authSecretBlock, 0, content, poolNameByte.Length + name.Length, authSecretBlock.Length);
|
||||
Buffer.BlockCopy(timeByte, 0, content, poolNameByte.Length + name.Length + authSecretBlock.Length, timeByte.Length);
|
||||
|
||||
hmac = mac.ComputeHash(content);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception("Exception in authentication", e);
|
||||
}
|
||||
|
||||
return hmac;
|
||||
}
|
||||
|
||||
QByteArray AWSClient::getPasswordAuthenticationKey(const QByteArray &username, const QByteArray &password)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ public:
|
||||
|
||||
private slots:
|
||||
void initiateAuthReply();
|
||||
void respondToAuthChallengeReply();
|
||||
void getIdReply();
|
||||
|
||||
private:
|
||||
QByteArray createClaim(const QByteArray &secretBlock, const QByteArray &srpB, const QByteArray &salt);
|
||||
|
||||
Reference in New Issue
Block a user