• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 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 #include "confui_sign_server.h"
17 
18 #include <android-base/logging.h>
19 
20 #include "host/commands/secure_env/primary_key_builder.h"
21 #include "host/commands/secure_env/tpm_hmac.h"
22 #include "host/libs/config/cuttlefish_config.h"
23 
24 namespace cuttlefish {
ConfUiSignServer(TpmResourceManager & tpm_resource_manager,SharedFD server_fd)25 ConfUiSignServer::ConfUiSignServer(TpmResourceManager& tpm_resource_manager,
26                                    SharedFD server_fd)
27     : tpm_resource_manager_(tpm_resource_manager), server_fd_(server_fd) {
28   auto config = cuttlefish::CuttlefishConfig::Get();
29   CHECK(config) << "Config must not be null";
30   auto instance = config->ForDefaultInstance();
31   server_socket_path_ = instance.PerInstanceInternalPath("confui_sign.sock");
32 }
33 
MainLoop()34 [[noreturn]] void ConfUiSignServer::MainLoop() {
35   while (true) {
36     if (!server_fd_->IsOpen()) {
37       server_fd_ = SharedFD::SocketLocalServer(server_socket_path_, false,
38                                                SOCK_STREAM, 0600);
39     }
40     auto accepted_socket_fd = SharedFD::Accept(*server_fd_);
41     if (!accepted_socket_fd->IsOpen()) {
42       LOG(ERROR) << "Confirmation UI host signing client socket is broken.";
43       continue;
44     }
45     ConfUiSignSender sign_sender(accepted_socket_fd);
46 
47     // receive request
48     auto request_opt = sign_sender.Receive();
49     if (!request_opt) {
50       std::string error_category = (sign_sender.IsIoError() ? "IO" : "Logic");
51       LOG(ERROR) << "ReceiveRequest failed with " << error_category << " error";
52       continue;
53     }
54     auto request = request_opt.value();
55 
56     // get signing key
57     auto signing_key_builder = PrimaryKeyBuilder();
58     signing_key_builder.SigningKey();
59     signing_key_builder.UniqueData("confirmation_token");
60     auto signing_key = signing_key_builder.CreateKey(tpm_resource_manager_);
61     if (!signing_key) {
62       LOG(ERROR) << "Could not generate signing key";
63       sign_sender.Send(confui::SignMessageError::kUnknownError, {});
64       continue;
65     }
66 
67     // hmac
68     auto hmac = TpmHmac(tpm_resource_manager_, signing_key->get(),
69                         TpmAuth(ESYS_TR_PASSWORD), request.payload_.data(),
70                         request.payload_.size());
71     if (!hmac) {
72       LOG(ERROR) << "Could not calculate confirmation token hmac";
73       sign_sender.Send(confui::SignMessageError::kUnknownError, {});
74       continue;
75     }
76     if (hmac->size == 0) {
77       LOG(ERROR) << "hmac was too short";
78       sign_sender.Send(confui::SignMessageError::kUnknownError, {});
79       continue;
80     }
81 
82     // send hmac
83     std::vector<std::uint8_t> hmac_buffer(hmac->buffer,
84                                           hmac->buffer + hmac->size);
85     if (!sign_sender.Send(confui::SignMessageError::kOk, hmac_buffer)) {
86       LOG(ERROR) << "Sending signature failed likely due to I/O error";
87     }
88   }
89 }
90 }  // namespace cuttlefish
91