1 // Copyright 2020 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_POLICY_MESSAGING_LAYER_ENCRYPTION_DECRYPTION_H_ 6 #define CHROME_BROWSER_POLICY_MESSAGING_LAYER_ENCRYPTION_DECRYPTION_H_ 7 8 #include <string> 9 10 #include "base/callback.h" 11 #include "base/containers/flat_map.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/scoped_refptr.h" 14 #include "base/optional.h" 15 #include "base/strings/string_piece.h" 16 #include "base/threading/thread.h" 17 #include "base/threading/thread_task_runner_handle.h" 18 #include "chrome/browser/policy/messaging_layer/encryption/encryption.h" 19 #include "chrome/browser/policy/messaging_layer/util/status.h" 20 #include "chrome/browser/policy/messaging_layer/util/statusor.h" 21 22 namespace reporting { 23 24 // Full implementation of Decryptor, intended for use in tests and potentially 25 // in reporting server (wrapped in a Java class). 26 // 27 // Curve25519 decryption of the symmetric key with asymmetric private key. 28 // ChaCha20_Poly1305 decryption and verification of a record in place with 29 // symmetric key. 30 // 31 // Instantiated by an implementation-specific factory: 32 // StatusOr<scoped_refptr<Decryptor>> Create(); 33 class Decryptor : public base::RefCountedThreadSafe<Decryptor> { 34 public: 35 // Decryption record handle, which is created by |OpenRecord| and can accept 36 // pieces of data to be decrypted as one record by calling |AddToRecord| 37 // multiple times. Resulting decrypted record is available once |CloseRecord| 38 // is called. 39 class Handle { 40 public: 41 Handle(base::StringPiece shared_secret, scoped_refptr<Decryptor> decryptor); 42 Handle(const Handle& other) = delete; 43 Handle& operator=(const Handle& other) = delete; 44 ~Handle(); 45 46 // Adds piece of encrypted data to the record. 47 void AddToRecord(base::StringPiece data, 48 base::OnceCallback<void(Status)> cb); 49 50 // Closes and attempts to decrypt the record. Hands over the decrypted data 51 // to be processed by the server (or Status if unsuccessful). Accesses key 52 // store to attempt all private keys that are considered to be valid, 53 // starting with the one that matches the hash. Self-destructs after the 54 // callback. 55 void CloseRecord(base::OnceCallback<void(StatusOr<base::StringPiece>)> cb); 56 57 private: 58 // Shared secret based on which symmetric key is produced. 59 const std::string shared_secret_; 60 61 // Accumulated data to decrypt. 62 std::string record_; 63 64 scoped_refptr<Decryptor> decryptor_; 65 }; 66 67 // Factory method to instantiate the Decryptor. 68 static StatusOr<scoped_refptr<Decryptor>> Create(); 69 70 // Factory method creates a new record to collect data and decrypt them with 71 // the given encrypted key. Hands the handle raw pointer over to the callback, 72 // or error status. 73 void OpenRecord(base::StringPiece encrypted_key, 74 base::OnceCallback<void(StatusOr<Handle*>)> cb); 75 76 // Recreates shared secret from local private key and peer public value and 77 // returns it or error status. 78 StatusOr<std::string> DecryptSecret(base::StringPiece public_key, 79 base::StringPiece peer_public_value); 80 81 // Records a key pair (stores only private key). 82 // Executes on a sequenced thread, returns key id or error with callback. 83 void RecordKeyPair( 84 base::StringPiece private_key, 85 base::StringPiece public_key, 86 base::OnceCallback<void(StatusOr<Encryptor::PublicKeyId>)> cb); 87 88 // Retrieves private key matching the public key hash. 89 // Executes on a sequenced thread, returns with callback. 90 void RetrieveMatchingPrivateKey( 91 Encryptor::PublicKeyId public_key_id, 92 base::OnceCallback<void(StatusOr<std::string>)> cb); 93 94 private: 95 friend base::RefCountedThreadSafe<Decryptor>; 96 Decryptor(); 97 ~Decryptor(); 98 99 // Map of hash(public_key)->{private key, time stamp} 100 // Private key is located by the hash of a public key, sent together with the 101 // encrypted record. Keys older than pre-defined threshold are discarded. 102 // Time stamp allows to drop outdated keys (not implemented yet). 103 struct KeyInfo { 104 std::string private_key; 105 base::Time time_stamp; 106 }; 107 base::flat_map<Encryptor::PublicKeyId, KeyInfo> keys_; 108 109 // Sequential task runner for all keys_ activities: 110 // recording, lookup, purge. 111 scoped_refptr<base::SequencedTaskRunner> keys_sequenced_task_runner_; 112 113 SEQUENCE_CHECKER(keys_sequence_checker_); 114 }; 115 116 } // namespace reporting 117 118 #endif // CHROME_BROWSER_POLICY_MESSAGING_LAYER_ENCRYPTION_DECRYPTION_H_ 119