xref: /aosp_15_r20/external/tink/cc/examples/daead/deterministic_aead_cli.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ///////////////////////////////////////////////////////////////////////////////
16 // [START deterministic-aead-example]
17 // A command-line utility for testing Tink Deterministic AEAD.
18 #include <iostream>
19 #include <memory>
20 #include <ostream>
21 #include <string>
22 
23 #include "absl/flags/flag.h"
24 #include "absl/flags/parse.h"
25 #include "absl/log/check.h"
26 #include "absl/strings/string_view.h"
27 #include "tink/daead/deterministic_aead_config.h"
28 #include "tink/deterministic_aead.h"
29 #include "util/util.h"
30 #include "tink/keyset_handle.h"
31 #include "tink/util/status.h"
32 
33 ABSL_FLAG(std::string, keyset_filename, "", "Keyset file in JSON format");
34 ABSL_FLAG(std::string, mode, "", "Mode of operation {encrypt|decrypt}");
35 ABSL_FLAG(std::string, input_filename, "", "Filename to operate on");
36 ABSL_FLAG(std::string, output_filename, "", "Output file name");
37 ABSL_FLAG(std::string, associated_data, "",
38           "Associated data for Deterministic AEAD (default: empty");
39 
40 namespace {
41 
42 using ::crypto::tink::DeterministicAead;
43 using ::crypto::tink::DeterministicAeadConfig;
44 using ::crypto::tink::KeysetHandle;
45 using ::crypto::tink::util::Status;
46 using ::crypto::tink::util::StatusOr;
47 
48 constexpr absl::string_view kEncrypt = "encrypt";
49 constexpr absl::string_view kDecrypt = "decrypt";
50 
ValidateParams()51 void ValidateParams() {
52   // [START_EXCLUDE]
53   CHECK(absl::GetFlag(FLAGS_mode) == kEncrypt ||
54         absl::GetFlag(FLAGS_mode) == kDecrypt)
55       << "Invalid mode; must be `encrypt` or `decrypt`";
56   CHECK(!absl::GetFlag(FLAGS_keyset_filename).empty())
57       << "Keyset file must be specified";
58   CHECK(!absl::GetFlag(FLAGS_input_filename).empty())
59       << "Input file must be specified";
60   CHECK(!absl::GetFlag(FLAGS_output_filename).empty())
61       << "Output file must be specified";
62   // [END_EXCLUDE]
63 }
64 
65 }  // namespace
66 
67 namespace tink_cc_examples {
68 
69 // Deterministic AEAD example CLI implementation.
DeterministicAeadCli(absl::string_view mode,const std::string & keyset_filename,const std::string & input_filename,const std::string & output_filename,absl::string_view associated_data)70 Status DeterministicAeadCli(absl::string_view mode,
71                             const std::string& keyset_filename,
72                             const std::string& input_filename,
73                             const std::string& output_filename,
74                             absl::string_view associated_data) {
75   Status result = DeterministicAeadConfig::Register();
76   if (!result.ok()) return result;
77 
78   // Read keyset from file.
79   StatusOr<std::unique_ptr<KeysetHandle>> keyset_handle =
80       ReadJsonCleartextKeyset(keyset_filename);
81   if (!keyset_handle.ok()) return keyset_handle.status();
82 
83   // Get the primitive.
84   StatusOr<std::unique_ptr<DeterministicAead>> daead =
85       (*keyset_handle)->GetPrimitive<DeterministicAead>();
86   if (!daead.ok()) return daead.status();
87 
88   // Read the input.
89   StatusOr<std::string> input_file_content = ReadFile(input_filename);
90   if (!input_file_content.ok()) return input_file_content.status();
91 
92   // Compute the output.
93   std::string output;
94   if (mode == kEncrypt) {
95     StatusOr<std::string> result = (*daead)->EncryptDeterministically(
96         *input_file_content, associated_data);
97     if (!result.ok()) return result.status();
98     output = *result;
99   } else if (mode == kDecrypt) {
100     StatusOr<std::string> result = (*daead)->DecryptDeterministically(
101         *input_file_content, associated_data);
102     if (!result.ok()) return result.status();
103     output = *result;
104   }
105 
106   // Write output to file.
107   return WriteToFile(output, output_filename);
108 }
109 
110 }  // namespace tink_cc_examples
111 
main(int argc,char ** argv)112 int main(int argc, char** argv) {
113   absl::ParseCommandLine(argc, argv);
114 
115   ValidateParams();
116 
117   std::string mode = absl::GetFlag(FLAGS_mode);
118   std::string keyset_filename = absl::GetFlag(FLAGS_keyset_filename);
119   std::string input_filename = absl::GetFlag(FLAGS_input_filename);
120   std::string output_filename = absl::GetFlag(FLAGS_output_filename);
121   std::string associated_data = absl::GetFlag(FLAGS_associated_data);
122 
123   std::clog << "Using keyset from file " << keyset_filename
124             << " to Deterministic AEAD-" << mode << " file " << input_filename
125             << " with associated data '" << associated_data << "'."
126             << std::endl;
127   std::clog << "The resulting output will be written to " << output_filename
128             << "." << std::endl;
129 
130   CHECK_OK(tink_cc_examples::DeterministicAeadCli(
131       mode, keyset_filename, input_filename, output_filename, associated_data));
132   return 0;
133 }
134 // [END deterministic-aead-example]
135