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