Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef28ca4c authored by Joshua Duong's avatar Joshua Duong
Browse files

Move adb RSA utilities into its own library.

Since both the client and daemon will now be generating keys.

BUG: b/111434128

Test: atest adb_crypto_test
Change-Id: I6fac562ae5629ab30b6639fbd88d822dae6e96bd
parent 9e96e710
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -3,6 +3,12 @@
    {
      "name": "adbd_test"
    },
    {
      "name": "adb_crypto_test"
    },
    {
      "name": "adb_tls_connection_test"
    },
    {
      "name": "CtsInitTestCases"
    },
+6 −0
Original line number Diff line number Diff line
@@ -255,6 +255,8 @@ cc_library_host_static {
    },

    static_libs: [
        "libadb_crypto",
        "libadb_protos",
        "libbase",
        "libcrypto_utils",
        "libcrypto",
@@ -272,6 +274,7 @@ cc_test_host {
    defaults: ["adb_defaults"],
    srcs: libadb_test_srcs,
    static_libs: [
        "libadb_crypto",
        "libadb_host",
        "libbase",
        "libcutils",
@@ -347,6 +350,7 @@ cc_binary_host {
    ],

    static_libs: [
        "libadb_crypto",
        "libadb_host",
        "libandroidfw",
        "libbase",
@@ -422,6 +426,7 @@ cc_library_static {
    ],

    shared_libs: [
        "libadb_crypto",
        "libadbd_auth",
        "libasyncio",
        "libbase",
@@ -765,6 +770,7 @@ cc_test_host {
        "fastdeploy/deploypatchgenerator/patch_utils_test.cpp",
    ],
    static_libs: [
        "libadb_crypto",
        "libadb_host",
        "libandroidfw",
        "libbase",
+22 −71
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <set>
#include <string>

#include <adb/crypto/rsa_2048_key.h>
#include <android-base/errors.h>
#include <android-base/file.h>
#include <android-base/stringprintf.h>
@@ -53,100 +54,50 @@ static std::map<std::string, std::shared_ptr<RSA>>& g_keys =
    *new std::map<std::string, std::shared_ptr<RSA>>;
static std::map<int, std::string>& g_monitored_paths = *new std::map<int, std::string>;

static std::string get_user_info() {
    std::string hostname;
    if (getenv("HOSTNAME")) hostname = getenv("HOSTNAME");
#if !defined(_WIN32)
    char buf[64];
    if (hostname.empty() && gethostname(buf, sizeof(buf)) != -1) hostname = buf;
#endif
    if (hostname.empty()) hostname = "unknown";

    std::string username;
    if (getenv("LOGNAME")) username = getenv("LOGNAME");
#if !defined(_WIN32)
    if (username.empty() && getlogin()) username = getlogin();
#endif
    if (username.empty()) hostname = "unknown";
using namespace adb::crypto;

    return " " + username + "@" + hostname;
}

static bool calculate_public_key(std::string* out, RSA* private_key) {
    uint8_t binary_key_data[ANDROID_PUBKEY_ENCODED_SIZE];
    if (!android_pubkey_encode(private_key, binary_key_data, sizeof(binary_key_data))) {
        LOG(ERROR) << "Failed to convert to public key";
        return false;
    }
static bool generate_key(const std::string& file) {
    LOG(INFO) << "generate_key(" << file << ")...";

    size_t expected_length;
    if (!EVP_EncodedLength(&expected_length, sizeof(binary_key_data))) {
        LOG(ERROR) << "Public key too large to base64 encode";
    auto rsa_2048 = CreateRSA2048Key();
    if (!rsa_2048) {
        LOG(ERROR) << "Unable to create key";
        return false;
    }

    out->resize(expected_length);
    size_t actual_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(out->data()), binary_key_data,
                                           sizeof(binary_key_data));
    out->resize(actual_length);
    out->append(get_user_info());
    return true;
}

static int generate_key(const std::string& file) {
    LOG(INFO) << "generate_key(" << file << ")...";

    mode_t old_mask;
    FILE *f = nullptr;
    int ret = 0;
    std::string pubkey;

    EVP_PKEY* pkey = EVP_PKEY_new();
    BIGNUM* exponent = BN_new();
    RSA* rsa = RSA_new();
    if (!pkey || !exponent || !rsa) {
        LOG(ERROR) << "Failed to allocate key";
        goto out;
    }

    BN_set_word(exponent, RSA_F4);
    RSA_generate_key_ex(rsa, 2048, exponent, nullptr);
    EVP_PKEY_set1_RSA(pkey, rsa);
    RSA* rsa = EVP_PKEY_get0_RSA(rsa_2048->GetEvpPkey());
    CHECK(rsa);

    if (!calculate_public_key(&pubkey, rsa)) {
    if (!CalculatePublicKey(&pubkey, rsa)) {
        LOG(ERROR) << "failed to calculate public key";
        goto out;
        return false;
    }

    old_mask = umask(077);
    mode_t old_mask = umask(077);

    f = fopen(file.c_str(), "w");
    std::unique_ptr<FILE, decltype(&fclose)> f(nullptr, &fclose);
    f.reset(fopen(file.c_str(), "w"));
    if (!f) {
        PLOG(ERROR) << "Failed to open " << file;
        umask(old_mask);
        goto out;
        return false;
    }

    umask(old_mask);

    if (!PEM_write_PrivateKey(f, pkey, nullptr, nullptr, 0, nullptr, nullptr)) {
    if (!PEM_write_PrivateKey(f.get(), rsa_2048->GetEvpPkey(), nullptr, nullptr, 0, nullptr,
                              nullptr)) {
        LOG(ERROR) << "Failed to write key";
        goto out;
        return false;
    }

    if (!android::base::WriteStringToFile(pubkey, file + ".pub")) {
        PLOG(ERROR) << "failed to write public key";
        goto out;
        return false;
    }

    ret = 1;

out:
    if (f) fclose(f);
    EVP_PKEY_free(pkey);
    RSA_free(rsa);
    BN_free(exponent);
    return ret;
    return true;
}

static std::string hash_key(RSA* key) {
@@ -325,7 +276,7 @@ static bool pubkey_from_privkey(std::string* out, const std::string& path) {
    if (!privkey) {
        return false;
    }
    return calculate_public_key(out, privkey.get());
    return CalculatePublicKey(out, privkey.get());
}

std::string adb_auth_get_userkey() {
@@ -343,7 +294,7 @@ std::string adb_auth_get_userkey() {
}

int adb_auth_keygen(const char* filename) {
    return (generate_key(filename) == 0);
    return !generate_key(filename);
}

int adb_auth_pubkey(const char* filename) {

adb/crypto/Android.bp

0 → 100644
+85 −0
Original line number Diff line number Diff line
// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

cc_defaults {
    name: "libadb_crypto_defaults",
    cflags: [
        "-Wall",
        "-Wextra",
        "-Wthread-safety",
        "-Werror",
    ],

    compile_multilib: "both",

    srcs: [
        "key.cpp",
        "rsa_2048_key.cpp",
        "x509_generator.cpp",
    ],

    target: {
        windows: {
            compile_multilib: "first",
            enabled: true,
        },
    },

    export_include_dirs: ["include"],

    visibility: [
        "//system/core/adb:__subpackages__",
    ],

    host_supported: true,
    recovery_available: true,

    stl: "libc++_static",

    shared_libs: [
        "libadb_protos",
        "libbase",
        "liblog",
        "libcrypto",
        "libcrypto_utils",
    ],
}

cc_library {
    name: "libadb_crypto",
    defaults: ["libadb_crypto_defaults"],

    apex_available: [
        "com.android.adbd",
        "test_com.android.adbd",
    ],

    static_libs: [
        "libadb_protos",
    ],
}

// For running atest (b/147158681)
cc_library_static {
    name: "libadb_crypto_static",
    defaults: ["libadb_crypto_defaults"],

    apex_available: [
        "//apex_available:platform",
    ],

    static_libs: [
        "libadb_protos_static",
    ],
}
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <string>

#include <openssl/evp.h>

#include "key_type.pb.h"

namespace adb {
namespace crypto {

// Class that represents a public/private key pair.
class Key {
  public:
    explicit Key(bssl::UniquePtr<EVP_PKEY>&& pkey, adb::proto::KeyType type)
        : pkey_(std::move(pkey)), key_type_(type) {}
    Key(Key&&) = default;
    Key& operator=(Key&&) = default;

    EVP_PKEY* GetEvpPkey() const { return pkey_.get(); }
    adb::proto::KeyType GetKeyType() const { return key_type_; }
    static std::string ToPEMString(EVP_PKEY* pkey);

  private:
    bssl::UniquePtr<EVP_PKEY> pkey_;
    adb::proto::KeyType key_type_;
};  // Key

}  // namespace crypto
}  // namespace adb
Loading