# Tink for C++ HOW-TO

This document contains instructions and C++ code snippets for common tasks in
[Tink](https://github.com/google/tink).

## Setup instructions

Tink can be built using [Bazel](https://www.bazel.build) or
[CMake](http://cmake.org). Using any other build system is currently not
supported. This implies that you need to build your binary from scratch.

### Bazel

Using Tink in projects built with Bazel is straighforward and is the recommended
approach. For an example, see [this project which specifies Tink as a dependency
in a Bazel WORKSPACE file](https://github.com/thaidn/tink-examples).

### CMake

Using Tink with CMake is suported, see [CMAKE-HOWTO](CMAKE-HOWTO.md) for for a
detailed description.

## Initializing Tink

Tink provides customizable initialization, which allows for choosing specific
implementations (identified by _key types_) of desired primitives. This
initialization happens via _registration_ of the implementations.

For example, if you want to use all standard implementations of all primitives
in the current release of Tink, the initialization would be:

```cpp
   #include "tink/config/tink_config.h"

   // ...
   auto status = TinkConfig::Register();
   if (!status.ok()) /* ... handle failure */;
   // ...
```

To use standard implementations of only one primitive, say AEAD:

```cpp
   #include "tink/aead/aead_config.h"

   // ...
   auto status = AeadConfig::Register();
   if (!status.ok()) /* ... handle failure */;
   // ...
```

The registration of custom key managers can proceed directly via
`Registry` class:

```cpp
   #include "tink/registry.h"
   #include "custom_project/custom_aead_key_manager.h"

   // ...
   auto status = Registry::RegisterKeyManager(new CustomAeadKeyManager());
   if (!status.ok()) /* ... handle failure */;
```

## Generating new keys and keysets

Each `KeyManager` implementation provides a `NewKey(template)` method that
generates new keys of the corresponding key type.  However, to avoid accidental
leakage of sensitive key material, you should avoid mixing key(set) generation
with key(set) usage in code. To support the separation between these activities,
Tink provides a command-line tool called [Tinkey](TINKEY.md), which can be used
for common key management tasks.

Still, if there is a need to generate a KeysetHandle with fresh key material
directly in C++ code, you can use
[`KeysetHandle`](https://github.com/google/tink/blob/master/cc/keyset_handle.h):

```cpp
    auto new_keyset_handle_result = KeysetHandle::GenerateNew(key_template);
    if (!new_keyset_handle_result.ok()) return new_keyset_handle_result.status();
    auto keyset_handle = std::move(new_keyset_handle_result.ValueOrDie());
    // use the keyset...
```

Recommended key templates can be obtained from util classes corresponding to
Tink primitives, e.g.
[MacKeyTemplates](https://github.com/google/tink/blob/master/cc/mac/mac_key_templates.h),
[AeadKeyTemplates](https://github.com/google/tink/blob/master/cc/aead/aead_key_templates.h),
and
[HybridKeyTemplates](https://github.com/google/tink/blob/master/cc/hybrid/hybrid_key_templates.h).

## Loading existing keysets

To load encrypted keysets, use
[`KeysetHandle`](https://github.com/google/tink/blob/master/cc/keyset_handle.h)
and an appropriate
[`KeysetReader`](https://github.com/google/tink/blob/master/cc/keyset_reader.h)
depending on the wire format of the stored keyset, for example a
[`BinaryKeysetReader`](https://github.com/google/tink/blob/master/cc/binary_keyset_reader.h)
or a
[`JsonKeysetReader`](https://github.com/google/tink/blob/master/cc/json_keyset_reader.h):

```cpp
    #include "tink/aead.h"
    #include "tink/json_keyset_reader.h"
    #include "tink/cleartext_keyset_handle.h"
    #include "tink/integration/aws_kms_client.h"

    // ...
    std::string json_encrypted_keyset = ...;
    auto reader_result = JsonKeysetReader::New(json_encrypted_keyset);
    if (!reader_result.ok()) return reader_result.status();
    auto reader = std::move(reader_result.ValueOrDie());
    std::string master_key_uri =
        "aws-kms://arn:aws:kms:us-east-1:007084425826:key/84a65985-f868-4bfc-83c2-366618acf147";
    auto aead = std::move(AwsKmsClient::NewAead(master_key_uri).ValueOrDie());
    auto handle_result = KeysetHandle::Read(std::move(reader), *aead);
    if (!handle_result.ok()) return handle_result.status();
    auto keyset_handle = std::move(handle_result.ValueOrDie());
```

To load cleartext keysets, use
[`CleartextKeysetHandle`](https://github.com/google/tink/blob/master/cc/cleartext_keyset_handle.h)
and an appropriate
[`KeysetReader`](https://github.com/google/tink/blob/master/cc/keyset_reader.h),

```cpp
    #include "tink/binary_keyset_reader.h"
    #include "tink/cleartext_keyset_handle.h"

    // ...
    std::string binary_keyset = ...;
    auto reader_result = BinaryKeysetReader::New(binary_keyset);
    if (!reader_result.ok()) return reader_result.status();
    auto reader = std::move(reader_result.ValueOrDie());
    auto handle_result = CleartextKeysetHandle::Read(std::move(reader));
    if (!handle_result.ok()) return handle_result.status();
    auto keyset_handle = std::move(handle_result.ValueOrDie());
```

## Obtaining and using primitives

[_Primitives_](PRIMITIVES.md) represent cryptographic operations offered by
Tink, hence they form the core of the Tink API. A primitive is an interface that
specifies what operations are offered by the primitive. A primitive can have
multiple implementations, and you choose a desired implementation by using a key
of a corresponding type (see [this
document](KEY-MANAGEMENT.md#key-keyset-and-keysethandle) for further details).

A list of primitives and the implementations currently supported by Tink in C++
can be found [here](PRIMITIVES.md#c).

You obtain a primitive by calling the method `GetPrimitive<>` of a
`KeysetHandle`.

### Symmetric key encryption

You can use an [AEAD (Authenticated Encryption with Associated
Data)](PRIMITIVES.md#authenticated-encryption-with-associated-data) primitive to
encrypt or decrypt data:

```cpp
    #include "tink/aead.h"
    #include "tink/keyset_handle.h"


    // 1. Get a handle to the key material.
    KeysetHandle keyset_handle = ...;

    // 2. Get the primitive.
    auto aead_result= keyset_handle.GetPrimitive<Aead>();
    if (!aead_result.ok()) return aead_result.status();
    auto aead = std::move(aead_result.ValueOrDie());

    // 3. Use the primitive.
    auto ciphertext_result = aead.Encrypt(plaintext, aad);
    if (!ciphertext_result.ok()) return ciphertext_result.status();
    auto ciphertext = std::move(ciphertext_result.ValueOrDie());
```

### Hybrid encryption

You can encrypt and decrypt using [a combination of public key encryption and
symmetric key encryption](PRIMITIVES.md#hybrid-encryption):

```cpp
    #include "tink/hybrid_decrypt.h"
    #include "tink/keyset_handle.h"


    // 1. Get a handle to the key material.
    KeysetHandle keyset_handle = ...;

    // 2. Get the primitive.
    auto hybrid_decrypt_result = keyset_handle.GetPrimitive<HybridDecrypt>();
    if (!hybrid_decrypt_result.ok()) return hybrid_decrypt_result.status();
    auto hybrid_decrypt = std::move(hybrid_decrypt_result.ValueOrDie());

    // 3. Use the primitive.
    auto plaintext_result = hybrid_decrypt.Decrypt(ciphertext, context_info);
    if (!plaintext_result.ok()) return plaintext_result.status();
    auto plaintext = std::move(plaintext_result.ValueOrDie());
```
