Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 1 | // Copyright (c) 2013 The Chromium OS 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 SHILL_CRYPTO_UTIL_PROXY_H_ |
| 6 | #define SHILL_CRYPTO_UTIL_PROXY_H_ |
| 7 | |
Ben Chan | cd47732 | 2014-10-17 14:19:30 -0700 | [diff] [blame] | 8 | #include <memory> |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 9 | #include <string> |
| 10 | #include <vector> |
| 11 | |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 12 | #include <base/cancelable_callback.h> |
Ben Chan | cc67c52 | 2014-09-03 07:19:18 -0700 | [diff] [blame] | 13 | #include <base/macros.h> |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 14 | #include <base/memory/weak_ptr.h> |
Ben Chan | a0ddf46 | 2014-02-06 11:32:42 -0800 | [diff] [blame] | 15 | #include <base/strings/stringprintf.h> |
Utkarsh Sanghi | 83bd64b | 2014-07-29 16:01:43 -0700 | [diff] [blame] | 16 | #include <chromeos/minijail/minijail.h> |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 17 | #include <gtest/gtest_prod.h> // for FRIEND_TEST |
| 18 | |
| 19 | #include "shill/callbacks.h" |
| 20 | #include "shill/error.h" |
Peter Qiu | 8d6b597 | 2014-10-28 15:33:34 -0700 | [diff] [blame] | 21 | #include "shill/net/io_handler.h" |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 22 | #include "shill/proto_bindings/shims/protos/crypto_util.pb.h" |
| 23 | |
| 24 | namespace shill { |
| 25 | |
| 26 | class EventDispatcher; |
| 27 | class FileIO; |
Christopher Wiley | 5447d2e | 2013-03-19 17:46:03 -0700 | [diff] [blame] | 28 | class GLib; |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 29 | class ProcessKiller; |
| 30 | |
| 31 | class CryptoUtilProxy : public base::SupportsWeakPtr<CryptoUtilProxy> { |
| 32 | public: |
| 33 | static const char kCommandVerify[]; |
| 34 | static const char kCommandEncrypt[]; |
| 35 | static const char kCryptoUtilShimPath[]; |
| 36 | |
Paul Stewart | a794cd6 | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 37 | CryptoUtilProxy(EventDispatcher* dispatcher, GLib* glib); |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 38 | virtual ~CryptoUtilProxy(); |
| 39 | |
| 40 | // Verify credentials for the currently connected endpoint of |
| 41 | // |connected_service|. This is a fairly expensive/time consuming operation. |
| 42 | // Returns true if we've succeeded in kicking off a job to an external shim |
| 43 | // to verify credentials. |result_callback| will be called with the actual |
| 44 | // result of the job, either true, or false with a descriptive error. |
Christopher Wiley | 5447d2e | 2013-03-19 17:46:03 -0700 | [diff] [blame] | 45 | // |
| 46 | // |certificate| should be a device certificate in PEM format. |
| 47 | // |public_key| is a base64 encoded DER RSAPublicKey format public key. |
| 48 | // |nonce| has no particular format requirements. |
| 49 | // |signed_data| is the base64 encoded signed string given by the device. |
| 50 | // |destination_udn| has no format requirements. |
| 51 | // |ssid| has no constraints. |
| 52 | // |bssid| should be in the human readable format: 00:11:22:33:44:55. |
Paul Stewart | a794cd6 | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 53 | virtual bool VerifyDestination(const std::string& certificate, |
| 54 | const std::string& public_key, |
| 55 | const std::string& nonce, |
| 56 | const std::string& signed_data, |
| 57 | const std::string& destination_udn, |
| 58 | const std::vector<uint8_t>& ssid, |
| 59 | const std::string& bssid, |
| 60 | const ResultBoolCallback& result_callback, |
| 61 | Error* error); |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 62 | |
Christopher Wiley | 5447d2e | 2013-03-19 17:46:03 -0700 | [diff] [blame] | 63 | // Encrypt |data| under |public_key|. This is a fairly time consuming |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 64 | // process. Returns true if we've succeeded in kicking off a job to an |
| 65 | // external shim to sign the data. |result_callback| will be called with the |
| 66 | // results of the operation: an empty string and a descriptive error or the |
| 67 | // base64 encoded bytes of the encrypted data. |
Christopher Wiley | 5447d2e | 2013-03-19 17:46:03 -0700 | [diff] [blame] | 68 | // |
| 69 | // |public_key| is a base64 encoded DER RSAPublicKey format public key. |
| 70 | // |data| has no particular format requirements. |
Paul Stewart | a794cd6 | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 71 | virtual bool EncryptData(const std::string& public_key, |
| 72 | const std::string& data, |
| 73 | const ResultStringCallback& result_callback, |
| 74 | Error* error); |
Alex Vakulenko | 8a53229 | 2014-06-16 17:18:44 -0700 | [diff] [blame] | 75 | |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 76 | private: |
| 77 | friend class CryptoUtilProxyTest; |
| 78 | friend class MockCryptoUtilProxy; |
| 79 | FRIEND_TEST(CryptoUtilProxyTest, BasicAPIUsage); |
| 80 | FRIEND_TEST(CryptoUtilProxyTest, FailuresReturnValues); |
| 81 | FRIEND_TEST(CryptoUtilProxyTest, OnlyOneInstanceInFlightAtATime); |
| 82 | FRIEND_TEST(CryptoUtilProxyTest, ShimLifeTime); |
| 83 | FRIEND_TEST(CryptoUtilProxyTest, TimeoutsTriggerFailure); |
Christopher Wiley | b3e70d2 | 2013-04-26 17:28:37 -0700 | [diff] [blame] | 84 | FRIEND_TEST(CryptoUtilProxyTest, ShimCleanedBeforeCallback); |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 85 | |
| 86 | static const char kDestinationVerificationUser[]; |
| 87 | static const int kShimJobTimeoutMilliseconds; |
| 88 | |
| 89 | // Helper method for parsing the proto buffer return codes sent back by the |
| 90 | // shim. |
Paul Stewart | a794cd6 | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 91 | static bool ParseResponseReturnCode(int proto_return_code, Error* e); |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 92 | |
| 93 | // Kick off a run of the shim to verify credentials or sign data. Callers |
| 94 | // pass in the command they want to run on the shim (literally a command line |
| 95 | // argument to the shim), and a handler to handle the result. The handler is |
| 96 | // called both on errors, timeouts, and success. Behind the scenes, we first |
| 97 | // send |input| down to the shim through a pipe to its stdin, then wait for |
| 98 | // bytes to comes back over a pipe connected to the shim's stdout. |
Paul Stewart | a794cd6 | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 99 | virtual bool StartShimForCommand(const std::string& command, |
| 100 | const std::string& input, |
| 101 | const StringCallback& result_handler); |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 102 | // This is the big hammer we use to clean up past shim state. |
Paul Stewart | a794cd6 | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 103 | virtual void CleanupShim(const Error& shim_result); |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 104 | virtual void OnShimDeath(); |
| 105 | |
| 106 | // Callbacks that handle IO operations between shill and the shim. Called by |
| 107 | // GLib on changes in file descriptor state. |
| 108 | void HandleShimStdinReady(int fd); |
Paul Stewart | a794cd6 | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 109 | void HandleShimOutput(InputData* data); |
| 110 | void HandleShimReadError(const std::string& error_msg); |
| 111 | void HandleShimError(const Error& error); |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 112 | void HandleShimTimeout(); |
| 113 | // Used to handle the final result of both operations. |result| is a |
| 114 | // seriallized protocol buffer or an empty string on error. On error, |
| 115 | // |error| is filled in with an appropriate error condition. |
| 116 | // |result_callback| is a callback from the original caller (the manager). |
Paul Stewart | a794cd6 | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 117 | void HandleVerifyResult(const ResultBoolCallback& result_handler, |
| 118 | const std::string& result, |
| 119 | const Error& error); |
| 120 | void HandleEncryptResult(const ResultStringCallback& result_handler, |
| 121 | const std::string& result, |
| 122 | const Error& error); |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 123 | |
Paul Stewart | a794cd6 | 2015-06-16 13:13:10 -0700 | [diff] [blame] | 124 | EventDispatcher* dispatcher_; |
| 125 | GLib* glib_; |
| 126 | chromeos::Minijail* minijail_; |
| 127 | ProcessKiller* process_killer_; |
| 128 | FileIO* file_io_; |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 129 | std::string input_buffer_; |
| 130 | std::string::const_iterator next_input_byte_; |
| 131 | std::string output_buffer_; |
| 132 | int shim_stdin_; |
| 133 | int shim_stdout_; |
| 134 | pid_t shim_pid_; |
Ben Chan | cd47732 | 2014-10-17 14:19:30 -0700 | [diff] [blame] | 135 | std::unique_ptr<IOHandler> shim_stdin_handler_; |
| 136 | std::unique_ptr<IOHandler> shim_stdout_handler_; |
Christopher Wiley | 67e425e | 2013-05-02 15:54:51 -0700 | [diff] [blame] | 137 | Error shim_result_; |
Christopher Wiley | 5a3f23a | 2013-02-20 17:29:57 -0800 | [diff] [blame] | 138 | StringCallback result_handler_; |
| 139 | base::CancelableClosure shim_job_timeout_callback_; |
| 140 | |
| 141 | DISALLOW_COPY_AND_ASSIGN(CryptoUtilProxy); |
| 142 | }; |
| 143 | |
| 144 | } // namespace shill |
| 145 | |
| 146 | #endif // SHILL_CRYPTO_UTIL_PROXY_H_ |