/* * Copyright 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common/libs/security/confui_sign.h" #include #include #include #include #include "common/libs/fs/shared_buf.h" namespace cuttlefish { bool ConfUiSignerImpl::Send(SharedFD output, const confui::SignMessageError error, const std::vector& payload) { #define SET_FLAG_AND_RETURN_SEND \ sign_status_ |= kIoError; \ return false // this looks redundant but makes sure that the byte-length of // the error is guaranteed to be the same when it is received confui::SignRawMessage msg; msg.error_ = error; auto n_written_err = WriteAllBinary(output, &(msg.error_)); if (n_written_err != sizeof(msg.error_)) { sign_status_ |= kIoError; SET_FLAG_AND_RETURN_SEND; } decltype(msg.payload_.size()) payload_size = payload.size(); auto n_written_payload_size = WriteAllBinary(output, &payload_size); if (n_written_payload_size != sizeof(payload_size)) { SET_FLAG_AND_RETURN_SEND; } const char* buf = reinterpret_cast(payload.data()); auto n_written_payload = WriteAll(output, buf, payload.size()); if (n_written_payload != payload.size()) { SET_FLAG_AND_RETURN_SEND; } return true; } std::optional ConfUiSignerImpl::Receive( SharedFD input) { confui::SignRawMessage msg; auto n_read = ReadExactBinary(input, &(msg.error_)); if (n_read != sizeof(msg.error_)) { sign_status_ |= kIoError; } if (msg.error_ != confui::SignMessageError::kOk) { sign_status_ |= kLogicError; } if (!IsOk()) { return std::nullopt; } decltype(msg.payload_.size()) payload_size = 0; n_read = ReadExactBinary(input, &payload_size); if (n_read != sizeof(payload_size)) { sign_status_ |= kIoError; return std::nullopt; } std::vector buffer(payload_size); char* buf_data = reinterpret_cast(buffer.data()); n_read = ReadExact(input, buf_data, payload_size); if (n_read != payload_size) { sign_status_ |= kIoError; return std::nullopt; } msg.payload_.swap(buffer); return {msg}; } std::optional ConfUiSignSender::Receive() { return impl_.Receive(server_fd_); } bool ConfUiSignSender::Send(const SignMessageError error, const std::vector& encoded_hmac) { if (!impl_.IsOk()) { return false; } impl_.Send(server_fd_, error, encoded_hmac); return impl_.IsOk(); } bool ConfUiSignRequester::Request(const std::vector& message) { impl_.Send(client_fd_, confui::SignMessageError::kOk, message); return impl_.IsOk(); } std::optional ConfUiSignRequester::Receive() { if (!impl_.IsOk()) { return std::nullopt; } return impl_.Receive(client_fd_); } } // namespace cuttlefish