blob: 5c9aa439c9392935abb3cd28685a11d11c045555 [file] [log] [blame]
// 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 <string>
#include <vector>
#include "absl/strings/ascii.h"
#include "absl/strings/str_split.h"
#include "aws/core/Aws.h"
#include "aws/core/auth/AWSCredentialsProvider.h"
#include "aws/core/client/ClientConfiguration.h"
#include "aws/core/utils/crypto/Factories.h"
#include "aws/core/utils/memory/AWSMemory.h"
#include "aws/kms/KMSClient.h"
#include "tink/aead.h"
#include "tink/integration/awskms/aws_crypto.h"
#include "tink/integration/awskms/aws_kms_aead.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"
#include "tools/testing/cc/cli_util.h"
using crypto::tink::Aead;
using crypto::tink::integration::awskms::AwsKmsAead;
using crypto::tink::integration::awskms::AwsSha256Factory;
using crypto::tink::integration::awskms::AwsSha256HmacFactory;
using crypto::tink::integration::awskms::kAwsCryptoAllocationTag;
// A command-line utility for testing AwsKmsAead.
// It requires 6 arguments:
// key-arn-file: Amazon Resource Name of AWS KMS key for encryption
// access-key-csv-file: credentials file containing AWS access key
// operation: the actual AEAD-operation, i.e. "encrypt" or "decrypt"
// input-file: name of the file with input (plaintext for encryption, or
// or ciphertext for decryption)
// associated-data: a std::string to be used as assciated data
// output-file: name of the file for the resulting output
int main(int argc, char** argv) {
if (argc != 7) {
std::clog << "Usage: " << argv[0]
<< " key-arn-file access-key-csv-file"
<< " operation input-file associated-data output-file\n";
exit(1);
}
std::string key_arn_filename(argv[1]);
std::string access_key_filename(argv[2]);
std::string operation(argv[3]);
std::string input_filename(argv[4]);
std::string associated_data(argv[5]);
std::string output_filename(argv[6]);
if (!(operation == "encrypt" || operation == "decrypt")) {
std::clog << "Unknown operation '" << operation << "'.\n"
<< "Expected 'encrypt' or 'decrypt'.\n";
exit(1);
}
std::clog << "Using key_arn from file " << key_arn_filename
<< " and AWS access key from file " << access_key_filename
<< " to AEAD-" << operation
<< " file "<< input_filename
<< " with associated data '" << associated_data << "'.\n"
<< "The resulting output will be written to file "
<< output_filename << std::endl;
// Init AWS API.
Aws::SDKOptions options;
options.cryptoOptions.sha256Factory_create_fn = []() {
return Aws::MakeShared<AwsSha256Factory>(kAwsCryptoAllocationTag);
};
options.cryptoOptions.sha256HMACFactory_create_fn = []() {
return Aws::MakeShared<AwsSha256HmacFactory>(kAwsCryptoAllocationTag);
};
Aws::InitAPI(options);
// Prepare AWS credentials and params.
// access-key-cvs-file contains two lines, where the first line
// describes the actual comma-separated values present in the second line.
std::vector<std::string> access_key =
absl::StrSplit(CliUtil::Read(access_key_filename), '\n');
std::vector<std::string> access_key_values =
absl::StrSplit(access_key[1], ',');
std::string access_key_id = access_key_values[0];
absl::StripAsciiWhitespace(&access_key_id);
std::string secret_access_key = access_key_values[1];
absl::StripAsciiWhitespace(&secret_access_key);
Aws::Auth::AWSCredentials credentials(access_key_id.c_str(),
secret_access_key.c_str());
std::string key_arn = CliUtil::Read(key_arn_filename);
absl::StripAsciiWhitespace(&key_arn);
std::clog << "Will use key ARN " << key_arn << std::endl
<< "with access key ID [" << access_key_id << "]" << std::endl;
// Create AWS KMSClient.
Aws::Client::ClientConfiguration configuration;
configuration.region = "us-east-1";
configuration.scheme = Aws::Http::Scheme::HTTPS;
configuration.connectTimeoutMs = 30000;
configuration.requestTimeoutMs = 60000;
auto aws_client = Aws::MakeShared<Aws::KMS::KMSClient>(
kAwsCryptoAllocationTag, credentials, configuration);
// Create Aead-primitive.
auto aead_result = AwsKmsAead::New(key_arn, aws_client);
if (!aead_result.ok()) {
std::clog << "Aead creation failed: "
<< aead_result.status().error_message()
<< "\n";
exit(1);
}
std::unique_ptr<Aead> aead(std::move(aead_result.ValueOrDie()));
// Read the input.
std::string input = CliUtil::Read(input_filename);
// Compute the output.
std::clog << operation << "ing...\n";
std::string output;
if (operation == "encrypt") {
auto encrypt_result = aead->Encrypt(input, associated_data);
if (!encrypt_result.ok()) {
std::clog << "Error while encrypting the input:"
<< encrypt_result.status().error_message() << std::endl;
exit(1);
}
output = encrypt_result.ValueOrDie();
} else { // operation == "decrypt"
auto decrypt_result = aead->Decrypt(input, associated_data);
if (!decrypt_result.ok()) {
std::clog << "Error while decrypting the input:"
<< decrypt_result.status().error_message() << std::endl;
exit(1);
}
output = decrypt_result.ValueOrDie();
}
// Write the output to the output file.
CliUtil::Write(output, output_filename);
std::clog << "All done.\n";
}