📄 win32filestore.c
字号:
unsigned char *algId = (unsigned char *)0;
unsigned char *salt = (unsigned char *)0;
unsigned char *oldHmac = (unsigned char *)0;
unsigned char *newHmac = (unsigned char *)0;
unsigned char *passwordInfo = (unsigned char *)0;
unsigned char *password = (unsigned char *)0;
unsigned char *oldPassword = (unsigned char *)0;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* Initialize to "don't delete the password file".
*/
deletePasswordFile = 0;
do
{
/* If there is info, it must be a random object.
*/
if (info != (Pointer)0)
{
random = (VtRandomObject)info;
status = VT_ERROR_INVALID_ASSOCIATED_INFO;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
if (VOLT_OBJECT_TYPE_NOT_EQUAL (info, VOLT_OBJECT_TYPE_RANDOM))
break;
}
/* Make sure we have a password manager.
*/
PasswordManager = (VtPasswordManager)ctx->passwordCtx.PasswordFunction;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_STORAGE_CTX;
if (PasswordManager == (VtPasswordManager)0)
break;
/* Get the current password info and file handle.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltGetSaltAndHmacFromFile (
ctx, &iterationCount, &algId, &algIdLen, &salt, &saltLen,
&oldHmac, &oldHmacLen, &fileName, &fileHandle);
if (status != 0)
break;
/* Get a DigestImpl to be used to check the password. If the info
* was in the file, algId contains the algID. If not, algID is NULL
* and this function will use a default algorithm, allocate a new
* buffer, and set that buffer with the algID.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltGetDigestImpl (libCtx, &algId, &algIdLen, &DigestImpl);
if (status != 0)
break;
/* If there's no file, we're setting a new password.
*/
if (fileHandle == (VoltFileHandle)0)
{
/* Get the password we'll be using.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = PasswordManager (
(VtLibCtx)libCtx, ctx->passwordCtx.appData,
VT_PASSWORD_MGR_PURPOSE_SET, &oldPassword, &oldPasswordLen,
&password, &passwordLen);
if (status != 0)
break;
/* Create the file to hold the password info.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = fileCtx->CtxCreateDirectories (fileCtx, fileName);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = fileCtx->CtxOpenFile (
fileCtx, &fileHandle, fileName, VOLT_FILE_MODE_READ_OVERWRITE, 0);
if (status != 0)
break;
/* Build an empty salt buffer.
*/
saltLen = VOLT_EXTRA_PASS_SALT_LEN;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
salt = (unsigned char *)Z2Malloc (saltLen, 0);
if (salt == (unsigned char *)0)
break;
/* Set the iteration count.
*/
iterationCount = VOLT_EXTRA_PASS_ITERATION_COUNT;
oldPassword = (unsigned char *)0;
oldPasswordLen = 0;
}
else
{
/* If there is a file, there's an old password.
*/
purpose = VT_PASSWORD_MGR_PURPOSE_CHANGE;
do
{
/* Confirm that the old password is correct. First, get the
* passwords.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = PasswordManager (
(VtLibCtx)libCtx, ctx->passwordCtx.appData, purpose,
&oldPassword, &oldPasswordLen, &password, &passwordLen);
if (status != 0)
break;
/* If the callback returned an empty old password we know it's
* wrong. The password file is created only if there is a non
* empty password set. So we want to retry in that case.
*/
purpose = VT_PASSWORD_MGR_PURPOSE_CHANGE_RETRY;
if ( (oldPassword == (unsigned char *)0) || (oldPasswordLen == 0) )
continue;
/* Use newHmac as a temp variable.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = ComputePasswordHmacAlloc (
libCtx, random, VOLT_USE_SALT, DigestImpl,
oldPassword, oldPasswordLen, salt, saltLen, &newHmac, &newHmacLen);
if (status != 0)
break;
/* Is the passwordHmac that we just computed the same as the HMAC
* in the file? If so, we have the correct old password.
*/
cmpResult = Z2Memcmp (newHmac, oldHmac, newHmacLen);
Z2Free (newHmac);
newHmac = (unsigned char *)0;
if (cmpResult == 0)
break;
} while (1);
if (status != 0)
break;
}
/* At this point we have both the correct old password and the new
* password. If the new password is empty, it means the caller
* wants to clear any extra passwords set. So an empty password
* should be treated as no password instead of an empty password.
*/
if ( (password == (unsigned char *)0) || (passwordLen == 0) )
{
password = (unsigned char *)0;
passwordLen = 0;
}
/* We now need to re-encrypt all the appropriate files serviced by
* this storage provider with the new password.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltReEncryptFiles (
ctx, oldPassword, oldPasswordLen, password, passwordLen);
if (status != 0)
break;
/* If the new password is empty we need to delete the password file
* indicating that no password is set.
*/
if (passwordLen == 0)
{
deletePasswordFile = 1;
break;
}
/* Compute the password values for the new password.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = ComputePasswordHmacAlloc (
libCtx, random, VOLT_COMPUTE_SALT, DigestImpl, password, passwordLen,
salt, saltLen, &newHmac, &newHmacLen);
if (status != 0)
break;
/* Build the block of data that is the HMAC info stored in the file.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltBuildPasswordInfoAlloc (
libCtx, algId, algIdLen, iterationCount, salt, saltLen,
newHmac, newHmacLen, &passwordInfo, &passwordInfoLen);
if (status != 0)
break;
/* Store the password HMAC info in the file. This is the password
* file, so it does not take an extra password.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mIcStoreData (
ctx, passwordInfo, passwordInfoLen, (unsigned char *)0, 0,
fileCtx, fileHandle);
} while (0);
if (fileHandle != (VoltFileHandle)0)
{
fileCtx->CtxCloseFile (fileCtx, &fileHandle);
if (deletePasswordFile != 0)
fileCtx->CtxDeleteFile (fileCtx, (VoltFileHandle *)0, fileName);
}
if ( (password != (unsigned char *)0) ||
(oldPassword != (unsigned char *)0) )
{
PasswordManager (
(VtLibCtx)libCtx, ctx->passwordCtx.appData,
VT_PASSWORD_MGR_PURPOSE_RELEASE, &oldPassword, &oldPasswordLen,
&password, &passwordLen);
}
if (fileName != (unsigned char *)0)
Z2Free (fileName);
if (algId != (unsigned char *)0)
Z2Free (algId);
if (salt != (unsigned char *)0)
Z2Free (salt);
if (oldHmac != (unsigned char *)0)
Z2Free (oldHmac);
if (newHmac != (unsigned char *)0)
Z2Free (newHmac);
if (passwordInfo != (unsigned char *)0)
Z2Free (passwordInfo);
if (status == 0)
return status;
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, status, errorType, fnctLine,
"VoltWinSetExtraPassword", (char *)0)
return (status);
}
int VoltWinClientSetExtraPassword (
VtStorageCtx storageCtx,
Pointer info
)
{
int status;
unsigned int purpose, valueLen, passwordLen, oldPasswordLen, hmacLen, saltLen;
VoltStorageCtx *ctx = (VoltStorageCtx *)storageCtx;
VoltLibCtx *libCtx = (VoltLibCtx *)(ctx->voltObject.libraryCtx);
VoltDefaultStorageCtx *localCtx =
(VoltDefaultStorageCtx *)(ctx->localStorageCtx);
VtPasswordManager PasswordManager = (VtPasswordManager)0;
VtRandomObject random = (VtRandomObject)0;
unsigned char buffer[VOLT_EXTRA_PASS_SALT_LEN + VOLT_EXTRA_PASS_HMAC_LEN];
unsigned char oldHmac[VOLT_EXTRA_PASS_HMAC_LEN];
unsigned char *password = (unsigned char *)0;
unsigned char *oldPassword = (unsigned char *)0;
unsigned char *salt;
unsigned char *passwordHmac;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
salt = buffer;
passwordHmac = salt + VOLT_EXTRA_PASS_SALT_LEN;
saltLen = VOLT_EXTRA_PASS_SALT_LEN;
hmacLen = VOLT_EXTRA_PASS_HMAC_LEN;
do
{
/* If there is info, it must be a random object.
*/
if (info != (Pointer)0)
{
random = (VtRandomObject)info;
status = VT_ERROR_INVALID_ASSOCIATED_INFO;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
if (VOLT_OBJECT_TYPE_NOT_EQUAL (info, VOLT_OBJECT_TYPE_RANDOM))
break;
}
/* Make sure we have a password manager.
*/
PasswordManager = (VtPasswordManager)(ctx->passwordCtx.PasswordFunction);
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_STORAGE_CTX;
if (PasswordManager == (VtPasswordManager)0)
break;
/* Get the current password info and file handle.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltGetSaltAndHmacFromRegistry (ctx, buffer, &valueLen);
if (status != 0)
break;
/* If valueLen is 0, there's no current password, we're setting a
* new one.
*/
if (valueLen == 0)
{
/* Get the password we'll be using.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = PasswordManager (
(VtLibCtx)libCtx, ctx->passwordCtx.appData,
VT_PASSWORD_MGR_PURPOSE_SET, &oldPassword, &oldPasswordLen,
&password, &passwordLen);
if (status != 0)
break;
/* Make sure oldPassword is still NULL. When we later on
* re-encrypt, this variable has to be NULL so that we don't try
* to use an old password with existing data. It was originally
* NULL, but the password mgr might have reset it. The mgr should
* not have reset it, but we'll make sure it's NULL because we
* don't have control of the password mgr.
*/
oldPassword = (unsigned char *)0;
oldPasswordLen = 0;
}
else
{
/* If there is a old password info, there's an old password.
*/
purpose = VT_PASSWORD_MGR_PURPOSE_CHANGE;
do
{
/* Confirm that the old password is correct. First, get the
* passwords.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = PasswordManager (
(VtLibCtx)libCtx, ctx->passwordCtx.appData, purpose,
&oldPassword, &oldPasswordLen, &password, &passwordLen);
if (status != 0)
break;
/* If the callback returned an empty old password we know it's
* wrong. The password file is created only if there is a non
* empty password set. So we want to retry in that case.
*/
purpose = VT_PASSWORD_MGR_PURPOSE_CHANGE_RETRY;
if ( (oldPassword == (unsigned char *)0) || (oldPasswordLen == 0) )
continue;
VOLT_SET_FNCT_LINE (fnctLine)
status = ComputePasswordValuesClient (
libCtx, random, VOLT_USE_SALT, oldPassword, oldPasswordLen,
salt, oldHmac, &hmacLen);
if (status != 0)
break;
/* Is the passwordHmac that we just computed the same as the HMAC
* in the file? If so, we have the correct old password.
*/
if (Z2Memcmp (passwordHmac, oldHmac, hmacLen) == 0)
break;
} while (1);
if (status != 0)
break;
}
/* At this point we have both the correct old password and the new
* password. If the new password is empty, it means the caller
* wants to clear any extra passwords set. So an empty password
* should be treated as no password instead of an empty password.
*/
if ( (password == (unsigned char *)0) || (passwordLen == 0) )
{
password = (unsigned char *)0;
passwordLen = 0;
}
/* We now need to re-encrypt all the apprpriate files serviced by
* this storage provider with the new password.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_S
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -