blob: 483cc7c58fa500603a65d6ee3647b42b43828ca1 [file] [log] [blame]
Yifan Hong1deca4b2021-09-10 16:16:44 -07001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Yifan Hongbb24eea2021-09-17 18:21:56 -070017#define LOG_TAG "RpcTlsUtils"
Yifan Hong1deca4b2021-09-10 16:16:44 -070018#include <log/log.h>
19
Yifan Hongbb24eea2021-09-17 18:21:56 -070020#include <binder/RpcTlsUtils.h>
Yifan Hong1deca4b2021-09-10 16:16:44 -070021
22#include "Utils.h"
23
24namespace android {
25
26namespace {
27
28bssl::UniquePtr<X509> fromPem(const std::vector<uint8_t>& cert) {
29 if (cert.size() > std::numeric_limits<int>::max()) return nullptr;
30 bssl::UniquePtr<BIO> certBio(BIO_new_mem_buf(cert.data(), static_cast<int>(cert.size())));
31 return bssl::UniquePtr<X509>(PEM_read_bio_X509(certBio.get(), nullptr, nullptr, nullptr));
32}
33
Yifan Hong2c23db12021-08-16 16:59:37 -070034bssl::UniquePtr<X509> fromDer(const std::vector<uint8_t>& cert) {
35 if (cert.size() > std::numeric_limits<long>::max()) return nullptr;
36 const unsigned char* data = cert.data();
37 auto expectedEnd = data + cert.size();
38 bssl::UniquePtr<X509> ret(d2i_X509(nullptr, &data, static_cast<long>(cert.size())));
39 if (data != expectedEnd) {
40 ALOGE("%s: %td bytes remaining!", __PRETTY_FUNCTION__, expectedEnd - data);
41 return nullptr;
42 }
43 return ret;
44}
45
Yifan Hong1deca4b2021-09-10 16:16:44 -070046} // namespace
47
48bssl::UniquePtr<X509> deserializeCertificate(const std::vector<uint8_t>& cert,
Yifan Hong9734cfc2021-09-13 16:14:09 -070049 RpcCertificateFormat format) {
Yifan Hong1deca4b2021-09-10 16:16:44 -070050 switch (format) {
Yifan Hong9734cfc2021-09-13 16:14:09 -070051 case RpcCertificateFormat::PEM:
Yifan Hong1deca4b2021-09-10 16:16:44 -070052 return fromPem(cert);
Yifan Hong9734cfc2021-09-13 16:14:09 -070053 case RpcCertificateFormat::DER:
Yifan Hong2c23db12021-08-16 16:59:37 -070054 return fromDer(cert);
Yifan Hong1deca4b2021-09-10 16:16:44 -070055 }
56 LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
57}
58
Yifan Hong9734cfc2021-09-13 16:14:09 -070059std::vector<uint8_t> serializeCertificate(X509* x509, RpcCertificateFormat format) {
Yifan Hong1deca4b2021-09-10 16:16:44 -070060 bssl::UniquePtr<BIO> certBio(BIO_new(BIO_s_mem()));
61 switch (format) {
Yifan Hong9734cfc2021-09-13 16:14:09 -070062 case RpcCertificateFormat::PEM: {
Yifan Hong1deca4b2021-09-10 16:16:44 -070063 TEST_AND_RETURN({}, PEM_write_bio_X509(certBio.get(), x509));
64 } break;
Yifan Hong9734cfc2021-09-13 16:14:09 -070065 case RpcCertificateFormat::DER: {
Yifan Hong2c23db12021-08-16 16:59:37 -070066 TEST_AND_RETURN({}, i2d_X509_bio(certBio.get(), x509));
67 } break;
Yifan Hong1deca4b2021-09-10 16:16:44 -070068 default: {
69 LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
70 }
71 }
72 const uint8_t* data;
73 size_t len;
74 TEST_AND_RETURN({}, BIO_mem_contents(certBio.get(), &data, &len));
75 return std::vector<uint8_t>(data, data + len);
76}
77
78} // namespace android