## Problem

Encrypting a wallet through JSON RPC or Qt *appears to* allow a user to include null characters in the passphrase, but silently ignores everything including and after the first null character.

For instance (on regtest), trying to set a passphrase of "`a{null character}b`":

`curl --user __cookie__ --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "encryptwallet", "params": ["a\u0000b"]}' -H 'content-type: text/plain;' http://127.0.0.1:18443/`

This will succeed, but allow the user to unlock with the passphrase "`a`", instead of the expected full passphrase (which also works):

`curl --user __cookie__ --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "walletpassphrase", "params": ["a",10]}' -H 'content-type: text/plain;' http://127.0.0.1:18443/`

I am also able to replicate it in Qt on my macOS machine by running `printf 'a\0b' | pbcopy` and pasting the result into the passphrase dialog. 

My main concern is a user thinking that they're generating, say, 32 random bytes as a passphrase, and if they're unlucky and get a zero in the first few bytes, it unexpectedly cuts their security down to almost nothing. 

## Root Cause

The reason is due to our `SecureString` type. `SecureString` is a `std::string` specialization with a secure allocator. However, when assigned, it's treated like a C- string (no explicit length and null-terminated). See the [original PR](https://github.com/bitcoin/bitcoin/pull/666) for more details.

## Potential Solutions

I think there are two plausible approaches to take. The first (and my preference) is to allow and support null characters, and I will submit a PR that enables that (by making `SecureString` use the entire string). The second is to explicitly reject any passphrases that contain null characters.

One significant complication may be that, if anyone is *already* using a passphrase with a null, then my first solution would stop their wallet from unlocking. However, it would still be unlockable just by trimming the null and any subsequent characters.
secure_allocator(const secure_allocator& a) noexcept : base(a) {}
    template <typename U>
    secure_allocator(const secure_allocator<U>& a) noexcept : base(a)
    {
    }
    ~secure_allocator() noexcept {}
    template <typename _Other>
    struct rebind {
        typedef secure_allocator<_Other> other;
    };
    T* allocate(std::size_t n, const void* hint = nullptr)
    {
        T* allocation = static_cast<T*>(LockedPoolManager::Instance().alloc(sizeof(T) * n));
        if (!allocation) {
            throw std::bad_alloc();
        }
        return allocation;
    }
    void deallocate(T* p, std::size_t n)
    {
        if (p != nullptr) {
            memory_cleanse(p, sizeof(T) * n);
        }
        LockedPoolManager::Instance().free(p);
    }
};
typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
#endif