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