Add some more public keys.

This commit is contained in:
John Preston 2017-12-08 19:24:09 +04:00
parent 951db83ab6
commit 273ac5eaf1
5 changed files with 108 additions and 35 deletions

View File

@ -163,20 +163,6 @@ inline const char *cGUIDStr() {
return gGuidStr;
}
inline const char **cPublicRSAKeys(int &keysCount) {
static const char *(keys[]) = {"\
-----BEGIN RSA PUBLIC KEY-----\n\
MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6\n\
lyDONS789sVoD/xCS9Y0hkkC3gtL1tSfTlgCMOOul9lcixlEKzwKENj1Yz/s7daS\n\
an9tqw3bfUV/nqgbhGX81v/+7RFAEd+RwFnK7a+XYl9sluzHRyVVaTTveB2GazTw\n\
Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+\n\
8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n\n\
Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB\n\
-----END RSA PUBLIC KEY-----"};
keysCount = base::array_size(keys);
return keys;
}
struct BuiltInDc {
int id;
const char *ip;

View File

@ -23,6 +23,55 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "storage/serialize_common.h"
namespace MTP {
namespace {
const char *(PublicRSAKeys[]) = { "\
-----BEGIN RSA PUBLIC KEY-----\n\
MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6\n\
lyDONS789sVoD/xCS9Y0hkkC3gtL1tSfTlgCMOOul9lcixlEKzwKENj1Yz/s7daS\n\
an9tqw3bfUV/nqgbhGX81v/+7RFAEd+RwFnK7a+XYl9sluzHRyVVaTTveB2GazTw\n\
Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+\n\
8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n\n\
Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB\n\
-----END RSA PUBLIC KEY-----", "\
-----BEGIN PUBLIC KEY-----\n\
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAruw2yP/BCcsJliRoW5eB\n\
VBVle9dtjJw+OYED160Wybum9SXtBBLXriwt4rROd9csv0t0OHCaTmRqBcQ0J8fx\n\
hN6/cpR1GWgOZRUAiQxoMnlt0R93LCX/j1dnVa/gVbCjdSxpbrfY2g2L4frzjJvd\n\
l84Kd9ORYjDEAyFnEA7dD556OptgLQQ2e2iVNq8NZLYTzLp5YpOdO1doK+ttrltg\n\
gTCy5SrKeLoCPPbOgGsdxJxyz5KKcZnSLj16yE5HvJQn0CNpRdENvRUXe6tBP78O\n\
39oJ8BTHp9oIjd6XWXAsp2CvK45Ol8wFXGF710w9lwCGNbmNxNYhtIkdqfsEcwR5\n\
JwIDAQAB\n\
-----END PUBLIC KEY-----", "\
-----BEGIN PUBLIC KEY-----\n\
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvfLHfYH2r9R70w8prHbl\n\
Wt/nDkh+XkgpflqQVcnAfSuTtO05lNPspQmL8Y2XjVT4t8cT6xAkdgfmmvnvRPOO\n\
KPi0OfJXoRVylFzAQG/j83u5K3kRLbae7fLccVhKZhY46lvsueI1hQdLgNV9n1cQ\n\
3TDS2pQOCtovG4eDl9wacrXOJTG2990VjgnIKNA0UMoP+KF03qzryqIt3oTvZq03\n\
DyWdGK+AZjgBLaDKSnC6qD2cFY81UryRWOab8zKkWAnhw2kFpcqhI0jdV5QaSCEx\n\
vnsjVaX0Y1N0870931/5Jb9ICe4nweZ9kSDF/gip3kWLG0o8XQpChDfyvsqB9OLV\n\
/wIDAQAB\n\
-----END PUBLIC KEY-----", "\
-----BEGIN PUBLIC KEY-----\n\
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs/ditzm+mPND6xkhzwFI\n\
z6J/968CtkcSE/7Z2qAJiXbmZ3UDJPGrzqTDHkO30R8VeRM/Kz2f4nR05GIFiITl\n\
4bEjvpy7xqRDspJcCFIOcyXm8abVDhF+th6knSU0yLtNKuQVP6voMrnt9MV1X92L\n\
GZQLgdHZbPQz0Z5qIpaKhdyA8DEvWWvSUwwc+yi1/gGaybwlzZwqXYoPOhwMebzK\n\
Uk0xW14htcJrRrq+PXXQbRzTMynseCoPIoke0dtCodbA3qQxQovE16q9zz4Otv2k\n\
4j63cz53J+mhkVWAeWxVGI0lltJmWtEYK6er8VqqWot3nqmWMXogrgRLggv/Nbbo\n\
oQIDAQAB\n\
-----END PUBLIC KEY-----", "\
-----BEGIN PUBLIC KEY-----\n\
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvmpxVY7ld/8DAjz6F6q0\n\
5shjg8/4p6047bn6/m8yPy1RBsvIyvuDuGnP/RzPEhzXQ9UJ5Ynmh2XJZgHoE9xb\n\
nfxL5BXHplJhMtADXKM9bWB11PU1Eioc3+AXBB8QiNFBn2XI5UkO5hPhbb9mJpjA\n\
9Uhw8EdfqJP8QetVsI/xrCEbwEXe0xvifRLJbY08/Gp66KpQvy7g8w7VB8wlgePe\n\
xW3pT13Ap6vuC+mQuJPyiHvSxjEKHgqePji9NP3tJUFQjcECqcm0yV7/2d0t/pbC\n\
m+ZH1sadZspQCEPPrtbkQBlvHb4OLiIWPGHKSMeRFvp3IWcmdJqXahxLCUS1Eh6M\n\
AQIDAQAB\n\
-----END PUBLIC KEY-----" };
} // namespace
class DcOptions::WriteLocker {
public:
@ -49,16 +98,14 @@ private:
};
void DcOptions::readBuiltInPublicKeys() {
auto keysCount = 0;
auto keys = cPublicRSAKeys(keysCount);
for (auto i = 0; i != keysCount; ++i) {
auto keyBytes = gsl::as_bytes(gsl::make_span(keys[i], keys[i] + strlen(keys[i])));
auto key = internal::RSAPublicKey(keyBytes);
if (key.isValid()) {
_publicKeys.emplace(key.getFingerPrint(), std::move(key));
for (const auto key : PublicRSAKeys) {
const auto keyBytes = gsl::make_span(key, key + strlen(key));
auto parsed = internal::RSAPublicKey(gsl::as_bytes(keyBytes));
if (parsed.isValid()) {
_publicKeys.emplace(parsed.getFingerPrint(), std::move(parsed));
} else {
LOG(("MTP Error: could not read this public RSA key:"));
LOG((keys[i]));
LOG((key));
}
}
}
@ -364,11 +411,13 @@ void DcOptions::setCDNConfig(const MTPDcdnConfig &config) {
_cdnPublicKeys.clear();
for_const (auto &publicKey, config.vpublic_keys.v) {
Expects(publicKey.type() == mtpc_cdnPublicKey);
auto &keyData = publicKey.c_cdnPublicKey();
auto keyBytes = gsl::as_bytes(gsl::make_span(keyData.vpublic_key.v));
auto key = internal::RSAPublicKey(keyBytes);
const auto &keyData = publicKey.c_cdnPublicKey();
const auto keyBytes = gsl::make_span(keyData.vpublic_key.v);
auto key = internal::RSAPublicKey(gsl::as_bytes(keyBytes));
if (key.isValid()) {
_cdnPublicKeys[keyData.vdc_id.v].emplace(key.getFingerPrint(), std::move(key));
_cdnPublicKeys[keyData.vdc_id.v].emplace(
key.getFingerPrint(),
std::move(key));
} else {
LOG(("MTP Error: could not read this public RSA key:"));
LOG((qs(keyData.vpublic_key)));

View File

@ -26,9 +26,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include <openssl/bio.h>
#include <openssl/err.h>
using std::string;
namespace MTP {
namespace internal {
namespace {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
@ -66,14 +65,45 @@ void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM
}
#endif
enum class Format {
RSAPublicKey,
RSA_PUBKEY,
Unknown,
};
Format GuessFormat(base::const_byte_span key) {
const auto array = QByteArray::fromRawData(
reinterpret_cast<const char*>(key.data()),
key.size());
if (array.indexOf("BEGIN RSA PUBLIC KEY") >= 0) {
return Format::RSAPublicKey;
} else if (array.indexOf("BEGIN PUBLIC KEY") >= 0) {
return Format::RSA_PUBKEY;
}
return Format::Unknown;
}
namespace internal {
RSA *CreateRaw(base::const_byte_span key) {
const auto format = GuessFormat(key);
const auto bio = BIO_new_mem_buf(
const_cast<gsl::byte*>(key.data()),
key.size());
switch (format) {
case Format::RSAPublicKey:
return PEM_read_bio_RSAPublicKey(bio, nullptr, nullptr, nullptr);
case Format::RSA_PUBKEY:
return PEM_read_bio_RSA_PUBKEY(bio, nullptr, nullptr, nullptr);
}
Unexpected("format in RSAPublicKey::Private::Create.");
}
} // namespace
class RSAPublicKey::Private {
public:
Private(base::const_byte_span key)
: _rsa(PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<gsl::byte*>(key.data()), key.size()), 0, 0, 0)) {
: _rsa(CreateRaw(key)) {
if (_rsa) {
computeFingerprint();
}
@ -174,10 +204,14 @@ private:
};
RSAPublicKey::RSAPublicKey(base::const_byte_span key) : _private(std::make_shared<Private>(key)) {
RSAPublicKey::RSAPublicKey(base::const_byte_span key)
: _private(std::make_shared<Private>(key)) {
}
RSAPublicKey::RSAPublicKey(base::const_byte_span nBytes, base::const_byte_span eBytes) : _private(std::make_shared<Private>(nBytes, eBytes)) {
RSAPublicKey::RSAPublicKey(
base::const_byte_span nBytes,
base::const_byte_span eBytes)
: _private(std::make_shared<Private>(nBytes, eBytes)) {
}
bool RSAPublicKey::isValid() const {

View File

@ -26,15 +26,17 @@ namespace internal {
// this class holds an RSA public key and can encrypt fixed-size messages with it
class RSAPublicKey final {
public:
// key in RSAPublicKey "-----BEGIN RSA PUBLIC KEY----- ..." format
RSAPublicKey() = default;
explicit RSAPublicKey(base::const_byte_span key);
RSAPublicKey(base::const_byte_span nBytes, base::const_byte_span eBytes);
RSAPublicKey(RSAPublicKey &&other) = default;
RSAPublicKey(const RSAPublicKey &other) = default;
RSAPublicKey &operator=(RSAPublicKey &&other) = default;
RSAPublicKey &operator=(const RSAPublicKey &other) = default;
// key in "-----BEGIN RSA PUBLIC KEY----- ..." format
// or in "-----BEGIN PUBLIC KEY----- ..." format
explicit RSAPublicKey(base::const_byte_span key);
bool isValid() const;
uint64 getFingerPrint() const;
base::byte_vector getN() const;

View File

@ -157,7 +157,9 @@ bool SpecialConfigRequest::decryptSimpleConfig(const QByteArray &bytes) {
return false;
}
auto publicKey = internal::RSAPublicKey(gsl::as_bytes(gsl::make_span(kPublicKey.c_str(), kPublicKey.size())));
auto publicKey = internal::RSAPublicKey(gsl::as_bytes(gsl::make_span(
kPublicKey.c_str(),
kPublicKey.size())));
auto decrypted = publicKey.decrypt(gsl::as_bytes(gsl::make_span(decodedBytes)));
auto decryptedBytes = gsl::make_span(decrypted);