1 // 2 // Copyright (C) 2013 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef SHILL_CRYPTO_UTIL_PROXY_H_ 18 #define SHILL_CRYPTO_UTIL_PROXY_H_ 19 20 #include <memory> 21 #include <string> 22 #include <vector> 23 24 #include <base/cancelable_callback.h> 25 #include <base/macros.h> 26 #include <base/memory/weak_ptr.h> 27 #include <base/strings/stringprintf.h> 28 #include <brillo/minijail/minijail.h> 29 #include <gtest/gtest_prod.h> // for FRIEND_TEST 30 31 #include "shill/callbacks.h" 32 #include "shill/error.h" 33 #include "shill/net/io_handler.h" 34 #include "shill/shims/protos/crypto_util.pb.h" 35 36 namespace shill { 37 38 class EventDispatcher; 39 class FileIO; 40 class ProcessManager; 41 42 class CryptoUtilProxy : public base::SupportsWeakPtr<CryptoUtilProxy> { 43 public: 44 static const char kCommandVerify[]; 45 static const char kCommandEncrypt[]; 46 static const char kCryptoUtilShimPath[]; 47 48 explicit CryptoUtilProxy(EventDispatcher* dispatcher); 49 virtual ~CryptoUtilProxy(); 50 51 // Verify credentials for the currently connected endpoint of 52 // |connected_service|. This is a fairly expensive/time consuming operation. 53 // Returns true if we've succeeded in kicking off a job to an external shim 54 // to verify credentials. |result_callback| will be called with the actual 55 // result of the job, either true, or false with a descriptive error. 56 // 57 // |certificate| should be a device certificate in PEM format. 58 // |public_key| is a base64 encoded DER RSAPublicKey format public key. 59 // |nonce| has no particular format requirements. 60 // |signed_data| is the base64 encoded signed string given by the device. 61 // |destination_udn| has no format requirements. 62 // |ssid| has no constraints. 63 // |bssid| should be in the human readable format: 00:11:22:33:44:55. 64 virtual bool VerifyDestination(const std::string& certificate, 65 const std::string& public_key, 66 const std::string& nonce, 67 const std::string& signed_data, 68 const std::string& destination_udn, 69 const std::vector<uint8_t>& ssid, 70 const std::string& bssid, 71 const ResultBoolCallback& result_callback, 72 Error* error); 73 74 // Encrypt |data| under |public_key|. This is a fairly time consuming 75 // process. Returns true if we've succeeded in kicking off a job to an 76 // external shim to sign the data. |result_callback| will be called with the 77 // results of the operation: an empty string and a descriptive error or the 78 // base64 encoded bytes of the encrypted data. 79 // 80 // |public_key| is a base64 encoded DER RSAPublicKey format public key. 81 // |data| has no particular format requirements. 82 virtual bool EncryptData(const std::string& public_key, 83 const std::string& data, 84 const ResultStringCallback& result_callback, 85 Error* error); 86 87 private: 88 friend class CryptoUtilProxyTest; 89 friend class MockCryptoUtilProxy; 90 FRIEND_TEST(CryptoUtilProxyTest, BasicAPIUsage); 91 FRIEND_TEST(CryptoUtilProxyTest, FailuresReturnValues); 92 FRIEND_TEST(CryptoUtilProxyTest, OnlyOneInstanceInFlightAtATime); 93 FRIEND_TEST(CryptoUtilProxyTest, ShimLifeTime); 94 FRIEND_TEST(CryptoUtilProxyTest, TimeoutsTriggerFailure); 95 FRIEND_TEST(CryptoUtilProxyTest, ShimCleanedBeforeCallback); 96 97 static const char kDestinationVerificationUser[]; 98 static const uint64_t kRequiredCapabilities; 99 static const int kShimJobTimeoutMilliseconds; 100 101 // Helper method for parsing the proto buffer return codes sent back by the 102 // shim. 103 static bool ParseResponseReturnCode(int proto_return_code, Error* e); 104 105 // Kick off a run of the shim to verify credentials or sign data. Callers 106 // pass in the command they want to run on the shim (literally a command line 107 // argument to the shim), and a handler to handle the result. The handler is 108 // called both on errors, timeouts, and success. Behind the scenes, we first 109 // send |input| down to the shim through a pipe to its stdin, then wait for 110 // bytes to comes back over a pipe connected to the shim's stdout. 111 virtual bool StartShimForCommand(const std::string& command, 112 const std::string& input, 113 const StringCallback& result_handler); 114 // This is the big hammer we use to clean up past shim state. 115 virtual void CleanupShim(const Error& shim_result); 116 virtual void OnShimDeath(int exit_status); 117 118 // Callbacks that handle IO operations between shill and the shim. 119 // Called on changes in file descriptor state. 120 void HandleShimStdinReady(int fd); 121 void HandleShimOutput(InputData* data); 122 void HandleShimReadError(const std::string& error_msg); 123 void HandleShimError(const Error& error); 124 void HandleShimTimeout(); 125 // Used to handle the final result of both operations. |result| is a 126 // seriallized protocol buffer or an empty string on error. On error, 127 // |error| is filled in with an appropriate error condition. 128 // |result_callback| is a callback from the original caller (the manager). 129 void HandleVerifyResult(const ResultBoolCallback& result_handler, 130 const std::string& result, 131 const Error& error); 132 void HandleEncryptResult(const ResultStringCallback& result_handler, 133 const std::string& result, 134 const Error& error); 135 136 EventDispatcher* dispatcher_; 137 ProcessManager* process_manager_; 138 FileIO* file_io_; 139 std::string input_buffer_; 140 std::string::const_iterator next_input_byte_; 141 std::string output_buffer_; 142 int shim_stdin_; 143 int shim_stdout_; 144 pid_t shim_pid_; 145 std::unique_ptr<IOHandler> shim_stdin_handler_; 146 std::unique_ptr<IOHandler> shim_stdout_handler_; 147 Error shim_result_; 148 StringCallback result_handler_; 149 base::CancelableClosure shim_job_timeout_callback_; 150 151 DISALLOW_COPY_AND_ASSIGN(CryptoUtilProxy); 152 }; 153 154 } // namespace shill 155 156 #endif // SHILL_CRYPTO_UTIL_PROXY_H_ 157