blob: 3eb5625797957d800201c328d826fc01e93ebe42 [file] [log] [blame]
// Copyright 2019 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include "tink/streaming_aead.h"
#include "tink/keyset_handle.h"
#include "tink/util/istream_input_stream.h"
#include "tink/util/ostream_output_stream.h"
#include "tink/util/status.h"
#include "testing/cc/cli_util.h"
using crypto::tink::InputStream;
using crypto::tink::KeysetHandle;
using crypto::tink::OutputStream;
using crypto::tink::util::IstreamInputStream;
using crypto::tink::util::OstreamOutputStream;
// A command-line utility for testing StreamingAead-primitives.
// It requires 5 arguments:
// keyset-file: name of the file with the keyset to be used for encryption
// operation: the actual StreamingAead-operation, i.e. "encrypt" or "decrypt"
// input-file: name of the file with input (plaintext for encryption, or
// or ciphertext for decryption)
// associated-data-file: name of the file containing associated data
// output-file: name of the file for the resulting output
int main(int argc, char** argv) {
if (argc != 6) {
std::clog << "Usage: " << argv[0]
<< " keyset-file operation input-file associated-data-file "
<< "output-file\n";
exit(1);
}
std::string keyset_filename(argv[1]);
std::string operation(argv[2]);
std::string input_filename(argv[3]);
std::string associated_data_file(argv[4]);
std::string output_filename(argv[5]);
if (!(operation == "encrypt" || operation == "decrypt")) {
std::clog << "Unknown operation '" << operation << "'.\n"
<< "Expected 'encrypt' or 'decrypt'.\n";
exit(1);
}
std::clog << "Using keyset from file " << keyset_filename
<< " to StreamingAead-" << operation
<< " file "<< input_filename
<< " with associated data from from file " << associated_data_file
<< ".\n" << "The resulting output will be written to file "
<< output_filename << std::endl;
// Init Tink;
CliUtil::InitTink();
// Read the keyset.
std::unique_ptr<KeysetHandle> keyset_handle =
CliUtil::ReadKeyset(keyset_filename);
// Get the primitive.
auto primitive_result =
keyset_handle->GetPrimitive<crypto::tink::StreamingAead>();
if (!primitive_result.ok()) {
std::clog << "Getting StreamingAead-primitive from the factory failed: "
<< primitive_result.status().error_message() << std::endl;
exit(1);
}
std::unique_ptr<crypto::tink::StreamingAead> saead =
std::move(primitive_result.ValueOrDie());
// Open input/output streams, and read the associated data.
auto input = absl::make_unique<std::ifstream>(
input_filename, std::ifstream::in | std::ifstream::binary);
std::unique_ptr<InputStream> input_stream(
absl::make_unique<IstreamInputStream>(std::move(input)));
auto output = absl::make_unique<std::ofstream>(
output_filename, std::ofstream::out | std::ofstream::binary);
std::unique_ptr<OutputStream> output_stream(
absl::make_unique<OstreamOutputStream>(std::move(output)));
std::string associated_data = CliUtil::Read(associated_data_file);
// Compute the output.
std::clog << operation << "ing...\n";
if (operation == "encrypt") {
// Turn output_stream into an encrypting stream.
auto enc_stream_result =
saead->NewEncryptingStream(std::move(output_stream), associated_data);
if (!enc_stream_result.ok()) {
std::clog << "Error while creating an encrypting stream:"
<< enc_stream_result.status().error_message() << std::endl;
exit(1);
}
output_stream = std::move(enc_stream_result.ValueOrDie());
} else { // operation == "decrypt"
// Turn input_stream into a decrypting stream.
auto dec_stream_result =
saead->NewDecryptingStream(std::move(input_stream), associated_data);
if (!dec_stream_result.ok()) {
std::clog << "Error while creating a decrypting stream:"
<< dec_stream_result.status().error_message() << std::endl;
exit(1);
}
input_stream = std::move(dec_stream_result.ValueOrDie());
}
CliUtil::CopyStream(input_stream.get(), output_stream.get());
std::clog << "All done.\n";
return 0;
}