aboutsummaryrefslogtreecommitdiff
path: root/cc/primitive_set.h
diff options
context:
space:
mode:
authorBartosz Przydatek <przydatek@google.com>2017-05-11 12:47:33 +0000
committerThai Duong <thaidn@google.com>2017-05-11 13:20:48 -0700
commitdacb5d59be5ee94b869d8e5f793c42f514d30fde (patch)
tree595aad32455da915b4bf79466105870de326c8e8 /cc/primitive_set.h
parentdb2f3a866422f83d6c96c399b3a200ef2eba2867 (diff)
downloadtink-dacb5d59be5ee94b869d8e5f793c42f514d30fde.tar.gz
Merge "Cleanup of C++ PrimitiveSet."
ORIGINAL_AUTHOR=Bartosz Przydatek <przydatek@google.com> GitOrigin-RevId: 5b1d512269dd194cdb4813a294dbc6e18eb8a8fb
Diffstat (limited to 'cc/primitive_set.h')
-rw-r--r--cc/primitive_set.h84
1 files changed, 49 insertions, 35 deletions
diff --git a/cc/primitive_set.h b/cc/primitive_set.h
index b7b6e0359..7b07adb1f 100644
--- a/cc/primitive_set.h
+++ b/cc/primitive_set.h
@@ -17,6 +17,7 @@
#ifndef TINK_PRIMITIVE_SET_H_
#define TINK_PRIMITIVE_SET_H_
+#include <mutex> // NOLINT(build/c++11)
#include <unordered_map>
#include <vector>
@@ -44,15 +45,14 @@ namespace tink {
// 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.
+// determines the identifier 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:
+ // Entry-objects hold individual instances of primitives in the set.
template <class P2>
class Entry {
public:
@@ -78,58 +78,72 @@ class PrimitiveSet {
google::cloud::crypto::tink::KeyStatusType status_;
};
+ typedef std::vector<Entry<P>> Primitives;
+
+ // Constructs an empty PrimitiveSet.
PrimitiveSet<P>() : primary_(nullptr) {}
- typedef std::vector<Entry<P>> Primitives;
+ // 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);
- // Returns the entry with the primary primitive.
- const Entry<P>* get_primary() const {
- return primary_;
- }
+ // Returns the entries with primitives identifed by 'identifier'.
+ util::StatusOr<const Primitives*> get_primitives(
+ google::protobuf::StringPiece identifier);
// Returns all primitives that use RAW prefix.
- util::StatusOr<Primitives*> get_raw_primitives() {
+ util::StatusOr<const Primitives*> get_raw_primitives() {
return get_primitives(CryptoFormat::kRawPrefix);
}
- // Returns the entries with primitives identifed by 'identifier'.
- util::StatusOr<Primitives*> get_primitives(
- google::protobuf::StringPiece identifier) {
- typename CiphertextPrefixToPrimitivesMap::iterator found =
- primitives_.find(identifier.ToString());
- if (found == primitives_.end()) {
- return ToStatusF(util::error::NOT_FOUND,
- "No primitives found for identifier '%s'.",
- identifier.ToString().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());
+ // Returns the entry with the primary primitive.
+ const Entry<P>* get_primary() const {
+ return primary_;
}
private:
- Entry<P>* primary_;
typedef std::unordered_map<std::string, Primitives>
CiphertextPrefixToPrimitivesMap;
- CiphertextPrefixToPrimitivesMap primitives_;
+ Entry<P>* primary_;
+ std::mutex primitives_mutex_;
+ CiphertextPrefixToPrimitivesMap primitives_; // guarded by primitives_mutex_
};
+///////////////////////////////////////////////////////////////////////////////
+// Implementation details.
+
+template <class P>
+util::StatusOr<PrimitiveSet<P>::Entry<P>*> PrimitiveSet<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();
+ std::lock_guard<std::mutex> lock(primitives_mutex_);
+ primitives_[identifier].push_back(
+ Entry<P>(std::move(primitive), identifier, key.status()));
+ return &(primitives_[identifier].back());
+}
+
+template <class P>
+util::StatusOr<const std::vector<PrimitiveSet<P>::Entry<P>>*>
+PrimitiveSet<P>::get_primitives(google::protobuf::StringPiece identifier) {
+ std::lock_guard<std::mutex> lock(primitives_mutex_);
+ typename CiphertextPrefixToPrimitivesMap::iterator found =
+ primitives_.find(identifier.ToString());
+ if (found == primitives_.end()) {
+ return ToStatusF(util::error::NOT_FOUND,
+ "No primitives found for identifier '%s'.",
+ identifier.ToString().c_str());
+ }
+ return &(found->second);
+}
} // namespace tink
} // namespace crypto