📄 macosxfilestore.c
字号:
/* Copyright 2003-2005, Voltage Security, all rights reserved. * Encryption code adapted from Apple's libCdsaCrypt, version 1.0d1 */#if VOLT_OS == VOLT_MACOSX#include <Security/cssm.h>#define VOLT_UINT64 1#define VOLT_UINT32 1#include <errno.h>#include "vibe.h"#include "environment.h"#include "base.h"#include "libctx.h"#include "vsstore.h"#include "voltfile.h"#include "defaultstore.h"#include "errorctx.h"#include "stringutil.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <dirent.h>#pragma mark ------ Toolkit AES encrypt/decrypt functions ------static const unsigned int ivLen = 16; // length of the IV, in bytesint createAlgObjectAndKey(VoltLibCtx *libCtx, VtAlgorithmObject *algObj, VtKeyObject *keyObj, VtItem *keyData, VtItem *ivData){ VtBlockCipherInfo blockCipherInfo; // Keychain Services variables const char *serviceName = "Voltage SecureMail Secure Storage"; const UInt32 serviceNameLen = strlen(serviceName) + 1; const char *accountName = "Voltage SecureMail"; const UInt32 accountNameLen = strlen(accountName) + 1; OSErr err; int status; do { blockCipherInfo.cipherInfo = (Pointer)0; blockCipherInfo.feedback = VtFeedbackCBC; blockCipherInfo.feedbackInfo = (Pointer)ivData; blockCipherInfo.padding = VtPaddingPkcs5; blockCipherInfo.paddingInfo = (Pointer)0; status = VtCreateAlgorithmObject(libCtx, VtAlgorithmImplAES, (Pointer)&blockCipherInfo, algObj); if (status != 0) break; status = VtCreateKeyObject (libCtx, VtKeyImplDefault, (Pointer)0, keyObj); if (status != 0) break; // Try to get the key data from Keychain Services err = SecKeychainFindGenericPassword(NULL, serviceNameLen, serviceName, accountNameLen, accountName, &keyData->len, &keyData->data, NULL); // If call was not successful, set status to VT_ERROR_INVALID_STORAGE_CTX and break if (err != noErr) { status = VT_ERROR_INVALID_STORAGE_CTX; break; } status = VtSetKeyParam (*keyObj, VtKeyParamAES, (Pointer)keyData); if (status != 0) break; } while(0); return status;}int toolkitEncryptAlloc(VoltLibCtx *libCtx, unsigned char *data, unsigned int dataLen, unsigned char **encryptedData, unsigned int *encryptedDataLen){ VtRandomObject random = (VtRandomObject)0; VtAlgorithmObject encryptor = (VtAlgorithmObject)0; VtKeyObject aesKey = (VtKeyObject)0; VtItem keyData; VtItem ivData; unsigned char *dataWithPrefix = (unsigned char *)0; unsigned int dataWithPrefixLen = 0; unsigned int bufferSize; // Prefix variables const char *verifyPrefix = "VoltageStore0"; const int verifyPrefixLen = strlen(verifyPrefix); int status; do { status = VtGetLibCtxParam (libCtx, VtLibCtxParamRandomObj, (Pointer *)&random); if (status != 0) break; status = VtMalloc(libCtx, ivLen, 0, &ivData.data); if(status != 0) break; ivData.len = ivLen; status = VtGenerateRandomBytes (random, ivData.data, ivLen); if (status != 0) break; createAlgObjectAndKey(libCtx, &encryptor, &aesKey, &keyData, &ivData); // Prepare the data by appending a set prefix at the beginning for validity checking on decrypt // Allocate a buffer to hold the new data, with the prefix. dataWithPrefixLen = verifyPrefixLen + dataLen; status = VtMalloc (libCtx, dataWithPrefixLen, VT_MEMORY_SENSITIVE, (Pointer *)&dataWithPrefix); if (status != 0) break; memcpy(dataWithPrefix, verifyPrefix, verifyPrefixLen); memcpy(dataWithPrefix + verifyPrefixLen, data, dataLen); // Perform the actual encryption status = VtEncryptInit (encryptor, aesKey); if (status != 0) break; status = VtEncryptFinal (encryptor, (VtRandomObject)0, dataWithPrefix, dataWithPrefixLen, (unsigned char *)0, 0, &bufferSize); if (status == 0) status = VT_ERROR_GENERAL; if (status != VT_ERROR_BUFFER_TOO_SMALL) break; // Allocate enough space for the encrypted data, prefixed with the IV data status = VtMalloc (libCtx, bufferSize + ivLen, VT_MEMORY_SENSITIVE, (Pointer *)encryptedData); if (status != 0) break; // Write out the IV data as the first ivLen bytes memcpy(*encryptedData, ivData.data, ivLen); status = VtEncryptFinal (encryptor, (VtRandomObject)0, dataWithPrefix, dataWithPrefixLen, (*encryptedData) + ivLen, bufferSize, encryptedDataLen); if (status != 0) break; // Make sure we account for the bytes we added at the beginning *encryptedDataLen += ivLen; } while(0); VtFree (libCtx, (Pointer *)&ivData.data); VtFree (libCtx, (Pointer *)&dataWithPrefix); VtDestroyAlgorithmObject (&encryptor); SecKeychainItemFreeContent (NULL, keyData.data); VtDestroyKeyObject (&aesKey); return (status); }int toolkitDecryptAlloc(VoltLibCtx *libCtx, unsigned char *data, unsigned int dataLen, unsigned char **decryptedData, unsigned int *decryptedDataLen){ VtAlgorithmObject decryptor = (VtAlgorithmObject)0; VtKeyObject aesKey = (VtKeyObject)0; VtItem keyData; VtItem ivData; unsigned char *decryptedDataWithPrefix = (unsigned char *)0; unsigned int decryptedDataWithPrefixLen; unsigned int bufferSize; // Prefix variables const char *verifyPrefix = "VoltageStore0"; const int verifyPrefixLen = strlen(verifyPrefix); int status; do { // Expect the first ivLen bytes to be our ivData ivData.data = data; ivData.len = ivLen; // Update data and dataLen data = data + ivLen; dataLen -= ivLen; status = createAlgObjectAndKey(libCtx, &decryptor, &aesKey, &keyData, &ivData); if (status != 0) break; status = VtDecryptInit (decryptor, aesKey); if (status != 0) break; status = VtDecryptFinal (decryptor, (VtRandomObject)0, data, dataLen, (unsigned char *)0, 0, &bufferSize); if (status == 0) status = VT_ERROR_GENERAL; if (status != VT_ERROR_BUFFER_TOO_SMALL) break; status = VtMalloc (libCtx, bufferSize, VT_MEMORY_SENSITIVE, (Pointer *)&decryptedDataWithPrefix); if (status != 0) break; status = VtDecryptFinal (decryptor, (VtRandomObject)0, data, dataLen, decryptedDataWithPrefix, bufferSize, &decryptedDataWithPrefixLen); if (status != 0) break; // Check to see if we have the prefix we expect - if so, drop it and copy to final buffer; error if not. if(memcmp(verifyPrefix, decryptedDataWithPrefix, verifyPrefixLen) == 0) { bufferSize = decryptedDataWithPrefixLen - verifyPrefixLen; status = VtMalloc (libCtx, bufferSize, VT_MEMORY_SENSITIVE, (Pointer *)decryptedData); if (status != 0) break; memcpy(*decryptedData, decryptedDataWithPrefix + verifyPrefixLen, bufferSize); *decryptedDataLen = bufferSize; } else { status = VT_ERROR_FILE_READ; break; } } while (0); VtFree (libCtx, (Pointer *)&decryptedDataWithPrefix); VtDestroyAlgorithmObject (&decryptor); SecKeychainItemFreeContent (NULL, keyData.data); VtDestroyKeyObject (&aesKey); return (status);}#pragma mark ------ Toolkit functions ------int mIcStoreData ( VoltStorageCtx *prov, unsigned char *data, unsigned int dataLen, unsigned char *extraPassword, unsigned int extraPasswordLen, VoltFileCtx *fileCtx, VoltFileHandle fileHandle ){ int status; VoltLibCtx *libCtx = (VoltLibCtx *)(prov->voltObject.libraryCtx); unsigned char *encryptedData = (unsigned char *)0; unsigned int encryptedDataLen = 0; do { status = toolkitEncryptAlloc(libCtx, data, dataLen, &encryptedData, &encryptedDataLen); if(status != 0) break; status = fileCtx->CtxWriteFile (fileCtx, fileHandle, encryptedData, encryptedDataLen); } while(0); VtFree(libCtx, (Pointer *)&encryptedData); return (status);}int mIcLoadDataAlloc ( VoltStorageCtx *prov, VoltFileCtx *fileCtx, VoltFileHandle fileHandle, unsigned char *extraPassword, unsigned int extraPassowrdLen, unsigned char **data, unsigned int *dataLen ){ int status; unsigned int contentsLen; VoltFileInt fileSize; VoltLibCtx *libCtx = (VoltLibCtx *)(prov->voltObject.libraryCtx); unsigned char *contents = (unsigned char *)0; VOLT_DECLARE_FNCT_LINE (fnctLine) VOLT_DECLARE_ERROR_TYPE (errorType) *data = (unsigned char *)0; *dataLen = 0; do { /* Get the data out of the file. * First, how big is the file? */ VOLT_SET_ERROR_TYPE (errorType, 0) VOLT_SET_FNCT_LINE (fnctLine) status = fileCtx->CtxGetFileSize ( fileCtx, fileHandle, (char *)0, &fileSize); if (status != 0) break; /* Allocate the buffer to hold the contents. */ VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY) VOLT_SET_FNCT_LINE (fnctLine) status = VT_ERROR_MEMORY; contents = (unsigned char *)Z2Malloc (fileSize, VOLT_MEMORY_SENSITIVE); if (contents == (unsigned char *)0) break; /* Get the data. */ VOLT_SET_ERROR_TYPE (errorType, 0) VOLT_SET_FNCT_LINE (fnctLine) status = fileCtx->CtxReadFile ( fileCtx, fileHandle, (unsigned int)fileSize, contents, &contentsLen); if (status != 0 && status != VT_ERROR_FILE_END_OF_FILE) break; /* Decrypt the data. */ VOLT_SET_ERROR_TYPE (errorType, 0) VOLT_SET_FNCT_LINE (fnctLine) status = toolkitDecryptAlloc(libCtx, contents, contentsLen, data, dataLen); if(status != 0) break; } while (0); /* Free the contents buffer. */ if (contents != (unsigned char *)0) Z2Free (contents); /*If no error, we're done. */ if (status == 0) return (0); /* Log the error */ VOLT_LOG_ERROR ((VtLibCtx)libCtx, status, errorType, fnctLine, "mIcLoadDataAlloc", (char *)0) return (status);}// ************************************************************#pragma mark -#pragma mark Unchanged from deffilestore.c// ************************************************************int getICDirectory ( VoltLibCtx *libCtx, unsigned char *buf, int bufLen );int VtStorageFileMacOSX ( VtStorageCtx storageCtx, Pointer info, unsigned int flag, int providerNum ){ int status; unsigned int pathNameLen, bufferSize, offset;#if VOLT_ALIGNMENT != 1 unsigned int pad;#endif VoltStorageCtx *ctx = (VoltStorageCtx *)storageCtx; VtLibCtx libraryCtx = ctx->voltObject.libraryCtx; VoltLibCtx *libCtx = (VoltLibCtx *)libraryCtx; unsigned char *buffer = (unsigned char *)0; unsigned char *pathName = (unsigned char *)0; VoltDefaultStorageCtx *localCtx = (VoltDefaultStorageCtx *) 0; VtFileCtx fCtx = (VtFileCtx)0; VtFileCtxUseInfo *fInfo = (VtFileCtxUseInfo *) 0; VOLT_DECLARE_FNCT_LINE (fnctLine) VOLT_DECLARE_ERROR_TYPE (errorType) do { /* Check the flag, it should be VOLT_STORAGE_CTX_SET_TYPE_FLAG. */ VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY) VOLT_SET_FNCT_LINE (fnctLine) status = VT_ERROR_INVALID_TYPE; if (flag != VOLT_STORAGE_CTX_SET_TYPE_FLAG) break; /* If the associated info is not NULL pointer, it should be a * VtFileCtxUseInfo pointer. */ pathName = (unsigned char *)0; pathNameLen = 0; if (info != (Pointer)0) { fInfo = (VtFileCtxUseInfo *) info; pathName = (unsigned char *)fInfo->path; pathNameLen = Z2Strlen (pathName); fCtx = fInfo->fileCtx; } /* If File Ctx has not been provided by the caller * Try to use one from the Lib Ctx. */ status = VT_ERROR_NO_FILE_CTX; if( fCtx == (VtFileCtx)0 ) { fCtx = (VtFileCtx)VoltGetLibCtxInfo ( (VtLibCtx)libCtx, VOLT_LIB_CTX_INFO_TYPE_FILE_CTX); /* If we still don't have a valid file ctx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -