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

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

Merge changes from topic "binder_presigned_keys" am: 89932bc5 am: bfe39dc2...

Merge changes from topic "binder_presigned_keys" am: 89932bc5 am: bfe39dc2 am: 3dc5ef4d am: 241430c7

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

Change-Id: I8ae24564fe3d327d98f2d589255ef22fb04638cf
parents 2f216cef 241430c7
Loading
Loading
Loading
Loading
+61 −28
Original line number Original line Diff line number Diff line
@@ -25,54 +25,87 @@ namespace android {


namespace {
namespace {


bssl::UniquePtr<X509> fromPem(const std::vector<uint8_t>& cert) {
static_assert(sizeof(unsigned char) == sizeof(uint8_t));
    if (cert.size() > std::numeric_limits<int>::max()) return nullptr;

    bssl::UniquePtr<BIO> certBio(BIO_new_mem_buf(cert.data(), static_cast<int>(cert.size())));
template <typename PemReadBioFn,
    return bssl::UniquePtr<X509>(PEM_read_bio_X509(certBio.get(), nullptr, nullptr, nullptr));
          typename T = std::remove_pointer_t<std::invoke_result_t<
                  PemReadBioFn, BIO*, std::nullptr_t, std::nullptr_t, std::nullptr_t>>>
bssl::UniquePtr<T> fromPem(const std::vector<uint8_t>& data, PemReadBioFn fn) {
    if (data.size() > std::numeric_limits<int>::max()) return nullptr;
    bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(data.data(), static_cast<int>(data.size())));
    return bssl::UniquePtr<T>(fn(bio.get(), nullptr, nullptr, nullptr));
}
}


bssl::UniquePtr<X509> fromDer(const std::vector<uint8_t>& cert) {
template <typename D2iFn,
    if (cert.size() > std::numeric_limits<long>::max()) return nullptr;
          typename T = std::remove_pointer_t<
    const unsigned char* data = cert.data();
                  std::invoke_result_t<D2iFn, std::nullptr_t, const unsigned char**, long>>>
    auto expectedEnd = data + cert.size();
bssl::UniquePtr<T> fromDer(const std::vector<uint8_t>& data, D2iFn fn) {
    bssl::UniquePtr<X509> ret(d2i_X509(nullptr, &data, static_cast<long>(cert.size())));
    if (data.size() > std::numeric_limits<long>::max()) return nullptr;
    if (data != expectedEnd) {
    const unsigned char* dataPtr = data.data();
        ALOGE("%s: %td bytes remaining!", __PRETTY_FUNCTION__, expectedEnd - data);
    auto expectedEnd = dataPtr + data.size();
    bssl::UniquePtr<T> ret(fn(nullptr, &dataPtr, static_cast<long>(data.size())));
    if (dataPtr != expectedEnd) {
        ALOGE("%s: %td bytes remaining!", __PRETTY_FUNCTION__, expectedEnd - dataPtr);
        return nullptr;
        return nullptr;
    }
    }
    return ret;
    return ret;
}
}


template <typename T, typename WriteBioFn = int (*)(BIO*, T*)>
std::vector<uint8_t> serialize(T* object, WriteBioFn writeBio) {
    bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
    TEST_AND_RETURN({}, writeBio(bio.get(), object));
    const uint8_t* data;
    size_t len;
    TEST_AND_RETURN({}, BIO_mem_contents(bio.get(), &data, &len));
    return std::vector<uint8_t>(data, data + len);
}

} // namespace
} // namespace


bssl::UniquePtr<X509> deserializeCertificate(const std::vector<uint8_t>& cert,
bssl::UniquePtr<X509> deserializeCertificate(const std::vector<uint8_t>& data,
                                             RpcCertificateFormat format) {
                                             RpcCertificateFormat format) {
    switch (format) {
    switch (format) {
        case RpcCertificateFormat::PEM:
        case RpcCertificateFormat::PEM:
            return fromPem(cert);
            return fromPem(data, PEM_read_bio_X509);
        case RpcCertificateFormat::DER:
        case RpcCertificateFormat::DER:
            return fromDer(cert);
            return fromDer(data, d2i_X509);
    }
    }
    LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
    LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
}
}


std::vector<uint8_t> serializeCertificate(X509* x509, RpcCertificateFormat format) {
std::vector<uint8_t> serializeCertificate(X509* x509, RpcCertificateFormat format) {
    bssl::UniquePtr<BIO> certBio(BIO_new(BIO_s_mem()));
    switch (format) {
    switch (format) {
        case RpcCertificateFormat::PEM: {
        case RpcCertificateFormat::PEM:
            TEST_AND_RETURN({}, PEM_write_bio_X509(certBio.get(), x509));
            return serialize(x509, PEM_write_bio_X509);
        } break;
        case RpcCertificateFormat::DER:
        case RpcCertificateFormat::DER: {
            return serialize(x509, i2d_X509_bio);
            TEST_AND_RETURN({}, i2d_X509_bio(certBio.get(), x509));
    }
        } break;
    LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
        default: {
}

bssl::UniquePtr<EVP_PKEY> deserializeUnencryptedPrivatekey(const std::vector<uint8_t>& data,
                                                           RpcKeyFormat format) {
    switch (format) {
        case RpcKeyFormat::PEM:
            return fromPem(data, PEM_read_bio_PrivateKey);
        case RpcKeyFormat::DER:
            return fromDer(data, d2i_AutoPrivateKey);
    }
    LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
    LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
}
}

std::vector<uint8_t> serializeUnencryptedPrivatekey(EVP_PKEY* pkey, RpcKeyFormat format) {
    switch (format) {
        case RpcKeyFormat::PEM:
            return serialize(pkey, [](BIO* bio, EVP_PKEY* pkey) {
                return PEM_write_bio_PrivateKey(bio, pkey, nullptr /* enc */, nullptr /* kstr */,
                                                0 /* klen */, nullptr, nullptr);
            });
        case RpcKeyFormat::DER:
            return serialize(pkey, i2d_PrivateKey_bio);
    }
    }
    const uint8_t* data;
    LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
    size_t len;
    TEST_AND_RETURN({}, BIO_mem_contents(certBio.get(), &data, &len));
    return std::vector<uint8_t>(data, data + len);
}
}


} // namespace android
} // namespace android
+41 −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.
 */

// Formats for serializing TLS private keys.

#pragma once

#include <string>

namespace android {

enum class RpcKeyFormat {
    PEM,
    DER,
};

static inline std::string PrintToString(RpcKeyFormat format) {
    switch (format) {
        case RpcKeyFormat::PEM:
            return "PEM";
        case RpcKeyFormat::DER:
            return "DER";
        default:
            return "<unknown>";
    }
}

} // namespace android
+9 −1
Original line number Original line Diff line number Diff line
@@ -23,12 +23,20 @@
#include <openssl/ssl.h>
#include <openssl/ssl.h>


#include <binder/RpcCertificateFormat.h>
#include <binder/RpcCertificateFormat.h>
#include <binder/RpcKeyFormat.h>


namespace android {
namespace android {


bssl::UniquePtr<X509> deserializeCertificate(const std::vector<uint8_t>& cert,
bssl::UniquePtr<X509> deserializeCertificate(const std::vector<uint8_t>& data,
                                             RpcCertificateFormat format);
                                             RpcCertificateFormat format);


std::vector<uint8_t> serializeCertificate(X509* x509, RpcCertificateFormat format);
std::vector<uint8_t> serializeCertificate(X509* x509, RpcCertificateFormat format);


// Deserialize an un-encrypted private key.
bssl::UniquePtr<EVP_PKEY> deserializeUnencryptedPrivatekey(const std::vector<uint8_t>& data,
                                                           RpcKeyFormat format);

// Serialize a private key in un-encrypted form.
std::vector<uint8_t> serializeUnencryptedPrivatekey(EVP_PKEY* pkey, RpcKeyFormat format);

} // namespace android
} // namespace android
+31 −0
Original line number Original line Diff line number Diff line
@@ -173,6 +173,37 @@ cc_test {
    require_root: true,
    require_root: true,
}
}


cc_test {
    name: "RpcTlsUtilsTest",
    host_supported: true,
    target: {
        darwin: {
            enabled: false,
        },
        android: {
            test_suites: ["vts"],
        },
    },
    defaults: [
        "binder_test_defaults",
        "libbinder_tls_shared_deps",
    ],
    srcs: [
        "RpcAuthTesting.cpp",
        "RpcTlsUtilsTest.cpp",
    ],
    shared_libs: [
        "libbinder",
        "libbase",
        "libutils",
        "liblog",
    ],
    static_libs: [
        "libbinder_tls_static",
    ],
    test_suites: ["general-tests", "device-tests"],
}

cc_benchmark {
cc_benchmark {
    name: "binderRpcBenchmark",
    name: "binderRpcBenchmark",
    defaults: ["binder_test_defaults"],
    defaults: ["binder_test_defaults"],
+10 −0
Original line number Original line Diff line number Diff line
@@ -70,4 +70,14 @@ status_t RpcAuthSelfSigned::configure(SSL_CTX* ctx) {
    return OK;
    return OK;
}
}


status_t RpcAuthPreSigned::configure(SSL_CTX* ctx) {
    if (!SSL_CTX_use_PrivateKey(ctx, mPkey.get())) {
        return INVALID_OPERATION;
    }
    if (!SSL_CTX_use_certificate(ctx, mCert.get())) {
        return INVALID_OPERATION;
    }
    return OK;
}

} // namespace android
} // namespace android
Loading