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_