1 /*
2  * Copyright 2018 Google LLC
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 "fcp/secagg/client/secagg_client_r0_advertise_keys_input_not_set_state.h"
18 
19 #include <cstdint>
20 #include <memory>
21 #include <string>
22 #include <utility>
23 #include <vector>
24 
25 #include "absl/container/node_hash_map.h"
26 #include "fcp/base/monitoring.h"
27 #include "fcp/secagg/client/secagg_client_aborted_state.h"
28 #include "fcp/secagg/client/secagg_client_completed_state.h"
29 #include "fcp/secagg/client/secagg_client_r0_advertise_keys_input_set_state.h"
30 #include "fcp/secagg/client/secagg_client_r1_share_keys_input_not_set_state.h"
31 #include "fcp/secagg/client/secagg_client_state.h"
32 #include "fcp/secagg/client/send_to_server_interface.h"
33 #include "fcp/secagg/client/state_transition_listener_interface.h"
34 #include "fcp/secagg/shared/aes_prng_factory.h"
35 #include "fcp/secagg/shared/ecdh_key_agreement.h"
36 #include "fcp/secagg/shared/input_vector_specification.h"
37 #include "fcp/secagg/shared/secagg_messages.pb.h"
38 #include "fcp/secagg/shared/secagg_vector.h"
39 
40 namespace fcp {
41 namespace secagg {
42 
43 SecAggClientR0AdvertiseKeysInputNotSetState::
SecAggClientR0AdvertiseKeysInputNotSetState(uint32_t max_neighbors_expected,uint32_t minimum_surviving_neighbors_for_reconstruction,std::unique_ptr<std::vector<InputVectorSpecification>> input_vector_specs,std::unique_ptr<SecurePrng> prng,std::unique_ptr<SendToServerInterface> sender,std::unique_ptr<StateTransitionListenerInterface> transition_listener,std::unique_ptr<AesPrngFactory> prng_factory,AsyncAbort * async_abort)44     SecAggClientR0AdvertiseKeysInputNotSetState(
45         uint32_t max_neighbors_expected,
46         uint32_t minimum_surviving_neighbors_for_reconstruction,
47         std::unique_ptr<std::vector<InputVectorSpecification> >
48             input_vector_specs,
49         std::unique_ptr<SecurePrng> prng,
50         std::unique_ptr<SendToServerInterface> sender,
51         std::unique_ptr<StateTransitionListenerInterface> transition_listener,
52         std::unique_ptr<AesPrngFactory> prng_factory, AsyncAbort* async_abort)
53     : SecAggClientAliveBaseState(std::move(sender),
54                                  std::move(transition_listener),
55                                  ClientState::R0_ADVERTISE_KEYS, async_abort),
56       max_neighbors_expected_(max_neighbors_expected),
57       minimum_surviving_neighbors_for_reconstruction_(
58           minimum_surviving_neighbors_for_reconstruction),
59       input_vector_specs_(std::move(input_vector_specs)),
60       prng_(std::move(prng)),
61       prng_factory_(std::move(prng_factory)) {}
62 
63 SecAggClientR0AdvertiseKeysInputNotSetState::
64     ~SecAggClientR0AdvertiseKeysInputNotSetState() = default;
65 
66 StatusOr<std::unique_ptr<SecAggClientState> >
Start()67 SecAggClientR0AdvertiseKeysInputNotSetState::Start() {
68   auto enc_key_agreement = EcdhKeyAgreement::CreateFromRandomKeys().value();
69   auto prng_key_agreement = EcdhKeyAgreement::CreateFromRandomKeys().value();
70 
71   ClientToServerWrapperMessage message;
72   PairOfPublicKeys* public_keys =
73       message.mutable_advertise_keys()->mutable_pair_of_public_keys();
74   public_keys->set_enc_pk(enc_key_agreement->PublicKey().AsString());
75   public_keys->set_noise_pk(prng_key_agreement->PublicKey().AsString());
76 
77   sender_->Send(&message);
78   return {std::make_unique<SecAggClientR1ShareKeysInputNotSetState>(
79       max_neighbors_expected_, minimum_surviving_neighbors_for_reconstruction_,
80       std::move(enc_key_agreement), std::move(input_vector_specs_),
81       std::move(prng_), std::move(prng_key_agreement), std::move(sender_),
82       std::move(transition_listener_), std::move(prng_factory_), async_abort_)};
83 }
84 
85 StatusOr<std::unique_ptr<SecAggClientState> >
HandleMessage(const ServerToClientWrapperMessage & message)86 SecAggClientR0AdvertiseKeysInputNotSetState::HandleMessage(
87     const ServerToClientWrapperMessage& message) {
88   // Handle abort messages only.
89   if (message.has_abort()) {
90     if (message.abort().early_success()) {
91       return {std::make_unique<SecAggClientCompletedState>(
92           std::move(sender_), std::move(transition_listener_))};
93     } else {
94       return {std::make_unique<SecAggClientAbortedState>(
95           "Aborting because of abort message from the server.",
96           std::move(sender_), std::move(transition_listener_))};
97     }
98   } else {
99     // Returns an error indicating that the message is of invalid type.
100     return SecAggClientState::HandleMessage(message);
101   }
102 }
103 
104 StatusOr<std::unique_ptr<SecAggClientState> >
SetInput(std::unique_ptr<SecAggVectorMap> input_map)105 SecAggClientR0AdvertiseKeysInputNotSetState::SetInput(
106     std::unique_ptr<SecAggVectorMap> input_map) {
107   if (!ValidateInput(*input_map, *input_vector_specs_)) {
108     return FCP_STATUS(INVALID_ARGUMENT)
109            << "The input to SetInput does not match the "
110               "InputVectorSpecification.";
111   }
112 
113   return {std::make_unique<SecAggClientR0AdvertiseKeysInputSetState>(
114       max_neighbors_expected_, minimum_surviving_neighbors_for_reconstruction_,
115       std::move(input_map), std::move(input_vector_specs_), std::move(prng_),
116       std::move(sender_), std::move(transition_listener_),
117       std::move(prng_factory_), async_abort_)};
118 }
119 
StateName() const120 std::string SecAggClientR0AdvertiseKeysInputNotSetState::StateName() const {
121   return "R0_ADVERTISE_KEYS_INPUT_NOT_SET";
122 }
123 
124 }  // namespace secagg
125 }  // namespace fcp
126