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

Commit 1deca4b9 authored by Yifan Hong's avatar Yifan Hong
Browse files

binder: implement simple TLS verification for testing

Implements RpcCertificateVerifierSimple with an algorithm
that treats all certificates as leaf certificates.

Fix existing tests to set certificates properly. Also
add a test that checks that bad certificates are rejected.

Also adds RpcCertificateUtils that includes function for
(de)serializing certificates. These util functions are useful
for implementing RpcCertificateVerifier.

Test: binderRpcTest
Bug: 195166979
Fixes: 196422181
Fixes: 198833574
Change-Id: I6c1f0f88fe5bc712f3890426d6da26c9ad046d79
parent 2ec5688a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -262,6 +262,7 @@ cc_defaults {
    ],
    srcs: [
        "RpcTransportTls.cpp",
        "RpcCertificateUtils.cpp",
    ],
}

+61 −0
Original line number 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.
 */

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

#include <binder/RpcCertificateUtils.h>

#include "Utils.h"

namespace android {

namespace {

bssl::UniquePtr<X509> fromPem(const std::vector<uint8_t>& cert) {
    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())));
    return bssl::UniquePtr<X509>(PEM_read_bio_X509(certBio.get(), nullptr, nullptr, nullptr));
}

} // namespace

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

std::vector<uint8_t> serializeCertificate(X509* x509, CertificateFormat format) {
    bssl::UniquePtr<BIO> certBio(BIO_new(BIO_s_mem()));
    switch (format) {
        case CertificateFormat::PEM: {
            TEST_AND_RETURN({}, PEM_write_bio_X509(certBio.get(), x509));
        } break;
        default: {
            LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
        }
    }
    const uint8_t* data;
    size_t len;
    TEST_AND_RETURN({}, BIO_mem_contents(certBio.get(), &data, &len));
    return std::vector<uint8_t>(data, data + len);
}

} // namespace android
+4 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <openssl/bn.h>
#include <openssl/ssl.h>

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

#include "FdTrigger.h"
@@ -459,9 +460,9 @@ protected:
    std::shared_ptr<RpcCertificateVerifier> mCertVerifier;
};

std::vector<uint8_t> RpcTransportCtxTls::getCertificate(CertificateFormat) const {
    // TODO(b/195166979): return certificate here
    return {};
std::vector<uint8_t> RpcTransportCtxTls::getCertificate(CertificateFormat format) const {
    X509* x509 = SSL_CTX_get0_certificate(mCtx.get()); // does not own
    return serializeCertificate(x509, format);
}

// Verify by comparing the leaf of peer certificate with every certificate in
+11 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@

#pragma once

#include <string>

namespace android {

enum class CertificateFormat {
@@ -25,4 +27,13 @@ enum class CertificateFormat {
    // TODO(b/195166979): support other formats, e.g. DER
};

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

} // namespace android
+34 −0
Original line number 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.
 */

// Utilities for serializing and deserializing X509 certificates.

#pragma once

#include <vector>

#include <openssl/ssl.h>

#include <binder/CertificateFormat.h>

namespace android {

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

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

} // namespace android
Loading