Implement an mlock()'d string class for storing passphrases #666

pull nobled wants to merge 1 commits into bitcoin:master from nobled:secstrings changing 9 files +40 −54
  1. nobled commented at 6:41 AM on November 26, 2011: contributor

    This finishes a TODO comment: // TODO: mlock memory / munlock on return so they will not be swapped out, really need "mlockedstring" wrapper class to do this safely

    SecureString is identical to std::string except with secure_allocator
    substituting for std::allocator. This makes casting between them
    impossible, so converting between the two at API boundaries requires
    calling ::c_str() for now.
    

    The lack of implicit casting between the two was a big advantage in making this patch thorough, since the build would break if not all the prototypes were updated. So it should also be a 'feature' in making sure implicit casts (meaning gratuitous copies into non-locked memory) aren't accidentally introduced in the future.

    Passphrases are now only copied from non-locked memory in askpassphrasedialog.cpp (from Qt's QLineEdit / QString) and in bitcoinrpc.cpp (from whatever library is providing Array; I couldn't tell).

  2. Implement an mlock()'d string class for storing passphrases
    SecureString is identical to std::string except with secure_allocator
    substituting for std::allocator. This makes casting between them
    impossible, so converting between the two at API boundaries requires
    calling ::c_str() for now.
    94f778bdeb
  3. laanwj commented at 6:55 AM on November 26, 2011: member

    Improves security AND makes the code more readable, I like this.

    ACK.

  4. laanwj commented at 7:43 AM on November 26, 2011: member

    Using ::c_cstr at API boundaries does have the drawback that '\0' characters are not allowed -- the canonical form of converting between string types is to use data() and size(), or .begin()/.end(). Then again, I don't think you can enter those in form fields anyway :)

  5. TheBlueMatt commented at 7:27 PM on November 26, 2011: member

    Though it does make some code a bit easier to read, it is no more secure (in fact, with the additional conversions, one could argue its less secure, though not really). Anyway, meh.

  6. laanwj commented at 9:27 PM on November 26, 2011: member

    Less secure? How?

  7. TheBlueMatt commented at 9:33 PM on November 26, 2011: member

    .get_str().c_str() instead of .get_str() in several places means the string (likely) gets copied twice in memory instead of once.

  8. laanwj commented at 9:43 PM on November 26, 2011: member

    I really don't see how this could make things less secure.

    • By passing all the passphrases as SecureString all the way into the CWallet API, this makes sure the passphrases only exist in mlocked memory (except in Qt and inside the JSON parser, but that was already the case before, and in the case of Qt there is little to do against it). Before, they were passed in plain std::strings.
    • As I understand the conversions don't cause any extra allocation/deallocation of insecure memory, the conversions just pass memory around (and there's not that many more) from one mlocked area to another, which is filled with zeros before freeing.
    • By using a specific SecureString type it is signaled clearly that the data inside it should be handled with care.

    Sigh, seems that sometimes you just want to disagree with things for the sake of disagreeing... do you really like arguing that much?

  9. laanwj commented at 9:49 PM on November 26, 2011: member

    No, it does not copy anything (it can't, where would it copy to?). c_str() simply returns a pointer to the data inside the string.

  10. TheBlueMatt commented at 9:56 PM on November 26, 2011: member

    re: 1 yes, but those strings were previously mlocked, so no security is gained.

    re: 2 yes, that is my bad, I had just forgotten that those were returning pointers, not creating new objects...just my C++ inexperience showing...

  11. TheBlueMatt commented at 10:00 PM on November 26, 2011: member

    Let my rephrase my original comment: Makes code easier to read, but doesnt add security, probably worth pulling. Meh.

  12. laanwj commented at 10:01 PM on November 26, 2011: member
    1. In the case of bitcoin-qt they weren't. That was my reason for saying this is more secure.

    2. STL has a bad name from the MSVC 6.0 implementation, but luckily is not that inefficient :)

    Also this makes it harder to forget manually mlocking/munlocking (or maybe worse, skipping munlocking in the case of an exception so that memory stays locked indefinitely) in future usages of the API.

  13. gavinandresen referenced this in commit a7120a3647 on Dec 1, 2011
  14. gavinandresen merged this on Dec 1, 2011
  15. gavinandresen closed this on Dec 1, 2011

  16. coblee referenced this in commit e5b5b92e10 on Jul 17, 2012
  17. ptschip referenced this in commit 1c57c7b2ab on Jun 12, 2017
  18. Losangelosgenetics referenced this in commit 4aa4961366 on Mar 12, 2020
  19. DrahtBot locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-15 00:16 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me