blob: f493ababca86d2a8148977a9a591d080ea340dab [file] [log] [blame]
Christopher Wiley5a3f23a2013-02-20 17:29:57 -08001// 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 Chancd477322014-10-17 14:19:30 -07008#include <memory>
Christopher Wiley5a3f23a2013-02-20 17:29:57 -08009#include <string>
10#include <vector>
11
Christopher Wiley5a3f23a2013-02-20 17:29:57 -080012#include <base/cancelable_callback.h>
Ben Chancc67c522014-09-03 07:19:18 -070013#include <base/macros.h>
Christopher Wiley5a3f23a2013-02-20 17:29:57 -080014#include <base/memory/weak_ptr.h>
Ben Chana0ddf462014-02-06 11:32:42 -080015#include <base/strings/stringprintf.h>
Utkarsh Sanghi83bd64b2014-07-29 16:01:43 -070016#include <chromeos/minijail/minijail.h>
Christopher Wiley5a3f23a2013-02-20 17:29:57 -080017#include <gtest/gtest_prod.h> // for FRIEND_TEST
18
19#include "shill/callbacks.h"
20#include "shill/error.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070021#include "shill/net/io_handler.h"
Christopher Wiley5a3f23a2013-02-20 17:29:57 -080022#include "shill/proto_bindings/shims/protos/crypto_util.pb.h"
23
24namespace shill {
25
26class EventDispatcher;
27class FileIO;
Christopher Wiley5447d2e2013-03-19 17:46:03 -070028class GLib;
Christopher Wiley5a3f23a2013-02-20 17:29:57 -080029class ProcessKiller;
30
31class CryptoUtilProxy : public base::SupportsWeakPtr<CryptoUtilProxy> {
32 public:
33 static const char kCommandVerify[];
34 static const char kCommandEncrypt[];
35 static const char kCryptoUtilShimPath[];
36
Paul Stewarta794cd62015-06-16 13:13:10 -070037 CryptoUtilProxy(EventDispatcher* dispatcher, GLib* glib);
Christopher Wiley5a3f23a2013-02-20 17:29:57 -080038 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 Wiley5447d2e2013-03-19 17:46:03 -070045 //
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 Stewarta794cd62015-06-16 13:13:10 -070053 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 Wiley5a3f23a2013-02-20 17:29:57 -080062
Christopher Wiley5447d2e2013-03-19 17:46:03 -070063 // Encrypt |data| under |public_key|. This is a fairly time consuming
Christopher Wiley5a3f23a2013-02-20 17:29:57 -080064 // 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 Wiley5447d2e2013-03-19 17:46:03 -070068 //
69 // |public_key| is a base64 encoded DER RSAPublicKey format public key.
70 // |data| has no particular format requirements.
Paul Stewarta794cd62015-06-16 13:13:10 -070071 virtual bool EncryptData(const std::string& public_key,
72 const std::string& data,
73 const ResultStringCallback& result_callback,
74 Error* error);
Alex Vakulenko8a532292014-06-16 17:18:44 -070075
Christopher Wiley5a3f23a2013-02-20 17:29:57 -080076 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 Wileyb3e70d22013-04-26 17:28:37 -070084 FRIEND_TEST(CryptoUtilProxyTest, ShimCleanedBeforeCallback);
Christopher Wiley5a3f23a2013-02-20 17:29:57 -080085
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 Stewarta794cd62015-06-16 13:13:10 -070091 static bool ParseResponseReturnCode(int proto_return_code, Error* e);
Christopher Wiley5a3f23a2013-02-20 17:29:57 -080092
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 Stewarta794cd62015-06-16 13:13:10 -070099 virtual bool StartShimForCommand(const std::string& command,
100 const std::string& input,
101 const StringCallback& result_handler);
Christopher Wiley5a3f23a2013-02-20 17:29:57 -0800102 // This is the big hammer we use to clean up past shim state.
Paul Stewarta794cd62015-06-16 13:13:10 -0700103 virtual void CleanupShim(const Error& shim_result);
Christopher Wiley5a3f23a2013-02-20 17:29:57 -0800104 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 Stewarta794cd62015-06-16 13:13:10 -0700109 void HandleShimOutput(InputData* data);
110 void HandleShimReadError(const std::string& error_msg);
111 void HandleShimError(const Error& error);
Christopher Wiley5a3f23a2013-02-20 17:29:57 -0800112 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 Stewarta794cd62015-06-16 13:13:10 -0700117 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 Wiley5a3f23a2013-02-20 17:29:57 -0800123
Paul Stewarta794cd62015-06-16 13:13:10 -0700124 EventDispatcher* dispatcher_;
125 GLib* glib_;
126 chromeos::Minijail* minijail_;
127 ProcessKiller* process_killer_;
128 FileIO* file_io_;
Christopher Wiley5a3f23a2013-02-20 17:29:57 -0800129 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 Chancd477322014-10-17 14:19:30 -0700135 std::unique_ptr<IOHandler> shim_stdin_handler_;
136 std::unique_ptr<IOHandler> shim_stdout_handler_;
Christopher Wiley67e425e2013-05-02 15:54:51 -0700137 Error shim_result_;
Christopher Wiley5a3f23a2013-02-20 17:29:57 -0800138 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_