mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-22 22:00:39 -06:00
Merge pull request #12108 from noahpistilli/kd-check-mail
IOS/KD: Implement NWC24_CHECK_MAIL_NOW
This commit is contained in:
@ -29,6 +29,8 @@ add_library(common
|
||||
Crypto/bn.h
|
||||
Crypto/ec.cpp
|
||||
Crypto/ec.h
|
||||
Crypto/HMAC.cpp
|
||||
Crypto/HMAC.h
|
||||
Crypto/SHA1.cpp
|
||||
Crypto/SHA1.h
|
||||
Debug/MemoryPatches.cpp
|
||||
|
27
Source/Core/Common/Crypto/HMAC.cpp
Normal file
27
Source/Core/Common/Crypto/HMAC.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2023 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <mbedtls/hmac_drbg.h>
|
||||
|
||||
#include "Common/Crypto/HMAC.h"
|
||||
#include "Common/ScopeGuard.h"
|
||||
|
||||
namespace Common::HMAC
|
||||
{
|
||||
bool HMACWithSHA1(std::span<const u8> key, std::span<const u8> msg, u8* out)
|
||||
{
|
||||
mbedtls_md_context_t ctx;
|
||||
Common::ScopeGuard guard{[&ctx] { mbedtls_md_free(&ctx); }};
|
||||
mbedtls_md_init(&ctx);
|
||||
if (mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 1))
|
||||
return false;
|
||||
|
||||
if (mbedtls_md_hmac_starts(&ctx, key.data(), key.size()) ||
|
||||
mbedtls_md_hmac_update(&ctx, msg.data(), msg.size()) || mbedtls_md_hmac_finish(&ctx, out))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace Common::HMAC
|
14
Source/Core/Common/Crypto/HMAC.h
Normal file
14
Source/Core/Common/Crypto/HMAC.h
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2023 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
#include <span>
|
||||
|
||||
namespace Common::HMAC
|
||||
{
|
||||
// HMAC with the SHA1 message digest. Excepted output length is 20 bytes.
|
||||
bool HMACWithSHA1(std::span<const u8> key, std::span<const u8> msg, u8* out);
|
||||
} // namespace Common::HMAC
|
@ -27,6 +27,7 @@ public:
|
||||
explicit Impl(std::chrono::milliseconds timeout_ms, ProgressCallback callback);
|
||||
|
||||
bool IsValid() const;
|
||||
std::string GetHeaderValue(std::string_view name) const;
|
||||
void SetCookies(const std::string& cookies);
|
||||
void UseIPv4();
|
||||
void FollowRedirects(long max);
|
||||
@ -41,6 +42,7 @@ public:
|
||||
private:
|
||||
static inline std::once_flag s_curl_was_initialized;
|
||||
ProgressCallback m_callback;
|
||||
Headers m_response_headers;
|
||||
std::unique_ptr<CURL, decltype(&curl_easy_cleanup)> m_curl{nullptr, curl_easy_cleanup};
|
||||
std::string m_error_string;
|
||||
};
|
||||
@ -82,6 +84,11 @@ s32 HttpRequest::GetLastResponseCode() const
|
||||
return m_impl->GetLastResponseCode();
|
||||
}
|
||||
|
||||
std::string HttpRequest::GetHeaderValue(std::string_view name) const
|
||||
{
|
||||
return m_impl->GetHeaderValue(name);
|
||||
}
|
||||
|
||||
HttpRequest::Response HttpRequest::Get(const std::string& url, const Headers& headers,
|
||||
AllowedReturnCodes codes)
|
||||
{
|
||||
@ -173,6 +180,17 @@ void HttpRequest::Impl::FollowRedirects(long max)
|
||||
curl_easy_setopt(m_curl.get(), CURLOPT_MAXREDIRS, max);
|
||||
}
|
||||
|
||||
std::string HttpRequest::Impl::GetHeaderValue(std::string_view name) const
|
||||
{
|
||||
for (const auto& [key, value] : m_response_headers)
|
||||
{
|
||||
if (key == name)
|
||||
return value.value();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string HttpRequest::Impl::EscapeComponent(const std::string& string)
|
||||
{
|
||||
char* escaped = curl_easy_escape(m_curl.get(), string.c_str(), static_cast<int>(string.size()));
|
||||
@ -190,10 +208,26 @@ static size_t CurlWriteCallback(char* data, size_t size, size_t nmemb, void* use
|
||||
return actual_size;
|
||||
}
|
||||
|
||||
static size_t header_callback(char* buffer, size_t size, size_t nitems, void* userdata)
|
||||
{
|
||||
auto* headers = static_cast<HttpRequest::Headers*>(userdata);
|
||||
std::string_view full_buffer = std::string_view{buffer, nitems};
|
||||
const size_t colon_pos = full_buffer.find(':');
|
||||
if (colon_pos == std::string::npos)
|
||||
return nitems * size;
|
||||
|
||||
const std::string_view key = full_buffer.substr(0, colon_pos);
|
||||
const std::string_view value = StripWhitespace(full_buffer.substr(colon_pos + 1));
|
||||
|
||||
headers->emplace(std::string{key}, std::string{value});
|
||||
return nitems * size;
|
||||
}
|
||||
|
||||
HttpRequest::Response HttpRequest::Impl::Fetch(const std::string& url, Method method,
|
||||
const Headers& headers, const u8* payload,
|
||||
size_t size, AllowedReturnCodes codes)
|
||||
{
|
||||
m_response_headers.clear();
|
||||
curl_easy_setopt(m_curl.get(), CURLOPT_POST, method == Method::POST);
|
||||
curl_easy_setopt(m_curl.get(), CURLOPT_URL, url.c_str());
|
||||
if (method == Method::POST)
|
||||
@ -215,6 +249,9 @@ HttpRequest::Response HttpRequest::Impl::Fetch(const std::string& url, Method me
|
||||
}
|
||||
curl_easy_setopt(m_curl.get(), CURLOPT_HTTPHEADER, list);
|
||||
|
||||
curl_easy_setopt(m_curl.get(), CURLOPT_HEADERFUNCTION, header_callback);
|
||||
curl_easy_setopt(m_curl.get(), CURLOPT_HEADERDATA, static_cast<void*>(&m_response_headers));
|
||||
|
||||
std::vector<u8> buffer;
|
||||
curl_easy_setopt(m_curl.get(), CURLOPT_WRITEFUNCTION, CurlWriteCallback);
|
||||
curl_easy_setopt(m_curl.get(), CURLOPT_WRITEDATA, &buffer);
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
void FollowRedirects(long max = 1);
|
||||
s32 GetLastResponseCode() const;
|
||||
std::string EscapeComponent(const std::string& string);
|
||||
std::string GetHeaderValue(std::string_view name) const;
|
||||
Response Get(const std::string& url, const Headers& headers = {},
|
||||
AllowedReturnCodes codes = AllowedReturnCodes::Ok_Only);
|
||||
Response Post(const std::string& url, const std::vector<u8>& payload, const Headers& headers = {},
|
||||
|
@ -693,4 +693,9 @@ bool CaseInsensitiveEquals(std::string_view a, std::string_view b)
|
||||
return std::equal(a.begin(), a.end(), b.begin(),
|
||||
[](char ca, char cb) { return Common::ToLower(ca) == Common::ToLower(cb); });
|
||||
}
|
||||
|
||||
std::string BytesToHexString(std::span<const u8> bytes)
|
||||
{
|
||||
return fmt::format("{:02x}", fmt::join(bytes, ""));
|
||||
}
|
||||
} // namespace Common
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <locale>
|
||||
#include <span>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
@ -313,4 +314,5 @@ std::string GetEscapedHtml(std::string html);
|
||||
void ToLower(std::string* str);
|
||||
void ToUpper(std::string* str);
|
||||
bool CaseInsensitiveEquals(std::string_view a, std::string_view b);
|
||||
std::string BytesToHexString(std::span<const u8> bytes);
|
||||
} // namespace Common
|
||||
|
Reference in New Issue
Block a user