📄 win32filestore.c
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "vsstore.h"
#include "voltfile.h"
#include "defaultstore.h"
#include "volti18n.h"
#include "derhelp.h"
#include "algid.h"
#include "errorctx.h"
#define VOLT_EXTRA_PASS_ITERATION_COUNT 32000
#define PASS_FILE_STRING (unsigned char *)"passwordfile"
#define PASS_FILE_STRING_LEN 12
#define VOLT_EXTRA_PASS_SALT_BIN_LEN 18
#define VOLT_EXTRA_PASS_SALT_LEN 24
#define VOLT_EXTRA_PASS_HMAC_LEN 28
#define VOLT_EXTRA_PASS_FILE_LEN 73
#define VOLT_EXTRA_PASS_REG_SIZE \
3*(VOLT_EXTRA_PASS_SALT_LEN+VOLT_EXTRA_PASS_HMAC_LEN)
#if VOLT_OS == VOLT_WINDOWS_32
#include <tchar.h>
/* Get the salt, iteration count, digest algorithm, and password HMAC
* from the appropriate file, or indicate there is no HMAC and salt.
* (Note that there is another routine that gets salt and HMAC from the
* registry).
* <p>If there is a file, the function will allocate buffers for the
* salt, algID, and HMAC. It is the responsibility of the caller to
* free those buffers. If there is no file, the function will not
* allocate buffers for these values and will return NULL pointers.
* <p>If there is a file containing the password info, the function
* will return the file handle at the address given by
* fileHandleReturn. (This function will not check the validity of the
* fileHandleReturn arg). Upon return, the file pointer was reset to
* the beginning of the file.
* <p>NOTE!!! It is the caller's responsibility to close the file.
* <p>If there is no file, the function will place no information into
* the salt buffer, not allocate any buffers, set fileHandleReturn
* to NULL, and will return 0.
* <p>Whether or not there is a file, the function will return the
* file name. It is either the name of the file that exists or the name
* of the file that should exist. The function will allocate the memory
* to hold the file name and place into that memory a NULL-terminated
* string. It is the responsibility of the caller to free the memory.
*
* @param ctx The storage ctx that contains all the info to find the
* file.
* @param iterationCount Where the function will deposit the iteration
* count.
* @param digestAlgId The address where the function will deposit the
* pointer to the allocated memory containing the algID of the digest.
* @param digestAlgIdLen Where the function will deposit the length, in
* bytes, of the digest alg ID.
* @param salt Where the function will deposit a pointer to the
* allocated space that contains the salt.
* @param saltLen Where the function will deposit the length of the
* salt.
* @param hmac Where the function will deposit a pointer to the
* allocated space that contains the HMAC.
* @param hmacLen Where the function will deposit the length of the
* HMAC.
* @param fileNameReturn The address where the function will deposit a
* pointer to a NULL-terminated string that is the file name.
* @param fileHandleReturn The address where the function will place
* the file handle of the file containing the salt and HMAC. If there
* is no file, the function will place NULL there.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV VoltGetSaltAndHmacFromFile VOLT_PROTO_LIST ((
VoltStorageCtx *ctx,
unsigned int *iterationCount,
unsigned char **digestAlgId,
unsigned int *digestAlgIdLen,
unsigned char **salt,
unsigned int *saltLen,
unsigned char **hmac,
unsigned int *hmacLen,
unsigned char **fileNameReturn,
VoltFileHandle *fileHandleReturn
));
/* Get the digest Impl based on the algID. If no algID is given, return
* a default Impl, allocate space to hold the algID of the default
* digest algorithm, and return that allocated space.
*
* @param libCtx
* @param algId The address where the function will either find the
* pointer to the existing algID, or deposit the pointer to the newly
* allocated memory holding the algID of the chosen algorithm.
* @param algIdLen The address where the function will either find the
* length, in bytes, of the existing algID, or deposit the length of
* the newly allocated memory holding the algID of the chosen algorithm.
* @param DigestImpl The address where the function will deposit the
* AlgorithmImpl for the digest algorithm represented by the algID.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV VoltGetDigestImpl VOLT_PROTO_LIST ((
VoltLibCtx *libCtx,
unsigned char **algId,
unsigned int *algIdLen,
VtAlgorithmImpl **DigestImpl
));
/* Build the DER encoding of the PasswordInfo.
*
* @param libCtx
* @param digestAlgId
* @param digestAlgIdLen
* @param iterationCount
* @param salt Buffer containing the salt.
* @param saltLen The length, in bytes, of the salt.
* @param hmac
* @param hmacLen
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV VoltBuildPasswordInfoAlloc VOLT_PROTO_LIST ((
VoltLibCtx *libCtx,
unsigned char *digestAlgId,
unsigned int digestAlgIdLen,
unsigned int iterationCount,
unsigned char *salt,
unsigned int saltLen,
unsigned char *hmac,
unsigned int hmacLen,
unsigned char **passwordInfo,
unsigned int *passwordInfoLen
));
/* Get the salt and password HMAC from the registry, or indicate there
* is no passworad and salt. (Note that there is another routine that
* gets the values from a file).
* <p>The salt is the Base64 encoding of 18 bytes of random data. The
* password HMAC is the Base64 encoding of the result of an HMAC with
* SHA-1.
* <p>The caller passes a buffer that is at least
* VOLT_EXTRA_PASS_SALT_LEN + VOLT_EXTRA_PASS_HMAC_LEN bytes big. This
* function does not check the validity of the buffer, it is the
* responsibility of the caller not to make a mistake.
* <p>The function will place the salt into the first
* VOLT_EXTRA_PASS_SALT_LEN bytes of the buffer and the password HMAC
* into the next VOLT_EXTRA_PASS_HMAC_LEN bytes of the buffer.
* <p>If there are registry entries containing the password info, the
* function will set the valueLen to the number of bytes placed into
* the buffer.
* <p>If there is no password info in the registry, the function will
* place no information into the buffer, set valueLen to 0, and will
* return 0.
*
* @param ctx The storage ctx that contains all the info to find the
* registry info.
* @param buffer The buffer into which the function will place the salt
* and HMAC.
* @param valueLen The address where the function will deposit the
* number of bytes placed into the buffer (0 means no info in the
* registry).
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV VoltGetSaltAndHmacFromRegistry VOLT_PROTO_LIST ((
VoltStorageCtx *ctx,
unsigned char *buffer,
unsigned int *valueLen
));
/* The buffer contains the salt and password HMAC. Store them in the
* registry.
* <p>The first VOLT_EXTRA_PASS_SALT_LEN bytes in the buffer are the
* salt bytes, the next VOLT_EXTRA_PASS_HMAC_LEN bytes are the password
* HMAC.
*
* @param ctx The storage ctx for which the password info is being
* stored.
* @param buffer Contains the data to store.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV VoltStoreSaltAndHmacInRegistry VOLT_PROTO_LIST ((
VoltStorageCtx *ctx,
unsigned char *buffer
));
/* Clear the Hmac value from the registry to indicate that no password is set.
* this doesn't affect the salt value.
* @param ctx The storage ctx for which the password info is being
* stored.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV VoltDeleteHmacFromRegistry VOLT_PROTO_LIST ((
VoltLibCtx *libCtx
));
/* Find all files encrypted using an old extra password, decrypt them,
* re-encrypt them using the new extra password, and store the
* newly-encrypted files.
* <p>If there is no old password (the oldPassword arg is NULL), just
* decrypt the files using the Windows protected storage and encrypt them
* using the new extra password.
*
* @param ctx The storage ctx that contains all the info to find the
* files.
* @param oldPassword If not NULL, the extra password to use to decrypt
* files.
* @param oldPasswordLen The length, in bytes, of the oldPassword.
* @param password The extra password to use to encrypt the files.
* @param passwordLen The length, in bytes, of the password.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV VoltReEncryptFiles VOLT_PROTO_LIST ((
VoltStorageCtx *ctx,
unsigned char *oldPassword,
unsigned int oldPasswordLen,
unsigned char *password,
unsigned int passwordLen
));
/* This is for client compatible storage
*/
static int VOLT_CALLING_CONV VoltReEncryptFilesClient VOLT_PROTO_LIST ((
VoltStorageCtx *ctx,
unsigned char *oldPassword,
unsigned int oldPasswordLen,
unsigned char *password,
unsigned int passwordLen
));
/* Implements VSetExtraPassword
*/
int VOLT_CALLING_CONV VoltWinSetExtraPassword VOLT_PROTO_LIST ((
VtStorageCtx storageCtx,
Pointer info
));
/* Implements VSetExtraPassword
*/
int VOLT_CALLING_CONV VoltWinClientSetExtraPassword VOLT_PROTO_LIST ((
VtStorageCtx storageCtx,
Pointer info
));
/* Compute the salt and then use the password and salt to compute the
* password HMAC. Or, if the salt is already computed, use the given
* salt and compute the password HMAC. This will compute the salt and
* HMAC following the method of the original client code.
* <p>The caller passes in a flag indicating whether the salt is
* computed or not. The flag is either VOLT_COMPUTE_SALT or
* VOLT_USE_SALT.
* <p>If the salt is not computed, the caller passes in a buffer big
* enough to hold the result (24 bytes). If the salt is computed, the
* caller passes in the actual salt. The salt is 24 bytes long, it is
* the Base64 encoding of a 18-byte random value. This function does
* not check an existing salt to make sure it is valid.
* <p>The caller passes in a passwordHmac buffer which must be (at
* least) 28 bytes long. The HMAC value is actually the Base64 of the
* HMAC with SHA-1 of the key, salt, password (the key is a fixed
* value).
*
* @param libCtx
* @param random
* @param flag Indicates whether the function should compute a new salt
* or use the material in the salt buffer as the salt.
* @param password The password used to compute the HMAC.
* @param passwordLen The length, in bytes, of the password (this does
* not include a NULL-terminating character).
* @param salt A buffer, either contains an existing salt, or where the
* computed salt will be placed.
* @param passwordHmac A buffer, where the computed HMAC will be placed.
* @param passwordHmacLen Points to size of buffer, result returned at
* address.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV ComputePasswordValuesClient VOLT_PROTO_LIST ((
VoltLibCtx *libCtx,
VtRandomObject random,
unsigned int flag,
unsigned char *password,
unsigned int passwordLen,
unsigned char *salt,
unsigned char *passwordHmac,
unsigned int *passwordHmacLen
));
/* Generate a random salt and use the password and salt to compute the
* password HMAC. Or, if the salt is already computed, use the given
* salt and password to compute the password HMAC. This will compute
* the HMAC following the "toolkit method".
* <p>The HMAC is acually HMAC with digest, the digest being variable.
* For now, we support only SHA-1.
* <p>The caller passes in a flag indicating whether the salt is
* computed or not. The flag is either VOLT_COMPUTE_SALT or
* VOLT_USE_SALT.
* <p>If the flag is COMPUTE_SALT, the caller passes in a buffer big
* enough to hold the result (saltLen bytes). If the flag is USE_SALT,
* the caller passes in the actual salt. The salt is s random value.
* This function does not check the validity of the salt args.
* <p>The caller must also pass in an algorithm object set to perform
* the digest desired.
* <p>The function will allocate the memory to hold the result, the
* caller must free the memory (hence the word Alloc in the name). The
* caller passes the address of a pointer, the function will go to that
* address and deposit a pointer to the allocated memory.
*
* @param libCtx
* @param random
* @param flag Indicates whether the function should compute a new salt
* or use the material in the salt buffer as the salt.
* @param DigestImpl An AlgorithmImpl to use to build the HMAC object
* (assume the associated info is NULL).
* @param password The password used to compute the HMAC.
* @param passwordLen The length, in bytes, of the password (this does
* not include a NULL-terminating character).
* @param salt A buffer, either contains an existing salt, or where the
* computed salt will be placed.
* @param saltLen The length of the salt (if it is in the buffer), or
* the length the salt should be.
* @param passwordHmac Where the function will deposit the pointer to
* the allocated memory holding the result.
* @param passwordHmacLen Where the function will deposit the length of
* the passwordHmac.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV ComputePasswordHmacAlloc VOLT_PROTO_LIST ((
VoltLibCtx *libCtx,
VtRandomObject random,
unsigned int flag,
VtAlgorithmImpl *DigestImpl,
unsigned char *password,
unsigned int passwordLen,
unsigned char *salt,
unsigned int saltLen,
unsigned char **passwordHmac,
unsigned int *passwordHmacLen
));
#define VOLT_COMPUTE_SALT 0
#define VOLT_USE_SALT 1
/* Check the directoryName, is it . or .. or a subdirecotry. The
* direcotry name will be in wide chars.
* <p>If the directoryName is . or .., set directoryLen to 0. If not,
* set directoryLen to the number of bytes that make up the name. Note
* that the number of bytes is not the number of characters. This count
* will NOT include any NULL-terminating characters.
*
* @param libCtx
* @param directoryName
* @param directoryLen The address where the function will deposit
* either a 0 (the directory is . or ..) or the number of bytes that
* make up the directory name.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV SubdirectoryQuery VOLT_PROTO_LIST ((
VoltLibCtx *libCtx,
unsigned char *directoryName,
unsigned int *directoryLen
));
/* Definitions of password info file contents.
*/
typedef struct
{
Asn1Encoded *digestAlgId;
ASN1_INTEGER *iterationCount;
ASN1_OCTET_STRING *salt;
ASN1_OCTET_STRING *hmac;
} Asn1PasswordInfoFileContents;
DECLARE_ASN1_FUNCTIONS (Asn1PasswordInfoFileContents)
ASN1_SEQUENCE (Asn1PasswordInfoFileContents) =
{
ASN1_SIMPLE (Asn1PasswordInfoFileContents, digestAlgId, Asn1Encoded),
ASN1_SIMPLE (Asn1PasswordInfoFileContents, iterationCount, ASN1_INTEGER),
ASN1_SIMPLE (Asn1PasswordInfoFileContents, salt, ASN1_OCTET_STRING),
ASN1_SIMPLE (Asn1PasswordInfoFileContents, hmac, ASN1_OCTET_STRING),
} ASN1_SEQUENCE_END (Asn1PasswordInfoFileContents);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -