Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secure Cell passphrase API: ThemisPP #588

Merged
merged 10 commits into from
Feb 27, 2020
Merged

Commits on Feb 12, 2020

  1. themispp::impl::input_buffer utility

    This is how you say "AsRef<[u8]>" in C++. Yes, really.
    
    We are going to use this bunch of templates to accept anything that
    can be converted into a byte slice in new Secure Cell interface.
    
    Public interface:
    
    - themispp::input_buffer() templates
    
    Application code is allowed to invoke these freely. They are resilient
    to silly values, but until C++20 it is impossible to detect contiguous
    iterators reliably. Therefore is is technically possible to pass, say,
    std::deque<uint8_t> with inevitable probable segfault. Don't do that.
    (Thankfully, std::list and everything non-random-access is ruled out.)
    
    Private interface:
    
    - themispp::impl::input_buffer struct
    - themispp::impl::input_bytes() templates
    - themispp::impl::input_string() templates
    
    These functions are going to be used by ThemisPP internally. There are
    dummy identity conversion to handle themispp::input_buffer() results.
    String functions are used only by passphrase API constructors. They are
    not available to general users so that they don't pass std::string
    wherever they want.
    
    However, it is possible for users to provide specializations of all
    template functions in order to support their own custom containers.
    Tests provide an example of how this can be done.
    
    Note that the implementation is hidden in themispp::impl namespace
    which itself is mirrored in "themispp/impl" directory. This should
    prevent users from accidentally including and using these definitions.
    
    Also note the "compat" headers which are used to polyfill newer features
    of C++ when available. They are meant for internal use and should be
    used in pairs to avoid leaking magic macros to application code.
    ilammy committed Feb 12, 2020
    Configuration menu
    Copy the full SHA
    e138d5b View commit details
    Browse the repository at this point in the history
  2. themispp::impl::secret_bytes utility

    We are going to use this little class to store secret data inside
    Secure Cell. It is a wrapper over std::vector equipped with autowiping.
    The interface is restricted by design, limiting out own stupidity
    when coding ThemisPP.
    
    Use of soter_wipe() in ThemisPP in any form has a drawback: it makes
    application code dependent on Soter library directly. Previously only
    themispp::secure_rand_t (mostly unused) caused this, but now all new
    Secure Cell classes will trigger this. It's not an issue on Linux with
    its flat linker spaace, but virtually every other OS has nested linkage.
    ilammy committed Feb 12, 2020
    Configuration menu
    Copy the full SHA
    e3282fe View commit details
    Browse the repository at this point in the history
  3. themispp::secure_cell_seal API

    Implement Seal mode of Secure Cell, in both master key and passphrase
    flavors. The implementation is more or less straightforward, but there
    is one thing which must be commented. Initially I expected that
    allocator-aware templates can be placed directly into "themispp"
    namespace:
    
        auto cell = themispp::secure_cell_seal_with_passphrase("secret");
    
    However, it turned out that C++ grammar requires (until C++17) the
    template brackets to be present at all times, even if all template
    arguments can be inferred. This results in silly-looking:
    
        auto cell = themispp::secure_cell_seal_with_passphrase<>("secret");
    
    As a result, the actual implementation goes into "impl" subnamespace and
    proper name is reexported via a typedef. Well... it's C++, what can I do?
    Assuming that we do want to keep allocator awareness.
    
    New implementation gets a bunch of new test which verify both API and
    some behavior. In particular, they can be somewhat of a usage guide now.
    Though, they are still very much incomplete.
    
    Note that some tests are templated over "master key"/"passphrase" type.
    I really don't want to duplicate this code (it's enough KLOC here) *and*
    this ensures that both Secure Cell flavors have identical API. Win-win.
    (Actual implementation could be templated too, but that does not save
    much lines of code while making the implementation *much* more complex.)
    
    Also note a whole lot of "// NOLINT" comments. If we were not bound by
    C++03 compatibility we could have used modern alternatives, but C++03
    makes it hard to write code that compiles with every standard so we use
    the greatest common denominator. Hence we need clang-tidy to shut up.
    ilammy committed Feb 12, 2020
    Configuration menu
    Copy the full SHA
    670d64e View commit details
    Browse the repository at this point in the history
  4. themispp::secure_cell_context_imprint API

    This one is easy to do: there are no overloads, simple API, there will
    never be a passphrase API for Context Imprint. So it's mostly copy-paste
    of the Seal mode. Just pay attention to the argument order in Core API.
    It's slightly different for Context Imprint mode.
    
    Since Context Imprint mode does not verify message validity, there is
    not much that we can verify in tests. But at least we check the GIGO
    behavior.
    ilammy committed Feb 12, 2020
    Configuration menu
    Copy the full SHA
    689d64d View commit details
    Browse the repository at this point in the history
  5. themispp::secure_cell_token_protect API

    Ah! Token Protect API! The foster child of APIs in Themis which usually
    does not get enough attention and ends up as a second-class citizen.
    ThemisPP has specially obnoxious API for it, which is unique across all
    Themis wrappers. Well, not anymore.
    
    Instead of doing all that "set_token()"/"get_token()" we now return the
    encryption results as std::pair (with a couple of better accessors
    bolted onto it). This also gives us nice destructuring API which has
    finally arrived in C++17.
    
    Other than that, the implementation is pretty unremarkable. Mind the
    argument order and you'll be fine.
    
    The tests are templatized like Seal mode to make it easier to add
    passphrase support later. Note that we very message and token
    separately.
    ilammy committed Feb 12, 2020
    Configuration menu
    Copy the full SHA
    a087c49 View commit details
    Browse the repository at this point in the history
  6. Mark old Secure Cell API deprecated

    Yes, placement of attributes is... questionable but that's how you do it
    in C++. Don't ask me, I have no clue and don't want to know. There is
    probably a 75-page paper in C++ committee proceedings which explains in
    great detail why it must be done this way and absolutely cannot be done
    in a different, more sane way.
    
    clang-format does not make it look pretty either. Oh well... At least
    this code looks ugly and *definitely* deprecated.
    ilammy committed Feb 12, 2020
    Configuration menu
    Copy the full SHA
    b23c8c6 View commit details
    Browse the repository at this point in the history
  7. Update clang-format rules

    - Autodetect C++ standard version to prevent clang-format from fixing
      "> >" into ">>" in template usage like "foo<bar = <baz> >" which
      does not parse correctly in C++03
    ilammy committed Feb 12, 2020
    Configuration menu
    Copy the full SHA
    9cd1d2f View commit details
    Browse the repository at this point in the history
  8. Note new API in changelog

    ilammy committed Feb 12, 2020
    Configuration menu
    Copy the full SHA
    7cb57fa View commit details
    Browse the repository at this point in the history
  9. Use wording "key" with old master key API

    Replace whatever we were calling 'passwords' with something that looks
    like a key and is named like one.
    ilammy committed Feb 12, 2020
    Configuration menu
    Copy the full SHA
    228eb8f View commit details
    Browse the repository at this point in the history
  10. Use passphrase API in example project

    Well... project... The code style here leaves much to be desired, but
    I'm not going to fix it up right now. Just update it to use the latest
    API which is appropriate here.
    ilammy committed Feb 12, 2020
    Configuration menu
    Copy the full SHA
    353491e View commit details
    Browse the repository at this point in the history