1 /* 2 * Unit test suite for crypt32.dll's CryptStringToBinary and CryptBinaryToString 3 * functions. 4 * 5 * Copyright 2006 Juan Lang 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 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 30 #define CERT_HEADER "-----BEGIN CERTIFICATE-----\r\n" 31 #define ALT_CERT_HEADER "-----BEGIN This is some arbitrary text that goes on and on-----\r\n" 32 #define CERT_TRAILER "-----END CERTIFICATE-----\r\n" 33 #define ALT_CERT_TRAILER "-----END More arbitrary text------\r\n" 34 #define CERT_REQUEST_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----\r\n" 35 #define CERT_REQUEST_TRAILER "-----END NEW CERTIFICATE REQUEST-----\r\n" 36 #define X509_HEADER "-----BEGIN X509 CRL-----\r\n" 37 #define X509_TRAILER "-----END X509 CRL-----\r\n" 38 #define CERT_HEADER_NOCR "-----BEGIN CERTIFICATE-----\n" 39 #define CERT_TRAILER_NOCR "-----END CERTIFICATE-----\n" 40 #define CERT_REQUEST_HEADER_NOCR "-----BEGIN NEW CERTIFICATE REQUEST-----\n" 41 #define CERT_REQUEST_TRAILER_NOCR "-----END NEW CERTIFICATE REQUEST-----\n" 42 #define X509_HEADER_NOCR "-----BEGIN X509 CRL-----\n" 43 #define X509_TRAILER_NOCR "-----END X509 CRL-----\n" 44 45 struct BinTests 46 { 47 const BYTE *toEncode; 48 DWORD toEncodeLen; 49 const char *base64; 50 }; 51 52 static const BYTE toEncode1[] = { 0 }; 53 static const BYTE toEncode2[] = { 1,2 }; 54 /* static const BYTE toEncode3[] = { 1,2,3 }; */ 55 static const BYTE toEncode4[] = 56 "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" 57 "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" 58 "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890"; 59 60 static const struct BinTests tests[] = { 61 { toEncode1, sizeof(toEncode1), "AA==\r\n", }, 62 { toEncode2, sizeof(toEncode2), "AQI=\r\n", }, 63 /* { toEncode3, sizeof(toEncode3), "AQID\r\n", }, This test fails on Vista. */ 64 { toEncode4, sizeof(toEncode4), 65 "YWJjZGVmZ2hpamxrbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5MEFCQ0RFRkdISUpL\r\n" 66 "TE1OT1BRUlNUVVZXWFlaMDEyMzQ1Njc4OTBhYmNkZWZnaGlqbGttbm9wcXJzdHV2\r\n" 67 "d3h5ejAxMjM0NTY3ODkwQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2\r\n" 68 "Nzg5MGFiY2RlZmdoaWpsa21ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OTBBQkNERUZH\r\n" 69 "SElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY3ODkwAA==\r\n" }, 70 }; 71 72 static const struct BinTests testsNoCR[] = { 73 { toEncode1, sizeof(toEncode1), "AA==\n", }, 74 { toEncode2, sizeof(toEncode2), "AQI=\n", }, 75 /* { toEncode3, sizeof(toEncode3), "AQID\n", }, This test fails on Vista. */ 76 { toEncode4, sizeof(toEncode4), 77 "YWJjZGVmZ2hpamxrbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5MEFCQ0RFRkdISUpL\n" 78 "TE1OT1BRUlNUVVZXWFlaMDEyMzQ1Njc4OTBhYmNkZWZnaGlqbGttbm9wcXJzdHV2\n" 79 "d3h5ejAxMjM0NTY3ODkwQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2\n" 80 "Nzg5MGFiY2RlZmdoaWpsa21ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OTBBQkNERUZH\n" 81 "SElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY3ODkwAA==\n" }, 82 }; 83 84 static void encodeAndCompareBase64_A(const BYTE *toEncode, DWORD toEncodeLen, 85 DWORD format, const char *expected, const char *header, const char *trailer) 86 { 87 DWORD strLen = 0; 88 LPSTR str = NULL; 89 BOOL ret; 90 91 ret = CryptBinaryToStringA(toEncode, toEncodeLen, format, NULL, &strLen); 92 ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); 93 str = HeapAlloc(GetProcessHeap(), 0, strLen); 94 if (str) 95 { 96 DWORD strLen2 = strLen; 97 LPCSTR ptr = str; 98 99 ret = CryptBinaryToStringA(toEncode, toEncodeLen, format, str, 100 &strLen2); 101 ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); 102 ok(strLen2 == strLen - 1, "Expected length %d, got %d\n", 103 strLen - 1, strLen); 104 if (header) 105 { 106 ok(!strncmp(header, ptr, strlen(header)), 107 "Expected header %s, got %s\n", header, ptr); 108 ptr += strlen(header); 109 } 110 ok(!strncmp(expected, ptr, strlen(expected)), 111 "Expected %s, got %s\n", expected, ptr); 112 ptr += strlen(expected); 113 if (trailer) 114 ok(!strncmp(trailer, ptr, strlen(trailer)), 115 "Expected trailer %s, got %s\n", trailer, ptr); 116 HeapFree(GetProcessHeap(), 0, str); 117 } 118 } 119 120 static void testBinaryToStringA(void) 121 { 122 BOOL ret; 123 DWORD strLen = 0, i; 124 125 ret = CryptBinaryToStringA(NULL, 0, 0, NULL, NULL); 126 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 127 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 128 ret = CryptBinaryToStringA(NULL, 0, 0, NULL, &strLen); 129 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 130 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 131 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) 132 { 133 DWORD strLen = 0; 134 LPSTR str = NULL; 135 BOOL ret; 136 137 ret = CryptBinaryToStringA(tests[i].toEncode, tests[i].toEncodeLen, 138 CRYPT_STRING_BINARY, NULL, &strLen); 139 ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); 140 str = HeapAlloc(GetProcessHeap(), 0, strLen); 141 if (str) 142 { 143 DWORD strLen2 = strLen; 144 145 ret = CryptBinaryToStringA(tests[i].toEncode, tests[i].toEncodeLen, 146 CRYPT_STRING_BINARY, str, &strLen2); 147 ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); 148 ok(strLen == strLen2, "Expected length %d, got %d\n", strLen, 149 strLen2); 150 ok(!memcmp(str, tests[i].toEncode, tests[i].toEncodeLen), 151 "Unexpected value\n"); 152 HeapFree(GetProcessHeap(), 0, str); 153 } 154 encodeAndCompareBase64_A(tests[i].toEncode, tests[i].toEncodeLen, 155 CRYPT_STRING_BASE64, tests[i].base64, NULL, NULL); 156 encodeAndCompareBase64_A(tests[i].toEncode, tests[i].toEncodeLen, 157 CRYPT_STRING_BASE64HEADER, tests[i].base64, CERT_HEADER, 158 CERT_TRAILER); 159 encodeAndCompareBase64_A(tests[i].toEncode, tests[i].toEncodeLen, 160 CRYPT_STRING_BASE64REQUESTHEADER, tests[i].base64, 161 CERT_REQUEST_HEADER, CERT_REQUEST_TRAILER); 162 encodeAndCompareBase64_A(tests[i].toEncode, tests[i].toEncodeLen, 163 CRYPT_STRING_BASE64X509CRLHEADER, tests[i].base64, X509_HEADER, 164 X509_TRAILER); 165 } 166 for (i = 0; i < sizeof(testsNoCR) / sizeof(testsNoCR[0]); i++) 167 { 168 DWORD strLen = 0; 169 LPSTR str = NULL; 170 BOOL ret; 171 172 ret = CryptBinaryToStringA(testsNoCR[i].toEncode, 173 testsNoCR[i].toEncodeLen, CRYPT_STRING_BINARY | CRYPT_STRING_NOCR, 174 NULL, &strLen); 175 ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); 176 str = HeapAlloc(GetProcessHeap(), 0, strLen); 177 if (str) 178 { 179 DWORD strLen2 = strLen; 180 181 ret = CryptBinaryToStringA(testsNoCR[i].toEncode, 182 testsNoCR[i].toEncodeLen, CRYPT_STRING_BINARY | CRYPT_STRING_NOCR, 183 str, &strLen2); 184 ok(ret, "CryptBinaryToStringA failed: %d\n", GetLastError()); 185 ok(strLen == strLen2, "Expected length %d, got %d\n", strLen, 186 strLen2); 187 ok(!memcmp(str, testsNoCR[i].toEncode, testsNoCR[i].toEncodeLen), 188 "Unexpected value\n"); 189 HeapFree(GetProcessHeap(), 0, str); 190 } 191 encodeAndCompareBase64_A(testsNoCR[i].toEncode, 192 testsNoCR[i].toEncodeLen, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCR, 193 testsNoCR[i].base64, NULL, NULL); 194 encodeAndCompareBase64_A(testsNoCR[i].toEncode, 195 testsNoCR[i].toEncodeLen, 196 CRYPT_STRING_BASE64HEADER | CRYPT_STRING_NOCR, testsNoCR[i].base64, 197 CERT_HEADER_NOCR, CERT_TRAILER_NOCR); 198 encodeAndCompareBase64_A(testsNoCR[i].toEncode, 199 testsNoCR[i].toEncodeLen, 200 CRYPT_STRING_BASE64REQUESTHEADER | CRYPT_STRING_NOCR, 201 testsNoCR[i].base64, CERT_REQUEST_HEADER_NOCR, 202 CERT_REQUEST_TRAILER_NOCR); 203 encodeAndCompareBase64_A(testsNoCR[i].toEncode, 204 testsNoCR[i].toEncodeLen, 205 CRYPT_STRING_BASE64X509CRLHEADER | CRYPT_STRING_NOCR, 206 testsNoCR[i].base64, X509_HEADER_NOCR, X509_TRAILER_NOCR); 207 } 208 } 209 210 static void decodeAndCompareBase64_A(LPCSTR toDecode, LPCSTR header, 211 LPCSTR trailer, DWORD useFormat, DWORD expectedFormat, const BYTE *expected, 212 DWORD expectedLen) 213 { 214 static const char garbage[] = "garbage\r\n"; 215 LPSTR str; 216 DWORD len = strlen(toDecode) + strlen(garbage) + 1; 217 218 if (header) 219 len += strlen(header); 220 if (trailer) 221 len += strlen(trailer); 222 str = HeapAlloc(GetProcessHeap(), 0, len); 223 if (str) 224 { 225 LPBYTE buf; 226 DWORD bufLen = 0; 227 BOOL ret; 228 229 if (header) 230 strcpy(str, header); 231 else 232 *str = 0; 233 strcat(str, toDecode); 234 if (trailer) 235 strcat(str, trailer); 236 ret = CryptStringToBinaryA(str, 0, useFormat, NULL, &bufLen, NULL, 237 NULL); 238 ok(ret, "CryptStringToBinaryA failed: %d\n", GetLastError()); 239 buf = HeapAlloc(GetProcessHeap(), 0, bufLen); 240 if (buf) 241 { 242 DWORD skipped, usedFormat; 243 244 /* check as normal, make sure last two parameters are optional */ 245 ret = CryptStringToBinaryA(str, 0, useFormat, buf, &bufLen, NULL, 246 NULL); 247 ok(ret, "CryptStringToBinaryA failed: %d\n", GetLastError()); 248 ok(bufLen == expectedLen, 249 "Expected length %d, got %d\n", expectedLen, bufLen); 250 ok(!memcmp(buf, expected, bufLen), "Unexpected value\n"); 251 /* check last two params */ 252 ret = CryptStringToBinaryA(str, 0, useFormat, buf, &bufLen, 253 &skipped, &usedFormat); 254 ok(ret, "CryptStringToBinaryA failed: %d\n", GetLastError()); 255 ok(skipped == 0, "Expected skipped 0, got %d\n", skipped); 256 ok(usedFormat == expectedFormat, "Expected format %d, got %d\n", 257 expectedFormat, usedFormat); 258 HeapFree(GetProcessHeap(), 0, buf); 259 } 260 261 /* Check again, but with garbage up front */ 262 strcpy(str, garbage); 263 if (header) 264 strcat(str, header); 265 strcat(str, toDecode); 266 if (trailer) 267 strcat(str, trailer); 268 ret = CryptStringToBinaryA(str, 0, useFormat, NULL, &bufLen, NULL, 269 NULL); 270 /* expect failure with no header, and success with one */ 271 if (header) 272 ok(ret, "CryptStringToBinaryA failed: %d\n", GetLastError()); 273 else 274 ok(!ret && GetLastError() == ERROR_INVALID_DATA, 275 "Expected !ret and last error ERROR_INVALID_DATA, got ret=%d, error=%d\n", ret, GetLastError()); 276 if (ret) 277 { 278 buf = HeapAlloc(GetProcessHeap(), 0, bufLen); 279 if (buf) 280 { 281 DWORD skipped, usedFormat; 282 283 ret = CryptStringToBinaryA(str, 0, useFormat, buf, &bufLen, 284 &skipped, &usedFormat); 285 ok(ret, "CryptStringToBinaryA failed: %d\n", GetLastError()); 286 ok(skipped == strlen(garbage), 287 "Expected %d characters of \"%s\" skipped when trying format %08x, got %d (used format is %08x)\n", 288 lstrlenA(garbage), str, useFormat, skipped, usedFormat); 289 HeapFree(GetProcessHeap(), 0, buf); 290 } 291 } 292 HeapFree(GetProcessHeap(), 0, str); 293 } 294 } 295 296 static void decodeBase64WithLenFmtW(LPCSTR strA, int len, DWORD fmt, BOOL retA, 297 const BYTE *bufA, DWORD bufLenA, DWORD fmtUsedA) 298 { 299 BYTE buf[8] = {0}; 300 DWORD bufLen = sizeof(buf)-1, fmtUsed = 0xdeadbeef; 301 BOOL ret; 302 WCHAR strW[64]; 303 int i; 304 for (i = 0; (strW[i] = strA[i]) != 0; ++i); 305 ret = CryptStringToBinaryW(strW, len, fmt, buf, &bufLen, NULL, &fmtUsed); 306 ok(ret == retA && bufLen == bufLenA && memcmp(bufA, buf, bufLen) == 0 307 && fmtUsed == fmtUsedA, "base64 \"%s\" len %d: W and A differ\n", strA, len); 308 } 309 310 static void decodeBase64WithLenFmt(LPCSTR str, int len, DWORD fmt, LPCSTR expected, int le, BOOL isBroken) 311 { 312 BYTE buf[8] = {0}; 313 DWORD bufLen = sizeof(buf)-1, fmtUsed = 0xdeadbeef; 314 BOOL ret; 315 SetLastError(0xdeadbeef); 316 ret = CryptStringToBinaryA(str, len, fmt, buf, &bufLen, NULL, &fmtUsed); 317 buf[bufLen] = 0; 318 if (expected) { 319 BOOL correct = ret && strcmp(expected, (char*)buf) == 0; 320 ok(correct || (isBroken && broken(!ret)), 321 "base64 \"%s\" len %d: expected \"%s\", got \"%s\" (ret %d, le %d)\n", 322 str, len, expected, (char*)buf, ret, GetLastError()); 323 if (correct) 324 ok(fmtUsed == fmt, "base64 \"%s\" len %d: expected fmt %d, used %d\n", 325 str, len, fmt, fmtUsed); 326 } else { 327 ok(!ret && GetLastError() == le, 328 "base64 \"%s\" len %d: expected failure, got \"%s\" (ret %d, le %d)\n", 329 str, len, (char*)buf, ret, GetLastError()); 330 } 331 332 decodeBase64WithLenFmtW(str, len, fmt, ret, buf, bufLen, fmtUsed); 333 } 334 335 static void decodeBase64WithLenBroken(LPCSTR str, int len, LPCSTR expected, int le) 336 { 337 decodeBase64WithLenFmt(str, len, CRYPT_STRING_BASE64, expected, le, TRUE); 338 } 339 340 static void decodeBase64WithLen(LPCSTR str, int len, LPCSTR expected, int le) 341 { 342 decodeBase64WithLenFmt(str, len, CRYPT_STRING_BASE64, expected, le, FALSE); 343 } 344 345 static void decodeBase64WithFmt(LPCSTR str, DWORD fmt, LPCSTR expected, int le) 346 { 347 decodeBase64WithLenFmt(str, 0, fmt, expected, le, FALSE); 348 } 349 350 struct BadString 351 { 352 const char *str; 353 DWORD format; 354 }; 355 356 static const struct BadString badStrings[] = { 357 { "-----BEGIN X509 CRL-----\r\nAA==\r\n", CRYPT_STRING_BASE64X509CRLHEADER }, 358 }; 359 360 static void testStringToBinaryA(void) 361 { 362 BOOL ret; 363 DWORD bufLen = 0, i; 364 BYTE buf[8]; 365 366 ret = CryptStringToBinaryA(NULL, 0, 0, NULL, NULL, NULL, NULL); 367 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 368 "Expected ERROR_INVALID_PARAMETER, got ret=%d le=%u\n", ret, GetLastError()); 369 ret = CryptStringToBinaryA(NULL, 0, 0, NULL, &bufLen, NULL, NULL); 370 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 371 "Expected ERROR_INVALID_PARAMETER, got ret=%d le=%u\n", ret, GetLastError()); 372 /* Bogus format */ 373 ret = CryptStringToBinaryA(tests[0].base64, 0, 0, NULL, &bufLen, NULL, 374 NULL); 375 ok(!ret && GetLastError() == ERROR_INVALID_DATA, 376 "Expected ERROR_INVALID_DATA, got ret=%d le=%u\n", ret, GetLastError()); 377 /* Decoding doesn't expect the NOCR flag to be specified */ 378 ret = CryptStringToBinaryA(tests[0].base64, 1, 379 CRYPT_STRING_BASE64 | CRYPT_STRING_NOCR, NULL, &bufLen, NULL, NULL); 380 ok(!ret && GetLastError() == ERROR_INVALID_DATA, 381 "Expected ERROR_INVALID_DATA, got ret=%d le=%u\n", ret, GetLastError()); 382 /* Bad strings */ 383 for (i = 0; i < sizeof(badStrings) / sizeof(badStrings[0]); i++) 384 { 385 bufLen = 0; 386 ret = CryptStringToBinaryA(badStrings[i].str, 0, badStrings[i].format, 387 NULL, &bufLen, NULL, NULL); 388 ok(!ret && GetLastError() == ERROR_INVALID_DATA, 389 "%d: Expected ERROR_INVALID_DATA, got ret=%d le=%u\n", i, ret, GetLastError()); 390 } 391 /* Weird base64 strings (invalid padding, extra white-space etc.) */ 392 decodeBase64WithLen("V=", 0, 0, ERROR_INVALID_DATA); 393 decodeBase64WithLen("VV=", 0, 0, ERROR_INVALID_DATA); 394 decodeBase64WithLen("V==", 0, 0, ERROR_INVALID_DATA); 395 decodeBase64WithLen("V=", 2, 0, ERROR_INVALID_DATA); 396 decodeBase64WithLen("VV=", 3, 0, ERROR_INVALID_DATA); 397 decodeBase64WithLen("V==", 3, 0, ERROR_INVALID_DATA); 398 decodeBase64WithLenBroken("V", 0, "T", 0); 399 decodeBase64WithLenBroken("VV", 0, "U", 0); 400 decodeBase64WithLenBroken("VVV", 0, "UU", 0); 401 decodeBase64WithLen("V", 1, "T", 0); 402 decodeBase64WithLen("VV", 2, "U", 0); 403 decodeBase64WithLen("VVV", 3, "UU", 0); 404 decodeBase64WithLen("V===", 0, "T", 0); 405 decodeBase64WithLen("V========", 0, "T", 0); 406 decodeBase64WithLen("V===", 4, "T", 0); 407 decodeBase64WithLen("V\nVVV", 0, "UUU", 0); 408 decodeBase64WithLen("VV\nVV", 0, "UUU", 0); 409 decodeBase64WithLen("VVV\nV", 0, "UUU", 0); 410 decodeBase64WithLen("V\nVVV", 5, "UUU", 0); 411 decodeBase64WithLen("VV\nVV", 5, "UUU", 0); 412 decodeBase64WithLen("VVV\nV", 5, "UUU", 0); 413 decodeBase64WithLen("VV VV", 0, "UUU", 0); 414 decodeBase64WithLen("V===VVVV", 0, "T", 0); 415 decodeBase64WithLen("VV==VVVV", 0, "U", 0); 416 decodeBase64WithLen("VVV=VVVV", 0, "UU", 0); 417 decodeBase64WithLen("VVVV=VVVV", 0, "UUU", 0); 418 decodeBase64WithLen("V===VVVV", 8, "T", 0); 419 decodeBase64WithLen("VV==VVVV", 8, "U", 0); 420 decodeBase64WithLen("VVV=VVVV", 8, "UU", 0); 421 decodeBase64WithLen("VVVV=VVVV", 8, "UUU", 0); 422 423 decodeBase64WithFmt("-----BEGIN-----VVVV-----END-----", CRYPT_STRING_BASE64HEADER, 0, ERROR_INVALID_DATA); 424 decodeBase64WithFmt("-----BEGIN-----VVVV-----END -----", CRYPT_STRING_BASE64HEADER, 0, ERROR_INVALID_DATA); 425 decodeBase64WithFmt("-----BEGIN -----VVVV-----END-----", CRYPT_STRING_BASE64HEADER, 0, ERROR_INVALID_DATA); 426 decodeBase64WithFmt("-----BEGIN -----VVVV-----END -----", CRYPT_STRING_BASE64HEADER, "UUU", 0); 427 428 decodeBase64WithFmt("-----BEGIN -----V-----END -----", CRYPT_STRING_BASE64HEADER, "T", 0); 429 decodeBase64WithFmt("-----BEGIN foo-----V-----END -----", CRYPT_STRING_BASE64HEADER, "T", 0); 430 decodeBase64WithFmt("-----BEGIN foo-----V-----END foo-----", CRYPT_STRING_BASE64HEADER, "T", 0); 431 decodeBase64WithFmt("-----BEGIN -----V-----END foo-----", CRYPT_STRING_BASE64HEADER, "T", 0); 432 decodeBase64WithFmt("-----BEGIN -----V-----END -----", CRYPT_STRING_BASE64X509CRLHEADER, "T", 0); 433 decodeBase64WithFmt("-----BEGIN foo-----V-----END -----", CRYPT_STRING_BASE64X509CRLHEADER, "T", 0); 434 decodeBase64WithFmt("-----BEGIN foo-----V-----END foo-----", CRYPT_STRING_BASE64X509CRLHEADER, "T", 0); 435 decodeBase64WithFmt("-----BEGIN -----V-----END foo-----", CRYPT_STRING_BASE64X509CRLHEADER, "T", 0); 436 decodeBase64WithFmt("-----BEGIN -----V-----END -----", CRYPT_STRING_BASE64REQUESTHEADER, "T", 0); 437 decodeBase64WithFmt("-----BEGIN foo-----V-----END -----", CRYPT_STRING_BASE64REQUESTHEADER, "T", 0); 438 decodeBase64WithFmt("-----BEGIN foo-----V-----END foo-----", CRYPT_STRING_BASE64REQUESTHEADER, "T", 0); 439 decodeBase64WithFmt("-----BEGIN -----V-----END foo-----", CRYPT_STRING_BASE64REQUESTHEADER, "T", 0); 440 441 /* Too small buffer */ 442 buf[0] = 0; 443 bufLen = 4; 444 ret = CryptStringToBinaryA("VVVVVVVV", 8, CRYPT_STRING_BASE64, (BYTE*)buf, &bufLen, NULL, NULL); 445 ok(!ret && bufLen == 4 && buf[0] == 0, 446 "Expected ret 0, bufLen 4, buf[0] '\\0', got ret %d, bufLen %d, buf[0] '%c'\n", 447 ret, bufLen, buf[0]); 448 449 /* Good strings */ 450 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) 451 { 452 bufLen = 0; 453 /* Bogus length--oddly enough, that succeeds, even though it's not 454 * properly padded. 455 */ 456 ret = CryptStringToBinaryA(tests[i].base64, 1, CRYPT_STRING_BASE64, 457 NULL, &bufLen, NULL, NULL); 458 ok(ret, "CryptStringToBinaryA failed: %d\n", GetLastError()); 459 /* Check with the precise format */ 460 decodeAndCompareBase64_A(tests[i].base64, NULL, NULL, 461 CRYPT_STRING_BASE64, CRYPT_STRING_BASE64, tests[i].toEncode, 462 tests[i].toEncodeLen); 463 decodeAndCompareBase64_A(tests[i].base64, CERT_HEADER, CERT_TRAILER, 464 CRYPT_STRING_BASE64HEADER, CRYPT_STRING_BASE64HEADER, 465 tests[i].toEncode, tests[i].toEncodeLen); 466 decodeAndCompareBase64_A(tests[i].base64, ALT_CERT_HEADER, ALT_CERT_TRAILER, 467 CRYPT_STRING_BASE64HEADER, CRYPT_STRING_BASE64HEADER, 468 tests[i].toEncode, tests[i].toEncodeLen); 469 decodeAndCompareBase64_A(tests[i].base64, CERT_REQUEST_HEADER, 470 CERT_REQUEST_TRAILER, CRYPT_STRING_BASE64REQUESTHEADER, 471 CRYPT_STRING_BASE64REQUESTHEADER, tests[i].toEncode, 472 tests[i].toEncodeLen); 473 decodeAndCompareBase64_A(tests[i].base64, X509_HEADER, X509_TRAILER, 474 CRYPT_STRING_BASE64X509CRLHEADER, CRYPT_STRING_BASE64X509CRLHEADER, 475 tests[i].toEncode, tests[i].toEncodeLen); 476 /* And check with the "any" formats */ 477 decodeAndCompareBase64_A(tests[i].base64, NULL, NULL, 478 CRYPT_STRING_BASE64_ANY, CRYPT_STRING_BASE64, tests[i].toEncode, 479 tests[i].toEncodeLen); 480 /* Don't check with no header and the string_any format, that'll 481 * always succeed. 482 */ 483 decodeAndCompareBase64_A(tests[i].base64, CERT_HEADER, CERT_TRAILER, 484 CRYPT_STRING_BASE64_ANY, CRYPT_STRING_BASE64HEADER, tests[i].toEncode, 485 tests[i].toEncodeLen); 486 decodeAndCompareBase64_A(tests[i].base64, CERT_HEADER, CERT_TRAILER, 487 CRYPT_STRING_ANY, CRYPT_STRING_BASE64HEADER, tests[i].toEncode, 488 tests[i].toEncodeLen); 489 /* oddly, these seem to decode using the wrong format 490 decodeAndCompareBase64_A(tests[i].base64, CERT_REQUEST_HEADER, 491 CERT_REQUEST_TRAILER, CRYPT_STRING_BASE64_ANY, 492 CRYPT_STRING_BASE64REQUESTHEADER, tests[i].toEncode, 493 tests[i].toEncodeLen); 494 decodeAndCompareBase64_A(tests[i].base64, CERT_REQUEST_HEADER, 495 CERT_REQUEST_TRAILER, CRYPT_STRING_ANY, 496 CRYPT_STRING_BASE64REQUESTHEADER, tests[i].toEncode, 497 tests[i].toEncodeLen); 498 decodeAndCompareBase64_A(tests[i].base64, X509_HEADER, X509_TRAILER, 499 CRYPT_STRING_BASE64_ANY, CRYPT_STRING_BASE64X509CRLHEADER, 500 tests[i].toEncode, tests[i].toEncodeLen); 501 decodeAndCompareBase64_A(tests[i].base64, X509_HEADER, X509_TRAILER, 502 CRYPT_STRING_ANY, CRYPT_STRING_BASE64X509CRLHEADER, tests[i].toEncode, 503 tests[i].toEncodeLen); 504 */ 505 } 506 /* And again, with no CR--decoding handles this automatically */ 507 for (i = 0; i < sizeof(testsNoCR) / sizeof(testsNoCR[0]); i++) 508 { 509 bufLen = 0; 510 /* Bogus length--oddly enough, that succeeds, even though it's not 511 * properly padded. 512 */ 513 ret = CryptStringToBinaryA(testsNoCR[i].base64, 1, CRYPT_STRING_BASE64, 514 NULL, &bufLen, NULL, NULL); 515 ok(ret, "CryptStringToBinaryA failed: %d\n", GetLastError()); 516 /* Check with the precise format */ 517 decodeAndCompareBase64_A(testsNoCR[i].base64, NULL, NULL, 518 CRYPT_STRING_BASE64, CRYPT_STRING_BASE64, testsNoCR[i].toEncode, 519 testsNoCR[i].toEncodeLen); 520 decodeAndCompareBase64_A(testsNoCR[i].base64, CERT_HEADER, CERT_TRAILER, 521 CRYPT_STRING_BASE64HEADER, CRYPT_STRING_BASE64HEADER, 522 testsNoCR[i].toEncode, testsNoCR[i].toEncodeLen); 523 decodeAndCompareBase64_A(testsNoCR[i].base64, CERT_REQUEST_HEADER, 524 CERT_REQUEST_TRAILER, CRYPT_STRING_BASE64REQUESTHEADER, 525 CRYPT_STRING_BASE64REQUESTHEADER, testsNoCR[i].toEncode, 526 testsNoCR[i].toEncodeLen); 527 decodeAndCompareBase64_A(testsNoCR[i].base64, X509_HEADER, X509_TRAILER, 528 CRYPT_STRING_BASE64X509CRLHEADER, CRYPT_STRING_BASE64X509CRLHEADER, 529 testsNoCR[i].toEncode, testsNoCR[i].toEncodeLen); 530 /* And check with the "any" formats */ 531 decodeAndCompareBase64_A(testsNoCR[i].base64, NULL, NULL, 532 CRYPT_STRING_BASE64_ANY, CRYPT_STRING_BASE64, testsNoCR[i].toEncode, 533 testsNoCR[i].toEncodeLen); 534 /* Don't check with no header and the string_any format, that'll 535 * always succeed. 536 */ 537 decodeAndCompareBase64_A(testsNoCR[i].base64, CERT_HEADER, CERT_TRAILER, 538 CRYPT_STRING_BASE64_ANY, CRYPT_STRING_BASE64HEADER, 539 testsNoCR[i].toEncode, testsNoCR[i].toEncodeLen); 540 decodeAndCompareBase64_A(testsNoCR[i].base64, CERT_HEADER, CERT_TRAILER, 541 CRYPT_STRING_ANY, CRYPT_STRING_BASE64HEADER, testsNoCR[i].toEncode, 542 testsNoCR[i].toEncodeLen); 543 } 544 } 545 546 START_TEST(base64) 547 { 548 testBinaryToStringA(); 549 testStringToBinaryA(); 550 } 551