1 // Copyright 2019 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 /////////////////////////////////////////////////////////////////////////////// 16 17 #ifndef TINK_STREAMINGAEAD_DECRYPTING_RANDOM_ACCESS_STREAM_H_ 18 #define TINK_STREAMINGAEAD_DECRYPTING_RANDOM_ACCESS_STREAM_H_ 19 20 #include <memory> 21 #include <string> 22 #include <utility> 23 #include <vector> 24 25 #include "absl/synchronization/mutex.h" 26 #include "tink/primitive_set.h" 27 #include "tink/random_access_stream.h" 28 #include "tink/streaming_aead.h" 29 #include "tink/util/buffer.h" 30 #include "tink/util/statusor.h" 31 32 namespace crypto { 33 namespace tink { 34 namespace streamingaead { 35 36 // A wrapper around a RandomAccessStream that holds a reference to a 37 // set of StreamingAead-primitives and upon first PRead()-call attempts 38 // to read the stream via the provided primitives to find a matching one, 39 // i.e. the primitive that is able to decrypt the stream. 40 // Once a match is found, all subsequent calls are forwarded to it. 41 class DecryptingRandomAccessStream : public crypto::tink::RandomAccessStream { 42 public: 43 // Constructs an RandomAccessStream that wraps 'random_access_stream', 44 // and will use (one of) provided 'primitives' to decrypt the contents 45 // of 'random_access_stream', using 'associated_data' as authenticated 46 // associated data of the decryption process. 47 static util::StatusOr<std::unique_ptr<RandomAccessStream>> New( 48 std::shared_ptr< 49 crypto::tink::PrimitiveSet<crypto::tink::StreamingAead>> primitives, 50 std::unique_ptr<crypto::tink::RandomAccessStream> ciphertext_source, 51 absl::string_view associated_data); 52 53 ~DecryptingRandomAccessStream() override = default; 54 crypto::tink::util::Status PRead(int64_t position, int count, 55 crypto::tink::util::Buffer* dest_buffer) override; 56 crypto::tink::util::StatusOr<int64_t> size() override; 57 58 private: DecryptingRandomAccessStream(std::shared_ptr<crypto::tink::PrimitiveSet<crypto::tink::StreamingAead>> primitives,std::unique_ptr<crypto::tink::RandomAccessStream> ciphertext_source,absl::string_view associated_data)59 DecryptingRandomAccessStream( 60 std::shared_ptr< 61 crypto::tink::PrimitiveSet<crypto::tink::StreamingAead>> primitives, 62 std::unique_ptr<crypto::tink::RandomAccessStream> ciphertext_source, 63 absl::string_view associated_data) 64 : primitives_(primitives), 65 ciphertext_source_(std::move(ciphertext_source)), 66 associated_data_(associated_data), 67 attempted_matching_(false), 68 matching_stream_(nullptr) {} 69 std::shared_ptr< 70 crypto::tink::PrimitiveSet<crypto::tink::StreamingAead>> primitives_; 71 std::unique_ptr<crypto::tink::RandomAccessStream> ciphertext_source_; 72 std::string associated_data_; 73 mutable absl::Mutex matching_mutex_; 74 bool attempted_matching_ ABSL_GUARDED_BY(matching_mutex_); 75 std::unique_ptr<crypto::tink::RandomAccessStream> matching_stream_ 76 ABSL_GUARDED_BY(matching_mutex_); 77 }; 78 79 } // namespace streamingaead 80 } // namespace tink 81 } // namespace crypto 82 83 #endif // TINK_STREAMINGAEAD_DECRYPTING_RANDOM_ACCESS_STREAM_H_ 84