Serenity Operating System
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
8#include <AK/Memory.h>
9#include <LibCore/SecretString.h>
10
11namespace Core {
12
13ErrorOr<SecretString> SecretString::take_ownership(char*& cstring, size_t length)
14{
15 auto buffer = TRY(ByteBuffer::copy(cstring, length));
16
17 secure_zero(cstring, length);
18 free(cstring);
19 cstring = nullptr;
20
21 return SecretString(move(buffer));
22}
23
24SecretString SecretString::take_ownership(ByteBuffer&& buffer)
25{
26 return SecretString(move(buffer));
27}
28
29SecretString::SecretString(ByteBuffer&& buffer)
30 : m_secure_buffer(move(buffer))
31{
32 // SecretString is currently only used to provide the character data to invocations to crypt(),
33 // which requires a NUL-terminated string. To ensure this operation avoids a buffer overrun,
34 // append a NUL terminator here if there isn't already one.
35 if (m_secure_buffer.is_empty() || (m_secure_buffer[m_secure_buffer.size() - 1] != 0)) {
36 u8 nul = '\0';
37 m_secure_buffer.append(&nul, 1);
38 }
39}
40
41SecretString::~SecretString()
42{
43 // Note: We use secure_zero to avoid the zeroing from being optimized out by the compiler,
44 // which is possible if memset was to be used here.
45 if (!m_secure_buffer.is_empty()) {
46 secure_zero(m_secure_buffer.data(), m_secure_buffer.capacity());
47 }
48}
49
50}