Sweden-Number/dlls/crypt32/protectdata.c

105 lines
4.0 KiB
C
Raw Normal View History

/*
* Copyright 2005 Kees Cook <kees@outflux.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* The Win32 CryptProtectData and CryptUnprotectData functions are meant
* to provide a mechanism for encrypting data on a machine where other users
* of the system can't be trusted. It is used in many examples as a way
* to store username and password information to the registry, but store
* it not in the clear.
*
* The encryption is symmetric, but the method is unknown. However, since
* it is keyed to the machine and the user, it is unlikely that the values
* would be portable. Since programs must first call CryptProtectData to
* get a cipher text, the underlying system doesn't have to exactly
* match the real Windows version. However, attempts have been made to
* at least try to look like the Windows version, including guesses at the
* purpose of various portions of the "opaque data blob" that is used.
*
*/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "winreg.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
#define CRYPT32_PROTECTDATA_PROV PROV_RSA_FULL
#define CRYPT32_PROTECTDATA_HASH_CALG CALG_MD5
#define CRYPT32_PROTECTDATA_KEY_CALG CALG_RC2
#define CRYPT32_PROTECTDATA_SALT_LEN 16
#define CRYPT32_PROTECTDATA_SECRET "I'm hunting wabbits"
/*
* The data format returned by the real Windows CryptProtectData seems
* to be something like this:
DWORD count0; - how many "info0_*[16]" blocks follow (was always 1)
BYTE info0_0[16]; - unknown information
...
DWORD count1; - how many "info1_*[16]" blocks follow (was always 1)
BYTE info1_0[16]; - unknown information
...
DWORD null0; - NULL "end of records"?
DWORD str_len; - length of WCHAR string including term
WCHAR str[str_len]; - The "dataDescription" value
DWORD unknown0; - unknown value (seems large, but only WORD large)
DWORD unknown1; - unknown value (seems small, less than a BYTE)
DWORD data_len; - length of data (was 16 in samples)
BYTE data[data_len]; - unknown data (fingerprint?)
DWORD null1; - NULL ?
DWORD unknown2; - unknown value (seems large, but only WORD large)
DWORD unknown3; - unknown value (seems small, less than a BYTE)
DWORD salt_len; - length of salt(?) data
BYTE salt[salt_len]; - salt(?) for symmetric encryption
DWORD cipher_len; - length of cipher(?) data - was close to plain len
BYTE cipher[cipher_len]; - cipher text?
DWORD crc_len; - length of fingerprint(?) data - was 20 byte==160b SHA1
BYTE crc[crc_len]; - fingerprint of record?
* The data structures used in Wine are modelled after this guess.
*/
struct protect_data_t
{
DWORD count0;
DATA_BLOB info0; /* using this to hold crypt_magic_str */
DWORD count1;
DATA_BLOB info1;
DWORD null0;
WCHAR * szDataDescr; /* serialized differently than the DATA_BLOBs */
DWORD unknown0; /* perhaps the HASH alg const should go here? */
DWORD unknown1;
DATA_BLOB data0;
DWORD null1;
DWORD unknown2; /* perhaps the KEY alg const should go here? */
DWORD unknown3;
DATA_BLOB salt;
DATA_BLOB cipher;
DATA_BLOB fingerprint;
};