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 #pragma once
18 
19 #include <optional>
20 #include <vector>
21 
22 #include "common/libs/fs/shared_fd.h"
23 
24 namespace cuttlefish {
25 namespace confui {
26 enum class SignMessageError : std::uint8_t {
27   kOk = 0,
28   kUnknownError = 1,
29 };
30 
31 struct SignRawMessage {
32   SignMessageError error_;
33   std::vector<std::uint8_t> payload_;
34 };
35 }  // end of namespace confui
36 
37 class ConfUiSignerImpl {
38   // status and its mask bits
39   using ReceiveError = std::uint8_t;
40   static const ReceiveError kIoError = 1;
41   static const ReceiveError kLogicError = 2;
42 
43  public:
ConfUiSignerImpl()44   ConfUiSignerImpl() : sign_status_(0) {}
45 
IsIoError()46   bool IsIoError() const { return (kIoError & sign_status_) != 0; }
47 
IsLogicError()48   bool IsLogicError() const { return (kLogicError & sign_status_) != 0; }
49 
IsOk()50   bool IsOk() const { return !IsIoError() && !IsLogicError(); }
51 
52   // set the sign_status_ if there was an error
53   // TODO(kwstephenkim@): use android::base::Result. aosp/1940753
54   bool Send(SharedFD output, const confui::SignMessageError error,
55             const std::vector<std::uint8_t>& payload);
56   std::optional<confui::SignRawMessage> Receive(SharedFD input);
57 
58  private:
59   ReceiveError sign_status_;
60 };
61 
62 /*
63  * secure_env will use this in order:
64  *
65  *   Receive() // receive request
66  *   Send() // send signature
67  */
68 class ConfUiSignSender {
69   using SignMessageError = confui::SignMessageError;
70 
71  public:
ConfUiSignSender(SharedFD fd)72   ConfUiSignSender(SharedFD fd) : server_fd_(fd) {}
73 
74   // note that the error is IO error
75   std::optional<confui::SignRawMessage> Receive();
76   bool Send(const SignMessageError error,
77             const std::vector<std::uint8_t>& encoded_hmac);
78 
IsOk()79   bool IsOk() const { return impl_.IsOk(); }
IsIoError()80   bool IsIoError() const { return impl_.IsIoError(); }
IsLogicError()81   bool IsLogicError() const { return impl_.IsLogicError(); }
82 
83  private:
84   SharedFD server_fd_;
85   ConfUiSignerImpl impl_;
86 };
87 
88 /**
89  * confirmation UI host will use this in this order:
90  *
91  *   Request()
92  *   Receive()
93  */
94 class ConfUiSignRequester {
95   using SignMessageError = confui::SignMessageError;
96 
97  public:
ConfUiSignRequester(SharedFD fd)98   ConfUiSignRequester(SharedFD fd) : client_fd_(fd) {}
99   bool Request(const std::vector<std::uint8_t>& message);
100   std::optional<confui::SignRawMessage> Receive();
101 
102  private:
103   SharedFD client_fd_;
104   ConfUiSignerImpl impl_;
105 };
106 }  // end of namespace cuttlefish
107