diff options
Diffstat (limited to 'src/VBox/Main/src-all/HashedPw.cpp')
-rw-r--r-- | src/VBox/Main/src-all/HashedPw.cpp | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/VBox/Main/src-all/HashedPw.cpp b/src/VBox/Main/src-all/HashedPw.cpp new file mode 100644 index 00000000..a1c601c1 --- /dev/null +++ b/src/VBox/Main/src-all/HashedPw.cpp @@ -0,0 +1,114 @@ +/* $Id: HashedPw.cpp $ */ +/** @file + * Main - Password Hashing + */ + +/* + * Copyright (C) 2012-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include "HashedPw.h" + +#include <iprt/assert.h> +#include <iprt/ctype.h> +#include <iprt/sha.h> +#include <iprt/string.h> + + +/********************************************************************************************************************************* +* Global Variables * +*********************************************************************************************************************************/ +/** + * The prefix of a hashed password. + */ +static const char s_szHashedPwPrefix[] = "#SHA-512#"; + + +/** + * Checks if the password is a hashed one or not. + * + * Empty password are not considered hashed. + * + * @returns true if hashed, false if not. + * @param a_pstrPassword Password to inspect. + */ +bool VBoxIsPasswordHashed(RTCString const *a_pstrPassword) +{ + /* prefix */ + if (!a_pstrPassword->startsWith(s_szHashedPwPrefix)) + return false; + + /* salt (optional) */ + const char *pszSalt = a_pstrPassword->c_str() + sizeof(s_szHashedPwPrefix) - 1; + const char *pszSaltEnd = strchr(pszSalt, '#'); + if (!pszSaltEnd) + return false; + while (pszSalt != pszSaltEnd) + { + if (!RT_C_IS_XDIGIT(*pszSalt)) + return false; + pszSalt++; + } + + /* hash */ + uint8_t abHash[RTSHA512_HASH_SIZE]; + int vrc = RTSha512FromString(pszSaltEnd + 1, abHash); + return RT_SUCCESS(vrc); +} + + +/** + * Hashes a plain text password. + * + * @param a_pstrPassword Plain text password to hash. This is both + * input and output. + */ +void VBoxHashPassword(RTCString *a_pstrPassword) +{ + AssertReturnVoid(!VBoxIsPasswordHashed(a_pstrPassword)); + + char szHashedPw[sizeof(s_szHashedPwPrefix) + 1 + RTSHA512_DIGEST_LEN]; + if (a_pstrPassword->isEmpty()) + szHashedPw[0] = '\0'; + else + { + /* prefix */ + char *pszHashedPw = szHashedPw; + strcpy(pszHashedPw, s_szHashedPwPrefix); + pszHashedPw += sizeof(s_szHashedPwPrefix) - 1; + + /* salt */ + *pszHashedPw++ = '#'; /* no salt yet */ + + /* hash */ + uint8_t abHash[RTSHA512_HASH_SIZE]; + RTSha512(a_pstrPassword->c_str(), a_pstrPassword->length(), abHash); + int vrc = RTSha512ToString(abHash, pszHashedPw, sizeof(szHashedPw) - (size_t)(pszHashedPw - &szHashedPw[0])); + AssertReleaseRC(vrc); + } + + *a_pstrPassword = szHashedPw; +} + |