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