Yifan Hong | 1deca4b | 2021-09-10 16:16:44 -0700 | [diff] [blame] | 1 | /* |
| 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 Hong | bb24eea | 2021-09-17 18:21:56 -0700 | [diff] [blame^] | 17 | #define LOG_TAG "RpcTlsUtils" |
Yifan Hong | 1deca4b | 2021-09-10 16:16:44 -0700 | [diff] [blame] | 18 | #include <log/log.h> |
| 19 | |
Yifan Hong | bb24eea | 2021-09-17 18:21:56 -0700 | [diff] [blame^] | 20 | #include <binder/RpcTlsUtils.h> |
Yifan Hong | 1deca4b | 2021-09-10 16:16:44 -0700 | [diff] [blame] | 21 | |
| 22 | #include "Utils.h" |
| 23 | |
| 24 | namespace android { |
| 25 | |
| 26 | namespace { |
| 27 | |
| 28 | bssl::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 Hong | 2c23db1 | 2021-08-16 16:59:37 -0700 | [diff] [blame] | 34 | bssl::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 Hong | 1deca4b | 2021-09-10 16:16:44 -0700 | [diff] [blame] | 46 | } // namespace |
| 47 | |
| 48 | bssl::UniquePtr<X509> deserializeCertificate(const std::vector<uint8_t>& cert, |
Yifan Hong | 9734cfc | 2021-09-13 16:14:09 -0700 | [diff] [blame] | 49 | RpcCertificateFormat format) { |
Yifan Hong | 1deca4b | 2021-09-10 16:16:44 -0700 | [diff] [blame] | 50 | switch (format) { |
Yifan Hong | 9734cfc | 2021-09-13 16:14:09 -0700 | [diff] [blame] | 51 | case RpcCertificateFormat::PEM: |
Yifan Hong | 1deca4b | 2021-09-10 16:16:44 -0700 | [diff] [blame] | 52 | return fromPem(cert); |
Yifan Hong | 9734cfc | 2021-09-13 16:14:09 -0700 | [diff] [blame] | 53 | case RpcCertificateFormat::DER: |
Yifan Hong | 2c23db1 | 2021-08-16 16:59:37 -0700 | [diff] [blame] | 54 | return fromDer(cert); |
Yifan Hong | 1deca4b | 2021-09-10 16:16:44 -0700 | [diff] [blame] | 55 | } |
| 56 | LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format)); |
| 57 | } |
| 58 | |
Yifan Hong | 9734cfc | 2021-09-13 16:14:09 -0700 | [diff] [blame] | 59 | std::vector<uint8_t> serializeCertificate(X509* x509, RpcCertificateFormat format) { |
Yifan Hong | 1deca4b | 2021-09-10 16:16:44 -0700 | [diff] [blame] | 60 | bssl::UniquePtr<BIO> certBio(BIO_new(BIO_s_mem())); |
| 61 | switch (format) { |
Yifan Hong | 9734cfc | 2021-09-13 16:14:09 -0700 | [diff] [blame] | 62 | case RpcCertificateFormat::PEM: { |
Yifan Hong | 1deca4b | 2021-09-10 16:16:44 -0700 | [diff] [blame] | 63 | TEST_AND_RETURN({}, PEM_write_bio_X509(certBio.get(), x509)); |
| 64 | } break; |
Yifan Hong | 9734cfc | 2021-09-13 16:14:09 -0700 | [diff] [blame] | 65 | case RpcCertificateFormat::DER: { |
Yifan Hong | 2c23db1 | 2021-08-16 16:59:37 -0700 | [diff] [blame] | 66 | TEST_AND_RETURN({}, i2d_X509_bio(certBio.get(), x509)); |
| 67 | } break; |
Yifan Hong | 1deca4b | 2021-09-10 16:16:44 -0700 | [diff] [blame] | 68 | 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 |