1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2013 The Android Open Source Project 3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License"); 5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License. 6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at 7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// http://www.apache.org/licenses/LICENSE-2.0 9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software 11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS, 12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and 14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License. 15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 165a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 175a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#ifndef SHILL_CRYPTO_UTIL_PROXY_H_ 185a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#define SHILL_CRYPTO_UTIL_PROXY_H_ 195a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 20cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan#include <memory> 215a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include <string> 225a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include <vector> 235a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 245a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include <base/cancelable_callback.h> 25cc67c52a2c00f90e877971d552208dd99825d84eBen Chan#include <base/macros.h> 265a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include <base/memory/weak_ptr.h> 27a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/stringprintf.h> 2803e6719bae1e0903d94853b896673a033196bcf5Alex Vakulenko#include <brillo/minijail/minijail.h> 295a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include <gtest/gtest_prod.h> // for FRIEND_TEST 305a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 315a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include "shill/callbacks.h" 325a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#include "shill/error.h" 338d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/io_handler.h" 349151894faea5fa8ccd7d538976390fc95f37d13eSamuel Tan#include "shill/shims/protos/crypto_util.pb.h" 355a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 365a3f23a122566b53e230b1132c0241411016386aChristopher Wileynamespace shill { 375a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 385a3f23a122566b53e230b1132c0241411016386aChristopher Wileyclass EventDispatcher; 395a3f23a122566b53e230b1132c0241411016386aChristopher Wileyclass FileIO; 40304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawalclass ProcessManager; 415a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 425a3f23a122566b53e230b1132c0241411016386aChristopher Wileyclass CryptoUtilProxy : public base::SupportsWeakPtr<CryptoUtilProxy> { 435a3f23a122566b53e230b1132c0241411016386aChristopher Wiley public: 445a3f23a122566b53e230b1132c0241411016386aChristopher Wiley static const char kCommandVerify[]; 455a3f23a122566b53e230b1132c0241411016386aChristopher Wiley static const char kCommandEncrypt[]; 465a3f23a122566b53e230b1132c0241411016386aChristopher Wiley static const char kCryptoUtilShimPath[]; 475a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 4813d581fa047118d065f41eb1d0da203cf0a49b07mukesh agrawal explicit CryptoUtilProxy(EventDispatcher* dispatcher); 495a3f23a122566b53e230b1132c0241411016386aChristopher Wiley virtual ~CryptoUtilProxy(); 505a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 515a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Verify credentials for the currently connected endpoint of 525a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // |connected_service|. This is a fairly expensive/time consuming operation. 535a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Returns true if we've succeeded in kicking off a job to an external shim 545a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // to verify credentials. |result_callback| will be called with the actual 555a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // result of the job, either true, or false with a descriptive error. 565447d2e616b657a36ef878ae35c77f7d2f4d2c8eChristopher Wiley // 575447d2e616b657a36ef878ae35c77f7d2f4d2c8eChristopher Wiley // |certificate| should be a device certificate in PEM format. 585447d2e616b657a36ef878ae35c77f7d2f4d2c8eChristopher Wiley // |public_key| is a base64 encoded DER RSAPublicKey format public key. 595447d2e616b657a36ef878ae35c77f7d2f4d2c8eChristopher Wiley // |nonce| has no particular format requirements. 605447d2e616b657a36ef878ae35c77f7d2f4d2c8eChristopher Wiley // |signed_data| is the base64 encoded signed string given by the device. 615447d2e616b657a36ef878ae35c77f7d2f4d2c8eChristopher Wiley // |destination_udn| has no format requirements. 625447d2e616b657a36ef878ae35c77f7d2f4d2c8eChristopher Wiley // |ssid| has no constraints. 635447d2e616b657a36ef878ae35c77f7d2f4d2c8eChristopher Wiley // |bssid| should be in the human readable format: 00:11:22:33:44:55. 64a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart virtual bool VerifyDestination(const std::string& certificate, 65a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const std::string& public_key, 66a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const std::string& nonce, 67a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const std::string& signed_data, 68a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const std::string& destination_udn, 69a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const std::vector<uint8_t>& ssid, 70a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const std::string& bssid, 71a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const ResultBoolCallback& result_callback, 72a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error); 735a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 745447d2e616b657a36ef878ae35c77f7d2f4d2c8eChristopher Wiley // Encrypt |data| under |public_key|. This is a fairly time consuming 755a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // process. Returns true if we've succeeded in kicking off a job to an 765a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // external shim to sign the data. |result_callback| will be called with the 775a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // results of the operation: an empty string and a descriptive error or the 785a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // base64 encoded bytes of the encrypted data. 795447d2e616b657a36ef878ae35c77f7d2f4d2c8eChristopher Wiley // 805447d2e616b657a36ef878ae35c77f7d2f4d2c8eChristopher Wiley // |public_key| is a base64 encoded DER RSAPublicKey format public key. 815447d2e616b657a36ef878ae35c77f7d2f4d2c8eChristopher Wiley // |data| has no particular format requirements. 82a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart virtual bool EncryptData(const std::string& public_key, 83a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const std::string& data, 84a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const ResultStringCallback& result_callback, 85a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart Error* error); 868a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko 875a3f23a122566b53e230b1132c0241411016386aChristopher Wiley private: 885a3f23a122566b53e230b1132c0241411016386aChristopher Wiley friend class CryptoUtilProxyTest; 895a3f23a122566b53e230b1132c0241411016386aChristopher Wiley friend class MockCryptoUtilProxy; 905a3f23a122566b53e230b1132c0241411016386aChristopher Wiley FRIEND_TEST(CryptoUtilProxyTest, BasicAPIUsage); 915a3f23a122566b53e230b1132c0241411016386aChristopher Wiley FRIEND_TEST(CryptoUtilProxyTest, FailuresReturnValues); 925a3f23a122566b53e230b1132c0241411016386aChristopher Wiley FRIEND_TEST(CryptoUtilProxyTest, OnlyOneInstanceInFlightAtATime); 935a3f23a122566b53e230b1132c0241411016386aChristopher Wiley FRIEND_TEST(CryptoUtilProxyTest, ShimLifeTime); 945a3f23a122566b53e230b1132c0241411016386aChristopher Wiley FRIEND_TEST(CryptoUtilProxyTest, TimeoutsTriggerFailure); 95b3e70d2ca1cfb02effd82c6f95f2869d22201860Christopher Wiley FRIEND_TEST(CryptoUtilProxyTest, ShimCleanedBeforeCallback); 965a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 975a3f23a122566b53e230b1132c0241411016386aChristopher Wiley static const char kDestinationVerificationUser[]; 98304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal static const uint64_t kRequiredCapabilities; 995a3f23a122566b53e230b1132c0241411016386aChristopher Wiley static const int kShimJobTimeoutMilliseconds; 1005a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 1015a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Helper method for parsing the proto buffer return codes sent back by the 1025a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // shim. 103a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart static bool ParseResponseReturnCode(int proto_return_code, Error* e); 1045a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 1055a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Kick off a run of the shim to verify credentials or sign data. Callers 1065a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // pass in the command they want to run on the shim (literally a command line 1075a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // argument to the shim), and a handler to handle the result. The handler is 1085a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // called both on errors, timeouts, and success. Behind the scenes, we first 1095a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // send |input| down to the shim through a pipe to its stdin, then wait for 1105a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // bytes to comes back over a pipe connected to the shim's stdout. 111a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart virtual bool StartShimForCommand(const std::string& command, 112a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const std::string& input, 113a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const StringCallback& result_handler); 1145a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // This is the big hammer we use to clean up past shim state. 115a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart virtual void CleanupShim(const Error& shim_result); 116304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal virtual void OnShimDeath(int exit_status); 1175a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 11813d581fa047118d065f41eb1d0da203cf0a49b07mukesh agrawal // Callbacks that handle IO operations between shill and the shim. 11913d581fa047118d065f41eb1d0da203cf0a49b07mukesh agrawal // Called on changes in file descriptor state. 1205a3f23a122566b53e230b1132c0241411016386aChristopher Wiley void HandleShimStdinReady(int fd); 121a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart void HandleShimOutput(InputData* data); 122a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart void HandleShimReadError(const std::string& error_msg); 123a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart void HandleShimError(const Error& error); 1245a3f23a122566b53e230b1132c0241411016386aChristopher Wiley void HandleShimTimeout(); 1255a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // Used to handle the final result of both operations. |result| is a 1265a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // seriallized protocol buffer or an empty string on error. On error, 1275a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // |error| is filled in with an appropriate error condition. 1285a3f23a122566b53e230b1132c0241411016386aChristopher Wiley // |result_callback| is a callback from the original caller (the manager). 129a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart void HandleVerifyResult(const ResultBoolCallback& result_handler, 130a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const std::string& result, 131a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const Error& error); 132a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart void HandleEncryptResult(const ResultStringCallback& result_handler, 133a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const std::string& result, 134a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart const Error& error); 135a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart 136a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart EventDispatcher* dispatcher_; 137304afb43643faa19fa3a599a59fbb1574c0a06efmukesh agrawal ProcessManager* process_manager_; 138a794cd60a7339d576ea2eed263a4f0a20fb255afPaul Stewart FileIO* file_io_; 1395a3f23a122566b53e230b1132c0241411016386aChristopher Wiley std::string input_buffer_; 1405a3f23a122566b53e230b1132c0241411016386aChristopher Wiley std::string::const_iterator next_input_byte_; 1415a3f23a122566b53e230b1132c0241411016386aChristopher Wiley std::string output_buffer_; 1425a3f23a122566b53e230b1132c0241411016386aChristopher Wiley int shim_stdin_; 1435a3f23a122566b53e230b1132c0241411016386aChristopher Wiley int shim_stdout_; 1445a3f23a122566b53e230b1132c0241411016386aChristopher Wiley pid_t shim_pid_; 145cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan std::unique_ptr<IOHandler> shim_stdin_handler_; 146cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan std::unique_ptr<IOHandler> shim_stdout_handler_; 14767e425e5af9b28ffff2c17f879e70f9f6a4e10e9Christopher Wiley Error shim_result_; 1485a3f23a122566b53e230b1132c0241411016386aChristopher Wiley StringCallback result_handler_; 1495a3f23a122566b53e230b1132c0241411016386aChristopher Wiley base::CancelableClosure shim_job_timeout_callback_; 1505a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 1515a3f23a122566b53e230b1132c0241411016386aChristopher Wiley DISALLOW_COPY_AND_ASSIGN(CryptoUtilProxy); 1525a3f23a122566b53e230b1132c0241411016386aChristopher Wiley}; 1535a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 1545a3f23a122566b53e230b1132c0241411016386aChristopher Wiley} // namespace shill 1555a3f23a122566b53e230b1132c0241411016386aChristopher Wiley 1565a3f23a122566b53e230b1132c0241411016386aChristopher Wiley#endif // SHILL_CRYPTO_UTIL_PROXY_H_ 157