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

Commit 4ca3c7c7 authored by Yifan Hong's avatar Yifan Hong Committed by Automerger Merge Worker
Browse files

Merge changes I7b88f216,I87ca34d0,I1cc4c14a am: aa677d97 am: aebcaf45 am:...

Merge changes I7b88f216,I87ca34d0,I1cc4c14a am: aa677d97 am: aebcaf45 am: 16be1eb4 am: 2e6fe8ce

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1830389

Change-Id: I0f3ee0e11e34971a211221c94546d4ab0a9fb04c
parents e18a412e 2e6fe8ce
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -253,13 +253,16 @@ cc_defaults {
    export_header_lib_headers: [
    export_header_lib_headers: [
        "libbinder_headers",
        "libbinder_headers",
    ],
    ],
    export_shared_lib_headers: [
        "libssl",
    ],
    export_include_dirs: ["include_tls"],
    export_include_dirs: ["include_tls"],
    static_libs: [
    static_libs: [
        "libbase",
        "libbase",
    ],
    ],
    srcs: [
    srcs: [
        "RpcTransportTls.cpp",
        "RpcTransportTls.cpp",
        "RpcCertificateUtils.cpp",
        "RpcTlsUtils.cpp",
    ],
    ],
}
}


+2 −2
Original line number Original line Diff line number Diff line
@@ -14,10 +14,10 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#define LOG_TAG "RpcCertificateUtils"
#define LOG_TAG "RpcTlsUtils"
#include <log/log.h>
#include <log/log.h>


#include <binder/RpcCertificateUtils.h>
#include <binder/RpcTlsUtils.h>


#include "Utils.h"
#include "Utils.h"


+19 −63
Original line number Original line Diff line number Diff line
@@ -22,7 +22,7 @@
#include <openssl/bn.h>
#include <openssl/bn.h>
#include <openssl/ssl.h>
#include <openssl/ssl.h>


#include <binder/RpcCertificateUtils.h>
#include <binder/RpcTlsUtils.h>
#include <binder/RpcTransportTls.h>
#include <binder/RpcTransportTls.h>


#include "FdTrigger.h"
#include "FdTrigger.h"
@@ -44,8 +44,6 @@ using android::base::Result;
namespace android {
namespace android {
namespace {
namespace {


constexpr const int kCertValidDays = 30;

// Implement BIO for socket that ignores SIGPIPE.
// Implement BIO for socket that ignores SIGPIPE.
int socketNew(BIO* bio) {
int socketNew(BIO* bio) {
    BIO_set_data(bio, reinterpret_cast<void*>(-1));
    BIO_set_data(bio, reinterpret_cast<void*>(-1));
@@ -100,49 +98,6 @@ bssl::UniquePtr<BIO> newSocketBio(android::base::borrowed_fd fd) {
    return ret;
    return ret;
}
}


bssl::UniquePtr<EVP_PKEY> makeKeyPairForSelfSignedCert() {
    bssl::UniquePtr<EC_KEY> ec_key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
    if (ec_key == nullptr || !EC_KEY_generate_key(ec_key.get())) {
        ALOGE("Failed to generate key pair.");
        return nullptr;
    }
    bssl::UniquePtr<EVP_PKEY> evp_pkey(EVP_PKEY_new());
    // Use set1 instead of assign to avoid leaking ec_key when assign fails. set1 increments
    // the refcount of the ec_key, so it is okay to release it at the end of this function.
    if (evp_pkey == nullptr || !EVP_PKEY_set1_EC_KEY(evp_pkey.get(), ec_key.get())) {
        ALOGE("Failed to assign key pair.");
        return nullptr;
    }
    return evp_pkey;
}

bssl::UniquePtr<X509> makeSelfSignedCert(EVP_PKEY* evp_pkey, const int valid_days) {
    bssl::UniquePtr<X509> x509(X509_new());
    bssl::UniquePtr<BIGNUM> serial(BN_new());
    bssl::UniquePtr<BIGNUM> serialLimit(BN_new());
    TEST_AND_RETURN(nullptr, BN_lshift(serialLimit.get(), BN_value_one(), 128));
    TEST_AND_RETURN(nullptr, BN_rand_range(serial.get(), serialLimit.get()));
    TEST_AND_RETURN(nullptr, BN_to_ASN1_INTEGER(serial.get(), X509_get_serialNumber(x509.get())));
    TEST_AND_RETURN(nullptr, X509_gmtime_adj(X509_getm_notBefore(x509.get()), 0));
    TEST_AND_RETURN(nullptr,
                    X509_gmtime_adj(X509_getm_notAfter(x509.get()), 60 * 60 * 24 * valid_days));

    X509_NAME* subject = X509_get_subject_name(x509.get());
    TEST_AND_RETURN(nullptr,
                    X509_NAME_add_entry_by_txt(subject, "O", MBSTRING_ASC,
                                               reinterpret_cast<const uint8_t*>("Android"), -1, -1,
                                               0));
    TEST_AND_RETURN(nullptr,
                    X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC,
                                               reinterpret_cast<const uint8_t*>("BinderRPC"), -1,
                                               -1, 0));
    TEST_AND_RETURN(nullptr, X509_set_issuer_name(x509.get(), subject));

    TEST_AND_RETURN(nullptr, X509_set_pubkey(x509.get(), evp_pkey));
    TEST_AND_RETURN(nullptr, X509_sign(x509.get(), evp_pkey, EVP_sha256()));
    return x509;
}

[[maybe_unused]] void sslDebugLog(const SSL* ssl, int type, int value) {
[[maybe_unused]] void sslDebugLog(const SSL* ssl, int type, int value) {
    switch (type) {
    switch (type) {
        case SSL_CB_HANDSHAKE_START:
        case SSL_CB_HANDSHAKE_START:
@@ -437,7 +392,7 @@ public:
    template <typename Impl,
    template <typename Impl,
              typename = std::enable_if_t<std::is_base_of_v<RpcTransportCtxTls, Impl>>>
              typename = std::enable_if_t<std::is_base_of_v<RpcTransportCtxTls, Impl>>>
    static std::unique_ptr<RpcTransportCtxTls> create(
    static std::unique_ptr<RpcTransportCtxTls> create(
            std::shared_ptr<RpcCertificateVerifier> verifier);
            std::shared_ptr<RpcCertificateVerifier> verifier, RpcAuth* auth);
    std::unique_ptr<RpcTransport> newTransport(android::base::unique_fd fd,
    std::unique_ptr<RpcTransport> newTransport(android::base::unique_fd fd,
                                               FdTrigger* fdTrigger) const override;
                                               FdTrigger* fdTrigger) const override;
    std::vector<uint8_t> getCertificate(RpcCertificateFormat) const override;
    std::vector<uint8_t> getCertificate(RpcCertificateFormat) const override;
@@ -460,17 +415,13 @@ ssl_verify_result_t RpcTransportCtxTls::sslCustomVerify(SSL* ssl, uint8_t* outAl
    LOG_ALWAYS_FATAL_IF(outAlert == nullptr);
    LOG_ALWAYS_FATAL_IF(outAlert == nullptr);
    const char* logPrefix = SSL_is_server(ssl) ? "Server" : "Client";
    const char* logPrefix = SSL_is_server(ssl) ? "Server" : "Client";


    bssl::UniquePtr<X509> peerCert(SSL_get_peer_certificate(ssl)); // Does not set error queue
    LOG_ALWAYS_FATAL_IF(peerCert == nullptr,
                        "%s: libssl should not ask to verify non-existing cert", logPrefix);

    auto ctx = SSL_get_SSL_CTX(ssl); // Does not set error queue
    auto ctx = SSL_get_SSL_CTX(ssl); // Does not set error queue
    LOG_ALWAYS_FATAL_IF(ctx == nullptr);
    LOG_ALWAYS_FATAL_IF(ctx == nullptr);
    // void* -> RpcTransportCtxTls*
    // void* -> RpcTransportCtxTls*
    auto rpcTransportCtxTls = reinterpret_cast<RpcTransportCtxTls*>(SSL_CTX_get_app_data(ctx));
    auto rpcTransportCtxTls = reinterpret_cast<RpcTransportCtxTls*>(SSL_CTX_get_app_data(ctx));
    LOG_ALWAYS_FATAL_IF(rpcTransportCtxTls == nullptr);
    LOG_ALWAYS_FATAL_IF(rpcTransportCtxTls == nullptr);


    status_t verifyStatus = rpcTransportCtxTls->mCertVerifier->verify(peerCert.get(), outAlert);
    status_t verifyStatus = rpcTransportCtxTls->mCertVerifier->verify(ssl, outAlert);
    if (verifyStatus == OK) {
    if (verifyStatus == OK) {
        return ssl_verify_ok;
        return ssl_verify_ok;
    }
    }
@@ -483,16 +434,15 @@ ssl_verify_result_t RpcTransportCtxTls::sslCustomVerify(SSL* ssl, uint8_t* outAl
// provided as a template argument so that this function can initialize an |Impl| object.
// provided as a template argument so that this function can initialize an |Impl| object.
template <typename Impl, typename>
template <typename Impl, typename>
std::unique_ptr<RpcTransportCtxTls> RpcTransportCtxTls::create(
std::unique_ptr<RpcTransportCtxTls> RpcTransportCtxTls::create(
        std::shared_ptr<RpcCertificateVerifier> verifier) {
        std::shared_ptr<RpcCertificateVerifier> verifier, RpcAuth* auth) {
    bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
    bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
    TEST_AND_RETURN(nullptr, ctx != nullptr);
    TEST_AND_RETURN(nullptr, ctx != nullptr);


    auto evp_pkey = makeKeyPairForSelfSignedCert();
    if (status_t authStatus = auth->configure(ctx.get()); authStatus != OK) {
    TEST_AND_RETURN(nullptr, evp_pkey != nullptr);
        ALOGE("%s: Failed to configure auth info: %s", __PRETTY_FUNCTION__,
    auto cert = makeSelfSignedCert(evp_pkey.get(), kCertValidDays);
              statusToString(authStatus).c_str());
    TEST_AND_RETURN(nullptr, cert != nullptr);
        return nullptr;
    TEST_AND_RETURN(nullptr, SSL_CTX_use_PrivateKey(ctx.get(), evp_pkey.get()));
    };
    TEST_AND_RETURN(nullptr, SSL_CTX_use_certificate(ctx.get(), cert.get()));


    // Enable two-way authentication by setting SSL_VERIFY_FAIL_IF_NO_PEER_CERT on server.
    // Enable two-way authentication by setting SSL_VERIFY_FAIL_IF_NO_PEER_CERT on server.
    // Client ignores SSL_VERIFY_FAIL_IF_NO_PEER_CERT flag.
    // Client ignores SSL_VERIFY_FAIL_IF_NO_PEER_CERT flag.
@@ -542,11 +492,13 @@ protected:
} // namespace
} // namespace


std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryTls::newServerCtx() const {
std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryTls::newServerCtx() const {
    return android::RpcTransportCtxTls::create<RpcTransportCtxTlsServer>(mCertVerifier);
    return android::RpcTransportCtxTls::create<RpcTransportCtxTlsServer>(mCertVerifier,
                                                                         mAuth.get());
}
}


std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryTls::newClientCtx() const {
std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryTls::newClientCtx() const {
    return android::RpcTransportCtxTls::create<RpcTransportCtxTlsClient>(mCertVerifier);
    return android::RpcTransportCtxTls::create<RpcTransportCtxTlsClient>(mCertVerifier,
                                                                         mAuth.get());
}
}


const char* RpcTransportCtxFactoryTls::toCString() const {
const char* RpcTransportCtxFactoryTls::toCString() const {
@@ -554,13 +506,17 @@ const char* RpcTransportCtxFactoryTls::toCString() const {
}
}


std::unique_ptr<RpcTransportCtxFactory> RpcTransportCtxFactoryTls::make(
std::unique_ptr<RpcTransportCtxFactory> RpcTransportCtxFactoryTls::make(
        std::shared_ptr<RpcCertificateVerifier> verifier) {
        std::shared_ptr<RpcCertificateVerifier> verifier, std::unique_ptr<RpcAuth> auth) {
    if (verifier == nullptr) {
    if (verifier == nullptr) {
        ALOGE("%s: Must provide a certificate verifier", __PRETTY_FUNCTION__);
        ALOGE("%s: Must provide a certificate verifier", __PRETTY_FUNCTION__);
        return nullptr;
        return nullptr;
    }
    }
    if (auth == nullptr) {
        ALOGE("%s: Must provide an auth provider", __PRETTY_FUNCTION__);
        return nullptr;
    }
    return std::unique_ptr<RpcTransportCtxFactoryTls>(
    return std::unique_ptr<RpcTransportCtxFactoryTls>(
            new RpcTransportCtxFactoryTls(std::move(verifier)));
            new RpcTransportCtxFactoryTls(std::move(verifier), std::move(auth)));
}
}


} // namespace android
} // namespace android
+46 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2021 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 <openssl/ssl.h>
#include <utils/Errors.h>

namespace android {

// An interface with a function that configures the SSL_CTX object with authentication information,
// including certificates and private keys.
class RpcAuth {
public:
    virtual ~RpcAuth() = default;

    // The keys and certificates to provide is up to the implementation. Multiple calls to
    // |configure()| may configure |ctx| with the same keys / certificates, or generate a
    // different key / certificate every time |configure()| is called.
    //
    // It is guaranteed that, when a context object (RpcTransportCtx) is created,
    // libbinder_tls calls |configure()| on server RpcAuth exactly once.
    //
    // The implementation may use the following function to set the private
    // keys and certificates:
    // - SSL_CTX_use_PrivateKey
    // - SSL_CTX_use_certificate
    // - SSL_CTX_set*_chain
    // - SSL_CTX_add0_chain_cert
    virtual status_t configure(SSL_CTX* ctx) = 0;
};

} // namespace android
+12 −1
Original line number Original line Diff line number Diff line
@@ -26,7 +26,18 @@ namespace android {
class RpcCertificateVerifier {
class RpcCertificateVerifier {
public:
public:
    virtual ~RpcCertificateVerifier() = default;
    virtual ~RpcCertificateVerifier() = default;
    virtual status_t verify(const X509* peerCert, uint8_t* outAlert) = 0;

    // The implementation may use the following function to get
    // the peer certificate and chain:
    // - SSL_get_peer_certificate
    // - SSL_get_peer_cert_chain
    // - SSL_get_peer_full_cert_chain
    //
    // The implementation should return OK on success or error codes on error. For example:
    // - PERMISSION_DENIED for rejected certificates
    // - NO_INIT for not presenting a certificate when requested
    // - UNKNOWN_ERROR for other errors
    virtual status_t verify(const SSL* ssl, uint8_t* outAlert) = 0;
};
};


} // namespace android
} // namespace android
Loading