Reactos
at master 228 lines 7.8 kB view raw
1/* 2 * Unit test suite for crypt32.dll's CryptProtectData/CryptUnprotectData 3 * 4 * Copyright 2005 Kees Cook <kees@outflux.net> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21#include <stdio.h> 22#include <stdarg.h> 23#include <windef.h> 24#include <winbase.h> 25#include <winerror.h> 26#include <wincrypt.h> 27 28#include "wine/test.h" 29 30static char secret[] = "I am a super secret string that no one can see!"; 31static char secret2[] = "I am a super secret string indescribable string"; 32static char key[] = "Wibble wibble wibble"; 33static BOOL protected = FALSE; /* if true, the unprotect tests can run */ 34static DATA_BLOB cipher; 35static DATA_BLOB cipher_entropy; 36static DATA_BLOB cipher_no_desc; 37 38static void test_cryptprotectdata(void) 39{ 40 LONG r; 41 DATA_BLOB plain; 42 DATA_BLOB entropy; 43 44 plain.pbData=(void*)secret; 45 plain.cbData=strlen(secret)+1; 46 47 entropy.pbData=(void*)key; 48 entropy.cbData=strlen(key)+1; 49 50 SetLastError(0xDEADBEEF); 51 protected = CryptProtectData(NULL, L"Ultra secret test message", NULL, NULL, NULL, 0, &cipher); 52 ok(!protected, "Encrypting without plain data source.\n"); 53 r = GetLastError(); 54 ok(r == ERROR_INVALID_PARAMETER, "Wrong (%lu) GetLastError seen\n",r); 55 56 SetLastError(0xDEADBEEF); 57 protected = CryptProtectData(&plain, L"Ultra secret test message", NULL, NULL, NULL, 0, NULL); 58 ok(!protected, "Encrypting without cipher destination.\n"); 59 r = GetLastError(); 60 ok(r == ERROR_INVALID_PARAMETER, "Wrong (%lu) GetLastError seen\n",r); 61 62 cipher.pbData=NULL; 63 cipher.cbData=0; 64 65 /* without entropy */ 66 SetLastError(0xDEADBEEF); 67 protected = CryptProtectData(&plain, L"Ultra secret test message", NULL, NULL, NULL, 0, &cipher); 68 ok(protected, "Encrypting without entropy.\n"); 69 if (protected) 70 { 71 r = GetLastError(); 72 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n",r); 73 } 74 75 cipher_entropy.pbData=NULL; 76 cipher_entropy.cbData=0; 77 78 /* with entropy */ 79 SetLastError(0xDEADBEEF); 80 protected = CryptProtectData(&plain, L"Ultra secret test message", &entropy, NULL, NULL, 0, &cipher_entropy); 81 ok(protected, "Encrypting with entropy.\n"); 82 83 cipher_no_desc.pbData=NULL; 84 cipher_no_desc.cbData=0; 85 86 /* with entropy but no description */ 87 plain.pbData=(void*)secret2; 88 plain.cbData=strlen(secret2)+1; 89 SetLastError(0xDEADBEEF); 90 protected = CryptProtectData(&plain,NULL,&entropy,NULL,NULL,0,&cipher_no_desc); 91 ok(protected, "Encrypting with entropy.\n"); 92} 93 94static void test_cryptunprotectdata(void) 95{ 96 LONG r; 97 DATA_BLOB plain; 98 DATA_BLOB entropy; 99 BOOL okay; 100 WCHAR * data_desc; 101 102 entropy.pbData=(void*)key; 103 entropy.cbData=strlen(key)+1; 104 105 plain.pbData=NULL; 106 plain.cbData=0; 107 108 SetLastError(0xDEADBEEF); 109 okay = CryptUnprotectData(&cipher,NULL,NULL,NULL,NULL,0,NULL); 110 ok(!okay,"Decrypting without destination\n"); 111 r = GetLastError(); 112 ok(r == ERROR_INVALID_PARAMETER, "Wrong (%lu) GetLastError seen\n",r); 113 114 SetLastError(0xDEADBEEF); 115 okay = CryptUnprotectData(NULL,NULL,NULL,NULL,NULL,0,&plain); 116 ok(!okay,"Decrypting without source\n"); 117 r = GetLastError(); 118 ok(r == ERROR_INVALID_PARAMETER, "Wrong (%lu) GetLastError seen\n",r); 119 120 plain.pbData=NULL; 121 plain.cbData=0; 122 123 SetLastError(0xDEADBEEF); 124 okay = CryptUnprotectData(&cipher_entropy,NULL,NULL,NULL,NULL,0,&plain); 125 ok(!okay,"Decrypting without needed entropy\n"); 126 r = GetLastError(); 127 ok(r == ERROR_INVALID_DATA, "Wrong (%lu) GetLastError seen\n", r); 128 129 plain.pbData=NULL; 130 plain.cbData=0; 131 data_desc=NULL; 132 133 /* without entropy */ 134 SetLastError(0xDEADBEEF); 135 okay = CryptUnprotectData(&cipher,&data_desc,NULL,NULL,NULL,0,&plain); 136 ok(okay,"Decrypting without entropy\n"); 137 138 ok(plain.pbData!=NULL,"Plain DATA_BLOB missing data\n"); 139 ok(plain.cbData==strlen(secret)+1,"Plain DATA_BLOB wrong length\n"); 140 ok(!strcmp((const char*)plain.pbData,secret),"Plain does not match secret\n"); 141 ok(data_desc!=NULL,"Description not allocated\n"); 142 ok(!lstrcmpW(data_desc, L"Ultra secret test message"),"Description does not match\n"); 143 144 LocalFree(plain.pbData); 145 LocalFree(data_desc); 146 147 plain.pbData=NULL; 148 plain.cbData=0; 149 data_desc=NULL; 150 151 /* with wrong entropy */ 152 SetLastError(0xDEADBEEF); 153 okay = CryptUnprotectData(&cipher_entropy,&data_desc,&cipher_entropy,NULL,NULL,0,&plain); 154 ok(!okay,"Decrypting with wrong entropy\n"); 155 r = GetLastError(); 156 ok(r == ERROR_INVALID_DATA, "Wrong (%lu) GetLastError seen\n",r); 157 158 /* with entropy */ 159 SetLastError(0xDEADBEEF); 160 okay = CryptUnprotectData(&cipher_entropy,&data_desc,&entropy,NULL,NULL,0,&plain); 161 ok(okay,"Decrypting with entropy\n"); 162 163 ok(plain.pbData!=NULL,"Plain DATA_BLOB missing data\n"); 164 ok(plain.cbData==strlen(secret)+1,"Plain DATA_BLOB wrong length\n"); 165 ok(!strcmp((const char*)plain.pbData,secret),"Plain does not match secret\n"); 166 ok(data_desc!=NULL,"Description not allocated\n"); 167 ok(!lstrcmpW(data_desc, L"Ultra secret test message"),"Description does not match\n"); 168 169 LocalFree(plain.pbData); 170 LocalFree(data_desc); 171 172 plain.pbData=NULL; 173 plain.cbData=0; 174 data_desc=NULL; 175 176 /* with entropy but no description */ 177 SetLastError(0xDEADBEEF); 178 okay = CryptUnprotectData(&cipher_no_desc,&data_desc,&entropy,NULL,NULL,0,&plain); 179 ok(okay,"Decrypting with entropy and no description\n"); 180 181 ok(plain.pbData!=NULL,"Plain DATA_BLOB missing data\n"); 182 ok(plain.cbData==strlen(secret2)+1,"Plain DATA_BLOB wrong length\n"); 183 ok(!strcmp((const char*)plain.pbData,secret2),"Plain does not match secret\n"); 184 ok(data_desc!=NULL,"Description not allocated\n"); 185 ok(data_desc[0]=='\0',"Description not empty\n"); 186 187 LocalFree(data_desc); 188 LocalFree(plain.pbData); 189 190 plain.pbData=NULL; 191 plain.cbData=0; 192} 193 194static void test_simpleroundtrip(const char *plaintext) 195{ 196 DATA_BLOB input; 197 DATA_BLOB encrypted; 198 DATA_BLOB output; 199 int res; 200 WCHAR emptyW[1]; 201 202 emptyW[0] = 0; 203 input.pbData = (unsigned char *)plaintext; 204 input.cbData = strlen(plaintext); 205 res = CryptProtectData(&input, emptyW, NULL, NULL, NULL, 0, &encrypted); 206 ok(res != 0, "can't protect\n"); 207 208 res = CryptUnprotectData(&encrypted, NULL, NULL, NULL, NULL, 0, &output); 209 ok(res != 0, "can't unprotect; last error %lu\n", GetLastError()); 210 ok(output.cbData == strlen(plaintext), "output wrong length %ld for input '%s', wanted %d\n", output.cbData, plaintext, lstrlenA(plaintext)); 211 ok(!memcmp(plaintext, (char *)output.pbData, output.cbData), "output wrong contents for input '%s'\n", plaintext); 212 LocalFree(output.pbData); 213 LocalFree(encrypted.pbData); 214} 215 216START_TEST(protectdata) 217{ 218 protected = FALSE; 219 test_cryptprotectdata(); 220 test_cryptunprotectdata(); 221 test_simpleroundtrip(""); 222 test_simpleroundtrip("hello"); 223 224 /* deinit globals here */ 225 if (cipher.pbData) LocalFree(cipher.pbData); 226 if (cipher_entropy.pbData) LocalFree(cipher_entropy.pbData); 227 if (cipher_no_desc.pbData) LocalFree(cipher_no_desc.pbData); 228}