SecretString.cpp 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. /*
  2. * Copyright (c) 2021, Brian Gianforcaro <bgianf@serenityos.org>
  3. * Copyright (c) 2021, Mustafa Quraish <mustafa@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/Memory.h>
  8. #include <LibCore/SecretString.h>
  9. namespace Core {
  10. ErrorOr<SecretString> SecretString::take_ownership(char*& cstring, size_t length)
  11. {
  12. auto buffer = TRY(ByteBuffer::copy(cstring, length));
  13. secure_zero(cstring, length);
  14. free(cstring);
  15. cstring = nullptr;
  16. return SecretString(move(buffer));
  17. }
  18. SecretString SecretString::take_ownership(ByteBuffer&& buffer)
  19. {
  20. return SecretString(move(buffer));
  21. }
  22. SecretString::SecretString(ByteBuffer&& buffer)
  23. : m_secure_buffer(move(buffer))
  24. {
  25. // SecretString is currently only used to provide the character data to invocations to crypt(),
  26. // which requires a NUL-terminated string. To ensure this operation avoids a buffer overrun,
  27. // append a NUL terminator here if there isn't already one.
  28. if (m_secure_buffer.is_empty() || (m_secure_buffer[m_secure_buffer.size() - 1] != 0)) {
  29. u8 nul = '\0';
  30. m_secure_buffer.append(&nul, 1);
  31. }
  32. }
  33. SecretString::~SecretString()
  34. {
  35. // Note: We use secure_zero to avoid the zeroing from being optimized out by the compiler,
  36. // which is possible if memset was to be used here.
  37. if (!m_secure_buffer.is_empty()) {
  38. secure_zero(m_secure_buffer.data(), m_secure_buffer.capacity());
  39. }
  40. }
  41. }