blob: 2aec2f6f57712ec3e30e0c88a7a519ab37e94c6c [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
17#define LOG_TAG "RpcCertificateUtils"
18#include <log/log.h>
19
20#include <binder/RpcCertificateUtils.h>
21
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,
49 CertificateFormat format) {
50 switch (format) {
51 case CertificateFormat::PEM:
52 return fromPem(cert);
Yifan Hong2c23db12021-08-16 16:59:37 -070053 case CertificateFormat::DER:
54 return fromDer(cert);
Yifan Hong1deca4b2021-09-10 16:16:44 -070055 }
56 LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
57}
58
59std::vector<uint8_t> serializeCertificate(X509* x509, CertificateFormat format) {
60 bssl::UniquePtr<BIO> certBio(BIO_new(BIO_s_mem()));
61 switch (format) {
62 case CertificateFormat::PEM: {
63 TEST_AND_RETURN({}, PEM_write_bio_X509(certBio.get(), x509));
64 } break;
Yifan Hong2c23db12021-08-16 16:59:37 -070065 case CertificateFormat::DER: {
66 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