1 /*
2 * Copyright 2022 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 #include "common/libs/security/confui_sign.h"
18
19 #include <cstdint>
20 #include <optional>
21 #include <vector>
22
23 #include <android-base/logging.h>
24
25 #include "common/libs/fs/shared_buf.h"
26
27 namespace cuttlefish {
Send(SharedFD output,const confui::SignMessageError error,const std::vector<std::uint8_t> & payload)28 bool ConfUiSignerImpl::Send(SharedFD output,
29 const confui::SignMessageError error,
30 const std::vector<std::uint8_t>& payload) {
31 #define SET_FLAG_AND_RETURN_SEND \
32 sign_status_ |= kIoError; \
33 return false
34
35 // this looks redundant but makes sure that the byte-length of
36 // the error is guaranteed to be the same when it is received
37 confui::SignRawMessage msg;
38 msg.error_ = error;
39 auto n_written_err = WriteAllBinary(output, &(msg.error_));
40 if (n_written_err != sizeof(msg.error_)) {
41 sign_status_ |= kIoError;
42 SET_FLAG_AND_RETURN_SEND;
43 }
44 decltype(msg.payload_.size()) payload_size = payload.size();
45 auto n_written_payload_size = WriteAllBinary(output, &payload_size);
46 if (n_written_payload_size != sizeof(payload_size)) {
47 SET_FLAG_AND_RETURN_SEND;
48 }
49 const char* buf = reinterpret_cast<const char*>(payload.data());
50 auto n_written_payload = WriteAll(output, buf, payload.size());
51
52 if (n_written_payload != payload.size()) {
53 SET_FLAG_AND_RETURN_SEND;
54 }
55 return true;
56 }
57
Receive(SharedFD input)58 std::optional<confui::SignRawMessage> ConfUiSignerImpl::Receive(
59 SharedFD input) {
60 confui::SignRawMessage msg;
61
62 auto n_read = ReadExactBinary(input, &(msg.error_));
63 if (n_read != sizeof(msg.error_)) {
64 sign_status_ |= kIoError;
65 }
66 if (msg.error_ != confui::SignMessageError::kOk) {
67 sign_status_ |= kLogicError;
68 }
69 if (!IsOk()) {
70 return std::nullopt;
71 }
72
73 decltype(msg.payload_.size()) payload_size = 0;
74 n_read = ReadExactBinary(input, &payload_size);
75 if (n_read != sizeof(payload_size)) {
76 sign_status_ |= kIoError;
77 return std::nullopt;
78 }
79
80 std::vector<std::uint8_t> buffer(payload_size);
81 char* buf_data = reinterpret_cast<char*>(buffer.data());
82 n_read = ReadExact(input, buf_data, payload_size);
83 if (n_read != payload_size) {
84 sign_status_ |= kIoError;
85 return std::nullopt;
86 }
87 msg.payload_.swap(buffer);
88 return {msg};
89 }
90
Receive()91 std::optional<confui::SignRawMessage> ConfUiSignSender::Receive() {
92 return impl_.Receive(server_fd_);
93 }
94
Send(const SignMessageError error,const std::vector<std::uint8_t> & encoded_hmac)95 bool ConfUiSignSender::Send(const SignMessageError error,
96 const std::vector<std::uint8_t>& encoded_hmac) {
97 if (!impl_.IsOk()) {
98 return false;
99 }
100 impl_.Send(server_fd_, error, encoded_hmac);
101 return impl_.IsOk();
102 }
103
Request(const std::vector<std::uint8_t> & message)104 bool ConfUiSignRequester::Request(const std::vector<std::uint8_t>& message) {
105 impl_.Send(client_fd_, confui::SignMessageError::kOk, message);
106 return impl_.IsOk();
107 }
108
Receive()109 std::optional<confui::SignRawMessage> ConfUiSignRequester::Receive() {
110 if (!impl_.IsOk()) {
111 return std::nullopt;
112 }
113 return impl_.Receive(client_fd_);
114 }
115 } // namespace cuttlefish
116