diff options
author | Bartosz Przydatek <przydatek@google.com> | 2017-03-28 15:03:13 +0000 |
---|---|---|
committer | Thai Duong <thaidn@google.com> | 2017-03-29 11:50:40 -0700 |
commit | 94925e322e9312f04330a23b060c6b483a1e9142 (patch) | |
tree | c41a4a3247a449361e55570b462dafb5324adfa5 /cc/primitive_set.h | |
parent | a631bebb8fb118e50ba0c58e6e6f6b86c2e5261f (diff) | |
download | tink-94925e322e9312f04330a23b060c6b483a1e9142.tar.gz |
Adding aux structures for primitive generation.
Change-Id: I51033bf71a0683b22717aa578042fa5d1f951e8e
ORIGINAL_AUTHOR=Bartosz Przydatek <przydatek@google.com>
GitOrigin-RevId: bd617b00f44a3c07b3de511f6dc6bb115d46fa01
Diffstat (limited to 'cc/primitive_set.h')
-rw-r--r-- | cc/primitive_set.h | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/cc/primitive_set.h b/cc/primitive_set.h new file mode 100644 index 000000000..d45309aff --- /dev/null +++ b/cc/primitive_set.h @@ -0,0 +1,136 @@ +// Copyright 2017 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. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef TINK_PRIMITIVE_SET_H_ +#define TINK_PRIMITIVE_SET_H_ + +#include <unordered_map> +#include <vector> + +#include "cc/crypto_format.h" +#include "cc/util/errors.h" +#include "cc/util/statusor.h" +#include "proto/tink.pb.h" + +namespace cloud { +namespace crypto { +namespace tink { + +// A container class for a set of primitives (i.e. implementations of +// cryptographic primitives offered by Tink). It provides also +// additional properties for the primitives it holds. In particular, +// one of the primitives in the set can be distinguished as "the +// primary" one. +// +// PrimitiveSet is an auxiliary class used for supporting key rotation: +// primitives in a set correspond to keys in a keyset. Users will +// usually work with primitive instances, which essentially wrap +// primitive sets. For example an instance of an Aead-primitive for a +// given keyset holds a set of Aead-primitivies corresponding to the +// keys in the keyset, and uses the set members to do the actual +// crypto operations: to encrypt data the primary Aead-primitive from +// the set is used, and upon decryption the ciphertext's prefix +// determines the id of the primitive from the set. +// +// PrimitiveSet is a public class to allow its use in implementations +// of custom primitives. +// +// TODO(przydatek): make it thread-safe. +template <class P> +class PrimitiveSet { + public: + template <class P2> + class Entry { + public: + Entry(std::unique_ptr<P2> primitive, std::string identifier, + google::cloud::crypto::tink::KeyStatusType status) : + primitive_(std::move(primitive)), + identifier_(identifier), + status_(status) { + } + P2& get_primitive() const { + return *primitive_; + } + const std::string& get_identifier() const { + return identifier_; + } + const google::cloud::crypto::tink::KeyStatusType get_status() const { + return status_; + } + private: + std::unique_ptr<P> primitive_; + std::string identifier_; + google::cloud::crypto::tink::KeyStatusType status_; + }; + + PrimitiveSet<P>() : primary_(nullptr) {} + + typedef std::vector<Entry<P>> Primitives; + + // Returns the entry with the primary primitive. + const Entry<P>* get_primary() const { + return primary_; + } + + // Returns all primitives that use RAW prefix. + util::StatusOr<Primitives*> get_raw_primitives() { + return get_primitives(CryptoFormat::kRawPrefix); + } + + // Returns the entries with primitive identifed by 'identifier'. + util::StatusOr<Primitives*> get_primitives( + const std::string& identifier) { + typename CiphertextPrefixToPrimitivesMap::iterator found = + primitives_.find(identifier); + if (found == primitives_.end()) { + return ToStatusF(util::error::NOT_FOUND, + "No primitives found for identifier '%s'.", + identifier.c_str()); + } + return &(found->second); + } + + // Sets the given 'primary' as as the primary primitive of this set. + void set_primary(Entry<P>* primary) { + primary_ = primary; + } + + // Adds 'primitive' to this set for the specified 'key'. + util::StatusOr<Entry<P>*> AddPrimitive( + std::unique_ptr<P> primitive, + google::cloud::crypto::tink::Keyset::Key key) { + auto identifier_result = CryptoFormat::get_output_prefix(key); + if (!identifier_result.ok()) return identifier_result.status(); + std::string identifier = identifier_result.ValueOrDie(); + primitives_[identifier].push_back(Entry<P>(std::move(primitive), + identifier, + key.status())); + return &(primitives_[identifier].back()); + } + + private: + Entry<P>* primary_; + typedef std::unordered_map<std::string, Primitives> + CiphertextPrefixToPrimitivesMap; + CiphertextPrefixToPrimitivesMap primitives_; +}; + + +} // namespace tink +} // namespace crypto +} // namespace cloud + +#endif // TINK_PRIMITIVE_SET_H_ |