github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/tao/util.h (about) 1 // File: util.h 2 // Author: Tom Roeder <tmroeder@google.com> 3 // 4 // Description: Utility methods for the Tao. 5 // 6 // Copyright (c) 2013, Google Inc. All rights reserved. 7 // 8 // Licensed under the Apache License, Version 2.0 (the "License"); 9 // you may not use this file except in compliance with the License. 10 // You may obtain a copy of the License at 11 // 12 // http://www.apache.org/licenses/LICENSE-2.0 13 // 14 // Unless required by applicable law or agreed to in writing, software 15 // distributed under the License is distributed on an "AS IS" BASIS, 16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 // See the License for the specific language governing permissions and 18 // limitations under the License. 19 #ifndef TAO_UTIL_H_ 20 #define TAO_UTIL_H_ 21 22 #include <sys/socket.h> // for socklen_t 23 24 /// These utilities from the standard library are used extensively 25 /// throughout the Tao implementation, so we include them here. 26 #include <list> 27 #include <memory> 28 #include <set> 29 #include <sstream> 30 #include <string> 31 32 /// These basic third-party headers are used extensively throughout the Tao 33 /// implementation, so we include them here. 34 #include <chromium/base/file_path.h> 35 #include <chromium/base/file_util.h> 36 37 #include "tao/tao.h" 38 39 namespace google { 40 namespace protobuf { 41 class Message; 42 } // namespace protobuf 43 } // namespace google 44 45 namespace tao { 46 /// These third-party and standard library utilities are used extensively 47 /// throughout the Tao implementation, so import them into the tao namespace 48 /// here. 49 /// @{ 50 51 /// A macro to disallow the copy constructor and operator= functions 52 /// This should be used in the private: declarations for a class. 53 /// Taken from Google C++ Style Guide. 54 #undef DISALLOW_COPY_AND_ASSIGN 55 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 56 TypeName(const TypeName &) = delete; \ 57 void operator=(const TypeName &) = delete; 58 59 using std::list; 60 using std::set; 61 using std::string; 62 using std::stringstream; 63 using std::unique_ptr; 64 // using std::make_unique; // implemented below 65 66 using chromium::base::CreateDirectory; // NOLINT 67 using chromium::base::DeleteFile; // NOLINT 68 using chromium::base::DirectoryExists; // NOLINT 69 using chromium::base::FilePath; // NOLINT 70 using chromium::base::PathExists; // NOLINT 71 using chromium::base::ReadFileToString; // NOLINT 72 using chromium::base::WriteStringToFile; // NOLINT 73 74 /// @} 75 76 /// Exception-safe factory for unique_ptr. 77 /// Author: Herb Sutter (http://herbsutter.com/gotw/_102/) 78 template <typename T, typename... Args> 79 std::unique_ptr<T> make_unique(Args &&... args) { 80 return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); 81 } 82 83 /// Close a file descriptor and ignore the return value. This is used by the 84 /// definition of ScopedFd. 85 /// @param fd A pointer to the file descriptor to close and free. 86 void fd_close(int *fd); 87 88 /// Close a FILE and ignore the return value. This is used by the 89 /// definition of ScopedFile. 90 /// @param fd A pointer to the FILE to close and free. 91 void file_close(FILE *file); 92 93 /// Remove a directory and all its subfiles and subdirectories. This is used by 94 /// the definition of ScopedTempDir. 95 /// @param dir The path to the directory. 96 void temp_file_cleaner(string *dir); 97 98 /// A version of unique_ptr::reset() that returns the new pointer. Useful for 99 /// putting reset inside of conditionals. 100 /// @param t The unique_ptr to be reset. 101 /// @param p The new pointer to manage. 102 template <typename T> 103 T *reset(unique_ptr<T> &t, T *p) { // NOLINT 104 t.reset(p); 105 return p; 106 } 107 108 /// A functor template for wrapping unique_ptr deallocator functions. 109 template <typename T, void (*F)(T *)> 110 struct UniquePointerDeleter { 111 void operator()(T *ptr) const { F(ptr); } 112 }; 113 114 /// A typedef template (aka type alias, alias template) for zero-overhead 115 /// unique_ptr with a custom deallocator function. 116 template <typename T, void (*F)(T *)> 117 using unique_free_ptr = unique_ptr<T, UniquePointerDeleter<T, F>>; 118 119 /// Cleanse the contents of a string. 120 /// @param s The string to be cleansed. 121 void SecureStringErase(string *s); 122 123 /// Cleanse the contents of a string then free it. 124 /// @param s The string to be cleansed and freed. 125 void SecureStringFree(string *s); 126 127 /// A smart pointer to a string that clears itself. 128 typedef unique_free_ptr<string, SecureStringFree> ScopedSafeString; 129 130 /// A smart pointer to a file descriptor. 131 typedef unique_free_ptr<int, fd_close> ScopedFd; 132 133 /// A smart pointer to a FILE. 134 typedef unique_free_ptr<FILE, file_close> ScopedFile; 135 136 /// A smart pointer to a temporary directory to be cleaned upon destruction. 137 typedef unique_free_ptr<string, temp_file_cleaner> ScopedTempDir; 138 139 /// Extract pointer to string data. These can be used for library functions 140 /// that require raw pointers instead of C++ strings. Returned const pointers 141 /// should not be written to. Returned non-const pointers can be written. Any 142 /// string operation that invalidates an iterator will also invalidate the 143 /// returned pointer. 144 /// @param s The string. 145 /// @{ 146 // TODO(kwalsh) See cryptic note about string_as_array vs const_cast in Keyczar 147 // and elsewhere saying: 148 // DO NOT USE const_cast<char*>(str->data())! See the unittest for why. 149 // This likely has to do with the fact that the buffer returned from data() is 150 // not meant to be modified and might in fact be copy-on-write shared. 151 inline const char *str2char(const string &s) { 152 return s.empty() ? nullptr : &*s.begin(); 153 } 154 inline const unsigned char *str2uchar(const string &s) { 155 return reinterpret_cast<const unsigned char *>(str2char(s)); 156 } 157 inline char *str2char(string *s) { return s->empty() ? nullptr : &*s->begin(); } 158 inline unsigned char *str2uchar(string *s) { 159 return reinterpret_cast<unsigned char *>(str2char(s)); 160 } 161 /// @} 162 163 /// Call the OpenSSL initialization routines and set up locking for 164 /// multi-threaded access. 165 bool InitializeOpenSSL(); 166 167 /// Perform application initialization routines, including initialization for 168 /// OpenSSL, google logging, google protobuffers, and google flags. The 169 /// parameters have the same semantics as google flags. 170 /// @param argc Pointer to argc from main. 171 /// @param argv Pointer to argv from main. 172 /// @param remove_args Whether or not to remove processed args. 173 bool InitializeApp(int *argc, char ***argv, bool remove_args); 174 175 /// Check for, log, and clear any recent openssl errors on the current thread. 176 /// Returns true iff there were no recent errors. 177 /// 178 /// This function can be used for non-fatal errors, e.g. 179 /// X509 *cert = SSL_get_certificate(...); 180 /// if (!OpenSSLSuccess()) { 181 /// LOG(ERROR) << "Could not find certificate, dropping this connection"; 182 /// return false; 183 /// } 184 /// 185 /// Or, this function can be used with google-glog CHECK for fatal errors, e.g. 186 /// X509 *cert = SSL_get_certificate(...); 187 /// CHECK(OpenSSLSuccess()) << "Required cert missing, exiting program"; 188 /// 189 /// We also install an OpenSSL FailureFunction that will call this function 190 /// before exiting on any FATAL error, e.g. errors from any CHECK(...) failure. 191 /// So this will also print details on ssl errors: 192 /// X509 *cert = SSL_get_certificate(...); 193 /// CHECK(cert != null) << "Could not find a required certificate, exiting 194 /// program"; 195 bool OpenSSLSuccess(); 196 197 /// Generate and save a random secret, sealed against the host Tao. 198 /// @param tao The interface to access the host Tao. 199 /// @param path The location to store the sealed secret. 200 /// @param policy A sealing policy under which to seal the secret. 201 /// @param secret_size The number of random bytes for the new secret. 202 /// @param[out] secret The new random secret. 203 bool MakeSealedSecret(Tao *tao, const string &path, const string &policy, 204 int secret_size, string *secret); 205 206 /// Read and unseal a secret that is sealed against the host Tao. 207 /// @param tao The interface to access the host Tao. 208 /// @param path The location to store the sealed secret. 209 /// @param policy The policy under which the secret is expected to have been 210 /// sealed. The call will fail if this does not match the actual policy under 211 /// which the secret was sealed. 212 /// @param secret[out] The unsealed secret. 213 bool GetSealedSecret(Tao *tao, const string &path, const string &policy, 214 string *secret); 215 216 /// Create a temporary directory. 217 /// @param prefix The partial path of the directory to create. 218 /// @param[out] dir A pointer to an object that will take ownership of the 219 /// new temporary directory. 220 bool CreateTempDir(const string &prefix, ScopedTempDir *dir); 221 222 /// Add double-quotes to a string, but escape any existing backslashes or 223 /// double-quotes. 224 /// @param s The string to escape and add quotes around. 225 string quotedString(const string &s); 226 227 /// Read a double-quoted string from a stream, and remove the outer 228 /// double-quotes and escapes for inner double-quotes and backslashes. 229 /// This also ignores leading whitespace, as typical of istream operations. 230 /// @param in The input stream. 231 /// @param s The resulting quoted string. 232 std::stringstream &getQuotedString(std::stringstream &in, string *s); // NOLINT 233 234 /// Skip a sequence of characters in a stream. 235 /// @param in The input stream. 236 /// @param s The characters to skip. 237 std::stringstream &skip(std::stringstream &in, const string &s); // NOLINT 238 239 /// Elide a string for debug-printing purposes. 240 /// Non-printing and backslashes will be converted to escape sequences, and 241 /// long sequences of characters between double-quotes will be truncated. 242 string elideString(const string &s); 243 244 /// Elide an array of bytes for debug-printing purposes. 245 /// Bytes will be printed in hex, with long sequences truncated. 246 string elideBytes(const string &s); 247 248 /// Encode an array of bytes as hex. 249 /// @param s The array of bytes. 250 string bytesToHex(const string &s); 251 252 /// Decode hex into an array of bytes. 253 /// @param hex The hex string. 254 /// @param[out] s The array of bytes. 255 bool bytesFromHex(const string &hex, string *s); 256 257 /// Join a sequence of printable values as a string. Values are converted to 258 /// strings using the standard put << operator. 259 /// @param it An STL-like iterator marking the start of the sequence. 260 /// @param end An STL-like iterator marking the end of the sequence. 261 /// @param delim A delimiter to put between values. 262 template <class T> 263 static string join(T it, T end, const string &delim) { 264 stringstream out; 265 bool first = true; 266 for (; it != end; ++it) { 267 if (!first) out << delim; 268 first = false; 269 out << *it; 270 } 271 return out.str(); 272 } 273 274 /// Join a list of printable values as a string. Values are converted to 275 /// strings using the standard put << operator. 276 /// @param values A list of values. 277 /// @param delim A delimiter to put between values. 278 template <class T> 279 static string join(const list<T> &values, const string &delim) { 280 return join(values.begin(), values.end(), delim); 281 } 282 283 /// Join a set of printable values as a string. Values are converted to 284 /// strings using the standard put << operator. 285 /// @param values A set of values. 286 /// @param delim A delimiter to put between values. 287 template <class T> 288 static string join(const set<T> &values, const string &delim) { 289 return join(values.begin(), values.end(), delim); 290 } 291 292 /// Split a string into a list of strings. 293 /// @param s The string to split. 294 /// @param delim The delimiter used to separate the values. 295 /// @param[out] values A list of substrings from s, with delimiters discarded. 296 bool split(const string &s, const string &delim, list<string> *values); 297 298 /// Split a string into a list of integers. 299 /// @param s The string to split. 300 /// @param delim The delimiter used to separate the integers. 301 /// @param[out] values A list of integers from s. 302 bool split(const string &s, const string &delim, list<int> *values); 303 304 /// Get the modification timestamp for a file. 305 /// @param path The file path. 306 time_t FileModificationTime(const string &path); 307 308 /// Get random bytes from OpenSSL. 309 /// @param size The number of bytes to get. 310 /// @param[out] s A string in which to place the bytes. 311 bool WeakRandBytes(size_t size, string *s); 312 313 /// Encode string using web-safe base64w. No padding or newlines are added. This 314 /// function does not fail. 315 /// @param in The string to be encoded. May be emptystring. 316 string Base64WEncode(const string &in); 317 318 /// Encode string using web-safe base64w. No padding or newlines are added. 319 /// @param in The string to be encoded. May be emptystring. 320 /// @param[out] out A string to be overwritten with the result. 321 /// @return false if and only if out is nullptr. 322 bool Base64WEncode(const string &in, string *out); 323 324 /// Decode string using web-safe base64w. This function fails if padding, 325 /// newlines, or other unexpected characters are found in the input, or if the 326 /// input length is not valid. 327 /// @param in The string to be encoded. May be emptystring. 328 /// @param[out] out A string to be overwritten with the result. 329 bool Base64WDecode(const string &in, string *out); 330 331 /// Encode a key as a binary auth statement that can be parsed by the Go Tao 332 /// binary package in github.com/jlmucb/cloudproxy/tao/auth. Note that there is 333 /// no corresponding ParseSpeaksfor function, since this code exists only to 334 /// pass well-formed messages down to the Tao. 335 /// @param key The bytes of the key to authorize. 336 /// @param binaryTaoName The binary-marshaled principal name of the delegator. 337 /// @param[out] out The resulting binary-serialized auth.Speaksfor statement. 338 bool MarshalSpeaksfor(const string &key, const string &binaryTaoName, 339 string *out); 340 341 /// Encode a key as an auth.Prin of type "key". This uses the binary encoding 342 /// from the Go package github.com/jlmucb/cloudproxy/tao/auth 343 /// @param key The bytes of the key to write as an auth.Prin 344 /// @param[out] out The resulting binary-encoded auth.Prin. 345 bool MarshalKeyPrin(const string &key, string *out); 346 347 348 bool InitNewCounter(Tao *tao, const string &label, const int64_t& c); 349 bool GetACounter(Tao *tao, const string &label, const int64_t* c); 350 bool MakeRollbackProtectedSealedSecret(Tao *tao, const string &path, 351 const string &policy, int secret_size, string *secret); 352 bool GetRollbackProtectedSealedSecret(Tao *tao, const string &path, 353 const string &policy, string *secret); 354 355 } // namespace tao 356 357 #endif // TAO_UTIL_H_