ReactOS 0.4.16-dev-1946-g52006dd
base64.c
Go to the documentation of this file.
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 <windows.h>
24#include <wincrypt.h>
25
26#include "wine/test.h"
27
28#define CERT_HEADER "-----BEGIN CERTIFICATE-----\r\n"
29#define ALT_CERT_HEADER "-----BEGIN This is some arbitrary text that goes on and on-----\r\n"
30#define CERT_TRAILER "-----END CERTIFICATE-----\r\n"
31#define ALT_CERT_TRAILER "-----END More arbitrary text------\r\n"
32#define CERT_REQUEST_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----\r\n"
33#define CERT_REQUEST_TRAILER "-----END NEW CERTIFICATE REQUEST-----\r\n"
34#define X509_HEADER "-----BEGIN X509 CRL-----\r\n"
35#define X509_TRAILER "-----END X509 CRL-----\r\n"
36#define CERT_HEADER_NOCR "-----BEGIN CERTIFICATE-----\n"
37#define CERT_TRAILER_NOCR "-----END CERTIFICATE-----\n"
38#define CERT_REQUEST_HEADER_NOCR "-----BEGIN NEW CERTIFICATE REQUEST-----\n"
39#define CERT_REQUEST_TRAILER_NOCR "-----END NEW CERTIFICATE REQUEST-----\n"
40#define X509_HEADER_NOCR "-----BEGIN X509 CRL-----\n"
41#define X509_TRAILER_NOCR "-----END X509 CRL-----\n"
42
44{
45 const BYTE *toEncode;
47 const char *base64;
48};
49
50static const BYTE toEncode1[] = { 0 };
51static const BYTE toEncode2[] = { 1,2 };
52/* static const BYTE toEncode3[] = { 1,2,3 }; */
53static const BYTE toEncode4[] =
54 "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890"
55 "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890"
56 "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890";
57static const BYTE toEncode5[] =
58 "abcdefghijlkmnopqrstuvwxyz01234567890ABCDEFGHI";
59
60static const BYTE toEncode6[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
61
62static const struct BinTests tests[] = {
63 { toEncode1, sizeof(toEncode1), "AA==\r\n", },
64 { toEncode2, sizeof(toEncode2), "AQI=\r\n", },
65 /* { toEncode3, sizeof(toEncode3), "AQID\r\n", }, This test fails on Vista. */
66 { toEncode4, sizeof(toEncode4),
67 "YWJjZGVmZ2hpamxrbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5MEFCQ0RFRkdISUpL\r\n"
68 "TE1OT1BRUlNUVVZXWFlaMDEyMzQ1Njc4OTBhYmNkZWZnaGlqbGttbm9wcXJzdHV2\r\n"
69 "d3h5ejAxMjM0NTY3ODkwQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2\r\n"
70 "Nzg5MGFiY2RlZmdoaWpsa21ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OTBBQkNERUZH\r\n"
71 "SElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY3ODkwAA==\r\n" },
72 { toEncode5, sizeof(toEncode5),
73 "YWJjZGVmZ2hpamxrbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5MEFCQ0RFRkdISQA=\r\n" },
74 { toEncode6, sizeof(toEncode6),
75 "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh\r\n"
76 "YQA=\r\n" },
77};
78
79static const struct BinTests testsNoCR[] = {
80 { toEncode1, sizeof(toEncode1), "AA==\n", },
81 { toEncode2, sizeof(toEncode2), "AQI=\n", },
82 /* { toEncode3, sizeof(toEncode3), "AQID\n", }, This test fails on Vista. */
83 { toEncode4, sizeof(toEncode4),
84 "YWJjZGVmZ2hpamxrbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5MEFCQ0RFRkdISUpL\n"
85 "TE1OT1BRUlNUVVZXWFlaMDEyMzQ1Njc4OTBhYmNkZWZnaGlqbGttbm9wcXJzdHV2\n"
86 "d3h5ejAxMjM0NTY3ODkwQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU2\n"
87 "Nzg5MGFiY2RlZmdoaWpsa21ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OTBBQkNERUZH\n"
88 "SElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NTY3ODkwAA==\n" },
89 { toEncode5, sizeof(toEncode5),
90 "YWJjZGVmZ2hpamxrbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5MEFCQ0RFRkdISQA=\n" },
91 { toEncode6, sizeof(toEncode6),
92 "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh\n"
93 "YQA=\n" },
94};
95
96static WCHAR *strdupAtoW(const char *str)
97{
98 WCHAR *ret = NULL;
99 DWORD len;
100
101 if (!str) return ret;
102 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
103 ret = malloc(len * sizeof(WCHAR));
104 if (ret)
106 return ret;
107}
108
110 DWORD format, const char *expected, const char *header, const char *trailer)
111{
112 DWORD strLen, strLen2, required;
113 const char *ptr;
114 LPSTR str = NULL;
115 BOOL ret;
116
117 required = strlen(expected) + 1;
118 if (header)
119 required += strlen(header);
120 if (trailer)
121 required += strlen(trailer);
122
123 strLen = 0;
125 ok(ret, "CryptBinaryToStringA failed: %ld\n", GetLastError());
126 ok(strLen == required, "Unexpected required length %lu, expected %lu.\n", required, strLen);
127
128 strLen2 = strLen;
130 ok(ret, "CryptBinaryToStringA failed: %ld\n", GetLastError());
131 ok(strLen == strLen2, "Unexpected required length %lu, expected %lu.\n", strLen2, strLen);
132
133 strLen2 = strLen - 1;
135 ok(ret, "CryptBinaryToStringA failed: %ld\n", GetLastError());
136 ok(strLen == strLen2, "Unexpected required length %lu, expected %lu.\n", strLen2, strLen);
137
138 str = malloc(strLen);
139
140 /* Partially filled output buffer. */
141 strLen2 = strLen - 1;
142 str[0] = 0x12;
144 ok((!ret && GetLastError() == ERROR_MORE_DATA) || broken(ret) /* XP */, "CryptBinaryToStringA failed %d, error %ld.\n",
145 ret, GetLastError());
146 ok(strLen2 == strLen || broken(strLen2 == strLen - 1), "Expected length %ld, got %ld\n", strLen, strLen2);
147 if (header)
148 ok(str[0] == header[0], "Unexpected buffer contents %#x.\n", str[0]);
149 else
150 ok(str[0] == expected[0], "Unexpected buffer contents %#x.\n", str[0]);
151 strLen2 = strLen;
153 ok(ret, "CryptBinaryToStringA failed: %ld\n", GetLastError());
154 ok(strLen2 == strLen - 1, "Expected length %ld, got %ld\n", strLen - 1, strLen2);
155
156 ptr = str;
157 if (header)
158 {
159 ok(!strncmp(header, ptr, strlen(header)), "Expected header %s, got %s\n", header, ptr);
160 ptr += strlen(header);
161 }
162 ok(!strncmp(expected, ptr, strlen(expected)), "Expected %s, got %s\n", expected, ptr);
163 ptr += strlen(expected);
164 if (trailer)
165 ok(!strncmp(trailer, ptr, strlen(trailer)), "Expected trailer %s, got %s\n", trailer, ptr);
166
167 free(str);
168}
169
171 const WCHAR *expected, const char *header, const char *trailer)
172{
173 WCHAR *headerW, *trailerW, required;
174 DWORD strLen, strLen2;
175 WCHAR *strW = NULL;
176 const WCHAR *ptr;
177 BOOL ret;
178
179 required = lstrlenW(expected) + 1;
180 if (header)
181 required += strlen(header);
182 if (trailer)
183 required += strlen(trailer);
184
185 strLen = 0;
187 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
188 ok(strLen == required, "Unexpected required length %lu, expected %u.\n", strLen, required);
189
190 /* Same call with non-zero length value. */
191 strLen2 = strLen;
193 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
194 ok(strLen == strLen2, "Unexpected required length.\n");
195
196 strLen2 = strLen - 1;
198 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
199 ok(strLen == strLen2, "Unexpected required length.\n");
200
201 strLen2 = strLen - 1;
203 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
204 ok(strLen == strLen2, "Unexpected required length.\n");
205
206 strW = malloc(strLen * sizeof(WCHAR));
207
208 headerW = strdupAtoW(header);
209 trailerW = strdupAtoW(trailer);
210
211 strLen2 = strLen - 1;
212 strW[0] = 0x1234;
214 ok((!ret && GetLastError() == ERROR_MORE_DATA) || broken(ret) /* XP */, "CryptBinaryToStringW failed, %d, error %ld\n",
215 ret, GetLastError());
216 if (headerW)
217 ok(strW[0] == 0x1234, "Unexpected buffer contents %#x.\n", strW[0]);
218 else
219 ok(strW[0] == 0x1234 || broken(strW[0] != 0x1234) /* XP */, "Unexpected buffer contents %#x.\n", strW[0]);
220
221 strLen2 = strLen;
223 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
224
225 ok(strLen2 == strLen - 1, "Expected length %ld, got %ld\n", strLen - 1, strLen);
226
227 ptr = strW;
228 if (headerW)
229 {
230 ok(!memcmp(headerW, ptr, lstrlenW(headerW)), "Expected header %s, got %s.\n", wine_dbgstr_w(headerW),
232 ptr += lstrlenW(headerW);
233 }
234 ok(!memcmp(expected, ptr, lstrlenW(expected)), "Expected %s, got %s.\n", wine_dbgstr_w(expected),
237 if (trailerW)
238 ok(!memcmp(trailerW, ptr, lstrlenW(trailerW)), "Expected trailer %s, got %s.\n", wine_dbgstr_w(trailerW),
240
241 free(strW);
242 free(headerW);
243 free(trailerW);
244}
245
247{
248 DWORD strLen2;
249
250 strLen2 = binary_len * 3; /* spaces + terminating \0 */
251
253 {
254 strLen2 += (binary_len + 7) / 16; /* space every 16 characters */
255 strLen2 += 1; /* terminating \n */
256 }
257 else if (!(flags & CRYPT_STRING_NOCRLF))
258 {
259 strLen2 += (binary_len + 7) / 16; /* space every 16 characters */
260 strLen2 += binary_len / 16 + 1; /* LF every 16 characters + terminating \r */
261
262 if (binary_len % 16)
263 strLen2 += 1; /* terminating \n */
264 }
265
266 return strLen2;
267}
268
270{
271 static const DWORD flags[] = { 0, CRYPT_STRING_NOCR, CRYPT_STRING_NOCRLF };
272 static const DWORD sizes[] = { 3, 4, 7, 8, 12, 15, 16, 17, 256 };
273 static const WCHAR hexdig[] = L"0123456789abcdef";
274 BYTE input[256 * sizeof(WCHAR)];
275 DWORD strLen, strLen2, i, j, k;
276 WCHAR *hex, *cmp, *ptr;
277 char *hex_a, *cmp_a;
278 BOOL ret;
279
282 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
283
284 strLen = 123;
285 ret = CryptBinaryToStringA(NULL, 0, 0, NULL, &strLen);
287 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
288 ok(strLen == 123, "Unexpected length.\n");
289
290 if (0)
292
293 strLen = 123;
294 ret = CryptBinaryToStringW(NULL, 0, 0, NULL, &strLen);
295 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "Unexpected error %ld\n", GetLastError());
296 ok(strLen == 123, "Unexpected length.\n");
297
298 for (i = 0; i < ARRAY_SIZE(tests); i++)
299 {
300 WCHAR *strW, *encodedW;
301 LPSTR str = NULL;
302 BOOL ret;
303
304 strLen = 0;
306 ok(ret, "CryptBinaryToStringA failed: %ld\n", GetLastError());
307 ok(strLen == tests[i].toEncodeLen, "Unexpected required length %lu.\n", strLen);
308
309 strLen2 = strLen;
310 str = malloc(strLen);
312 ok(ret, "CryptBinaryToStringA failed: %ld\n", GetLastError());
313 ok(strLen == strLen2, "Expected length %lu, got %lu\n", strLen, strLen2);
314 ok(!memcmp(str, tests[i].toEncode, tests[i].toEncodeLen), "Unexpected value\n");
315 free(str);
316
317 strLen = 0;
319 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
320 ok(strLen == tests[i].toEncodeLen, "Unexpected required length %lu.\n", strLen);
321
322 strLen2 = strLen;
323 strW = malloc(strLen);
325 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
326 ok(strLen == strLen2, "Expected length %lu, got %lu\n", strLen, strLen2);
327 ok(!memcmp(strW, tests[i].toEncode, tests[i].toEncodeLen), "Unexpected value\n");
328 free(strW);
329
331 tests[i].base64, NULL, NULL);
338
339 encodedW = strdupAtoW(tests[i].base64);
340
348
349 free(encodedW);
350 }
351
352 for (i = 0; i < ARRAY_SIZE(testsNoCR); i++)
353 {
354 LPSTR str = NULL;
355 WCHAR *encodedW;
356 BOOL ret;
357
360 ok(ret, "CryptBinaryToStringA failed: %ld\n", GetLastError());
361
362 strLen2 = strLen;
363 str = malloc(strLen);
366 ok(ret, "CryptBinaryToStringA failed: %ld\n", GetLastError());
367 ok(strLen == strLen2, "Expected length %ld, got %ld\n", strLen, strLen2);
368 ok(!memcmp(str, testsNoCR[i].toEncode, testsNoCR[i].toEncodeLen), "Unexpected value\n");
369 free(str);
370
380
381 encodedW = strdupAtoW(testsNoCR[i].base64);
382
393
394 free(encodedW);
395 }
396
397 /* Systems that don't support HEXRAW format convert to BASE64 instead - 3 bytes in -> 4 chars + crlf + 1 null out. */
398 strLen = 0;
400 ok(ret, "Failed to get string length.\n");
401 ok(strLen == 9 || broken(strLen == 7), "Unexpected string length %ld.\n", strLen);
402 if (strLen == 7)
403 {
404 win_skip("CryptBinaryToString(HEXRAW) not supported\n");
405 return;
406 }
407
408 for (i = 0; i < sizeof(input) / sizeof(WCHAR); i++)
409 ((WCHAR *)input)[i] = i;
410
411 for (i = 0; i < ARRAY_SIZE(flags); i++)
412 {
413 winetest_push_context("i %lu", i);
414 strLen = 0;
416 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
417 ok(strLen > 0, "Unexpected string length.\n");
418
419 strLen = 0;
421 ok(ret, "failed, error %ld.\n", GetLastError());
422 ok(strLen > 0, "Unexpected string length.\n");
423
424 strLen = ~0;
426 NULL, &strLen);
427 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
429 strLen2 = 0;
430 else if (flags[i] & CRYPT_STRING_NOCR)
431 strLen2 = 1;
432 else
433 strLen2 = 2;
434 strLen2 += sizeof(input) * 2 + 1;
435 ok(strLen == strLen2, "Expected length %ld, got %ld\n", strLen2, strLen);
436
437 hex = malloc(strLen * sizeof(WCHAR));
438 hex_a = malloc(strLen);
439
440 memset(hex, 0xcc, strLen * sizeof(WCHAR));
441 ptr = cmp = malloc(strLen * sizeof(WCHAR));
442 cmp_a = malloc(strLen);
443 for (j = 0; j < ARRAY_SIZE(input); j++)
444 {
445 *ptr++ = hexdig[(input[j] >> 4) & 0xf];
446 *ptr++ = hexdig[input[j] & 0xf];
447 }
449 {
450 *ptr++ = '\n';
451 }
452 else if (!(flags[i] & CRYPT_STRING_NOCRLF))
453 {
454 *ptr++ = '\r';
455 *ptr++ = '\n';
456 }
457 *ptr++ = 0;
458
459 for (j = 0; cmp[j]; ++j)
460 cmp_a[j] = cmp[j];
461 cmp_a[j] = 0;
462
464 hex, &strLen);
465 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
466 strLen2--;
467 ok(strLen == strLen2, "Expected length %ld, got %ld\n", strLen, strLen2);
468 ok(!memcmp(hex, cmp, strLen * sizeof(WCHAR)), "Unexpected value\n");
469
470 ++strLen;
472 hex_a, &strLen);
473 ok(ret, "failed, error %ld.\n", GetLastError());
474 ok(strLen == strLen2, "Expected length %ld, got %ld.\n", strLen, strLen2);
475 ok(!memcmp(hex_a, cmp_a, strLen), "Unexpected value.\n");
476
477 /* adjusts size if buffer too big */
478 strLen *= 2;
480 hex, &strLen);
481 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
482 ok(strLen == strLen2, "Expected length %ld, got %ld\n", strLen, strLen2);
483
484 strLen *= 2;
486 hex_a, &strLen);
487 ok(ret, "failed, error %ld.\n", GetLastError());
488 ok(strLen == strLen2, "Expected length %ld, got %ld.\n", strLen, strLen2);
489
490 /* no writes if buffer too small */
491 strLen /= 2;
492 strLen2 /= 2;
493 memset(hex, 0xcc, strLen * sizeof(WCHAR));
494 memset(cmp, 0xcc, strLen * sizeof(WCHAR));
495 SetLastError(0xdeadbeef);
497 hex, &strLen);
498 ok(!ret && GetLastError() == ERROR_MORE_DATA,"Expected ERROR_MORE_DATA, got ret=%d le=%lu\n",
499 ret, GetLastError());
500 ok(strLen == strLen2, "Expected length %ld, got %ld\n", strLen, strLen2);
501 ok(!memcmp(hex, cmp, strLen * sizeof(WCHAR)), "Unexpected value\n");
502
503 SetLastError(0xdeadbeef);
504 memset(hex_a, 0xcc, strLen + 3);
506 hex_a, &strLen);
507 ok(!ret && GetLastError() == ERROR_MORE_DATA,"got ret %d, error %lu.\n", ret, GetLastError());
508 ok(strLen == strLen2, "Expected length %ld, got %ld.\n", strLen2, strLen);
509 /* Output consists of the number of full bytes which fit in plus terminating 0. */
510 strLen = (strLen - 1) & ~1;
511 ok(!memcmp(hex_a, cmp_a, strLen), "Unexpected value\n");
512 ok(!hex_a[strLen], "got %#x.\n", (unsigned char)hex_a[strLen]);
513 ok((unsigned char)hex_a[strLen + 1] == 0xcc, "got %#x.\n", (unsigned char)hex_a[strLen + 1]);
514
515 /* Output is not filled if string length is less than 3. */
516 strLen = 1;
517 memset(hex_a, 0xcc, strLen2);
519 hex_a, &strLen);
520 ok(strLen == 1, "got %ld.\n", strLen);
521 ok((unsigned char)hex_a[0] == 0xcc, "got %#x.\n", (unsigned char)hex_a[strLen - 1]);
522
523 strLen = 2;
524 memset(hex_a, 0xcc, strLen2);
526 hex_a, &strLen);
527 ok(strLen == 2, "got %ld.\n", strLen);
528 ok((unsigned char)hex_a[0] == 0xcc, "got %#x.\n", (unsigned char)hex_a[0]);
529 ok((unsigned char)hex_a[1] == 0xcc, "got %#x.\n", (unsigned char)hex_a[1]);
530
531 strLen = 3;
532 memset(hex_a, 0xcc, strLen2);
534 hex_a, &strLen);
535 ok(strLen == 3, "got %ld.\n", strLen);
536 ok(hex_a[0] == 0x30, "got %#x.\n", (unsigned char)hex_a[0]);
537 ok(hex_a[1] == 0x30, "got %#x.\n", (unsigned char)hex_a[1]);
538 ok(!hex_a[2], "got %#x.\n", (unsigned char)hex_a[2]);
539
540 free(hex);
541 free(hex_a);
542 free(cmp);
543 free(cmp_a);
544
546 }
547
548 for (k = 0; k < ARRAY_SIZE(sizes); k++)
549 for (i = 0; i < ARRAY_SIZE(flags); i++)
550 {
551 strLen = 0;
553 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
554 ok(strLen > 0, "Unexpected string length.\n");
555
556 strLen = ~0;
558 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
560 ok(strLen == strLen2, "%lu: Expected length %ld, got %ld\n", i, strLen2, strLen);
561
562 hex = malloc(strLen * sizeof(WCHAR) + 256);
563 memset(hex, 0xcc, strLen * sizeof(WCHAR));
564
565 ptr = cmp = malloc(strLen * sizeof(WCHAR) + 256);
566 for (j = 0; j < sizes[k]; j++)
567 {
568 *ptr++ = hexdig[(input[j] >> 4) & 0xf];
569 *ptr++ = hexdig[input[j] & 0xf];
570
571 if (j >= sizes[k] - 1) break;
572
573 if (j && !(flags[i] & CRYPT_STRING_NOCRLF))
574 {
575
576 if (!((j + 1) % 16))
577 {
579 {
580 *ptr++ = '\n';
581 }
582 else
583 {
584 *ptr++ = '\r';
585 *ptr++ = '\n';
586 }
587 continue;
588 }
589 else if (!((j + 1) % 8))
590 *ptr++ = ' ';
591 }
592
593 *ptr++ = ' ';
594 }
595
597 {
598 *ptr++ = '\n';
599 }
600 else if (!(flags[i] & CRYPT_STRING_NOCRLF))
601 {
602 *ptr++ = '\r';
603 *ptr++ = '\n';
604 }
605 *ptr++ = 0;
606
608 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
609 strLen2--;
610 ok(strLen == strLen2, "%lu: Expected length %ld, got %ld\n", i, strLen, strLen2);
611 ok(!memcmp(hex, cmp, strLen * sizeof(WCHAR)), "%lu: got %s\n", i, wine_dbgstr_wn(hex, strLen));
612
613 /* adjusts size if buffer too big */
614 strLen *= 2;
616 ok(ret, "CryptBinaryToStringW failed: %ld\n", GetLastError());
617 ok(strLen == strLen2, "%lu: Expected length %ld, got %ld\n", i, strLen, strLen2);
618
619 /* no writes if buffer too small */
620 strLen /= 2;
621 strLen2 /= 2;
622 memset(hex, 0xcc, strLen * sizeof(WCHAR));
623 memset(cmp, 0xcc, strLen * sizeof(WCHAR));
624 SetLastError(0xdeadbeef);
626 ok(!ret && GetLastError() == ERROR_MORE_DATA,"Expected ERROR_MORE_DATA, got ret=%d le=%lu\n",
627 ret, GetLastError());
628 ok(strLen == strLen2, "%lu: Expected length %ld, got %ld\n", i, strLen, strLen2);
629 ok(!memcmp(hex, cmp, strLen * sizeof(WCHAR)), "%lu: got %s\n", i, wine_dbgstr_wn(hex, strLen));
630
631 free(hex);
632 free(cmp);
633 }
634}
635
637 LPCSTR trailer, DWORD useFormat, DWORD expectedFormat, const BYTE *expected,
638 DWORD expectedLen)
639{
640 static const char garbage[] = "garbage\r\n";
641 LPSTR str;
642 DWORD len = strlen(toDecode) + strlen(garbage) + 1;
643
644 if (header)
645 len += strlen(header);
646 if (trailer)
647 len += strlen(trailer);
648 str = malloc(len);
649 if (str)
650 {
651 LPBYTE buf;
652 DWORD bufLen = 0;
653 BOOL ret;
654
655 if (header)
656 strcpy(str, header);
657 else
658 *str = 0;
659 strcat(str, toDecode);
660 if (trailer)
661 strcat(str, trailer);
662 ret = CryptStringToBinaryA(str, 0, useFormat, NULL, &bufLen, NULL,
663 NULL);
664 ok(ret, "CryptStringToBinaryA failed: %ld\n", GetLastError());
665 buf = malloc(bufLen);
666 if (buf)
667 {
668 DWORD skipped, usedFormat;
669
670 /* check as normal, make sure last two parameters are optional */
671 ret = CryptStringToBinaryA(str, 0, useFormat, buf, &bufLen, NULL,
672 NULL);
673 ok(ret, "CryptStringToBinaryA failed: %ld\n", GetLastError());
674 ok(bufLen == expectedLen,
675 "Expected length %ld, got %ld\n", expectedLen, bufLen);
676 ok(!memcmp(buf, expected, bufLen), "Unexpected value\n");
677 /* check last two params */
678 ret = CryptStringToBinaryA(str, 0, useFormat, buf, &bufLen,
679 &skipped, &usedFormat);
680 ok(ret, "CryptStringToBinaryA failed: %ld\n", GetLastError());
681 ok(skipped == 0, "Expected skipped 0, got %ld\n", skipped);
682 ok(usedFormat == expectedFormat, "Expected format %ld, got %ld\n",
683 expectedFormat, usedFormat);
684 free(buf);
685 }
686
687 /* Check again, but with garbage up front */
688 strcpy(str, garbage);
689 if (header)
690 strcat(str, header);
691 strcat(str, toDecode);
692 if (trailer)
693 strcat(str, trailer);
694 ret = CryptStringToBinaryA(str, 0, useFormat, NULL, &bufLen, NULL,
695 NULL);
696 /* expect failure with no header, and success with one */
697 if (header)
698 ok(ret, "CryptStringToBinaryA failed: %ld\n", GetLastError());
699 else
701 "Expected !ret and last error ERROR_INVALID_DATA, got ret=%d, error=%ld\n", ret, GetLastError());
702 if (ret)
703 {
704 buf = malloc(bufLen);
705 if (buf)
706 {
707 DWORD skipped, usedFormat;
708
709 ret = CryptStringToBinaryA(str, 0, useFormat, buf, &bufLen,
710 &skipped, &usedFormat);
711 ok(ret, "CryptStringToBinaryA failed: %ld\n", GetLastError());
712 ok(skipped == strlen(garbage),
713 "Expected %d characters of \"%s\" skipped when trying format %08lx, got %ld (used format is %08lx)\n",
714 lstrlenA(garbage), str, useFormat, skipped, usedFormat);
715 free(buf);
716 }
717 }
718 free(str);
719 }
720}
721
723 const BYTE *bufA, DWORD bufLenA, DWORD fmtUsedA)
724{
725 BYTE buf[8] = {0};
726 DWORD bufLen = sizeof(buf)-1, fmtUsed = 0xdeadbeef;
727 BOOL ret;
728 WCHAR strW[64];
729 int i;
730 for (i = 0; (strW[i] = strA[i]) != 0; ++i);
731 ret = CryptStringToBinaryW(strW, len, fmt, buf, &bufLen, NULL, &fmtUsed);
732 ok(ret == retA && bufLen == bufLenA && memcmp(bufA, buf, bufLen) == 0
733 && fmtUsed == fmtUsedA, "base64 \"%s\" len %d: W and A differ\n", strA, len);
734}
735
736static void decodeBase64WithLenFmt(LPCSTR str, int len, DWORD fmt, LPCSTR expected, int le, BOOL isBroken)
737{
738 BYTE buf[8] = {0};
739 DWORD bufLen = sizeof(buf)-1, fmtUsed = 0xdeadbeef;
740 BOOL ret;
741 SetLastError(0xdeadbeef);
742 ret = CryptStringToBinaryA(str, len, fmt, buf, &bufLen, NULL, &fmtUsed);
743 buf[bufLen] = 0;
744 if (expected) {
745 BOOL correct = ret && strcmp(expected, (char*)buf) == 0;
746 ok(correct || (isBroken && broken(!ret)),
747 "base64 \"%s\" len %d: expected \"%s\", got \"%s\" (ret %d, le %ld)\n",
748 str, len, expected, (char*)buf, ret, GetLastError());
749 if (correct)
750 ok(fmtUsed == fmt, "base64 \"%s\" len %d: expected fmt %ld, used %ld\n",
751 str, len, fmt, fmtUsed);
752 } else {
753 ok(!ret && GetLastError() == le,
754 "base64 \"%s\" len %d: expected failure, got \"%s\" (ret %d, le %ld)\n",
755 str, len, (char*)buf, ret, GetLastError());
756 }
757
758 decodeBase64WithLenFmtW(str, len, fmt, ret, buf, bufLen, fmtUsed);
759}
760
762{
764}
765
767{
769}
770
772{
774}
775
777{
778 const char *str;
780};
781
782static const struct BadString badStrings[] = {
783 { "-----BEGIN X509 CRL-----\r\nAA==\r\n", CRYPT_STRING_BASE64X509CRLHEADER },
784};
785
787{
788 switch (c)
789 {
790 case '-':
791 case ',':
792 case ' ':
793 case '\t':
794 case '\r':
795 case '\n':
796 return TRUE;
797
798 default:
799 return FALSE;
800 }
801}
802
803static WCHAR wchar_from_str(BOOL wide, const void **str, DWORD *len)
804{
805 WCHAR c;
806
807 if (!*len)
808 return 0;
809
810 --*len;
811 if (wide)
812 c = *(*(const WCHAR **)str)++;
813 else
814 c = *(*(const char **)str)++;
815
816 return c ? c : 0xffff;
817}
818
820{
821 if (c >= '0' && c <= '9')
822 return c - '0';
823 c = towlower(c);
824 if (c >= 'a' && c <= 'f')
825 return c - 'a' + 0xa;
826 return 0xff;
827}
828
829static LONG string_to_hex(const void* str, BOOL wide, DWORD len, BYTE *hex, DWORD *hex_len,
830 DWORD *skipped, DWORD *ret_flags)
831{
832 unsigned int byte_idx = 0;
833 BYTE d1, d2;
834 WCHAR c;
835
836 if (!str || !hex_len)
838
839 if (!len)
840 len = wide ? wcslen(str) : strlen(str);
841
842 if (wide && !len)
844
845 if (skipped)
846 *skipped = 0;
847 if (ret_flags)
848 *ret_flags = 0;
849
850 while ((c = wchar_from_str(wide, &str, &len)) && is_hex_string_special_char(c))
851 ;
852
853 while ((d1 = digit_from_char(c)) != 0xff)
854 {
855 if ((d2 = digit_from_char(wchar_from_str(wide, &str, &len))) == 0xff)
856 {
857 if (!hex)
858 *hex_len = 0;
859 return ERROR_INVALID_DATA;
860 }
861
862 if (hex && byte_idx < *hex_len)
863 hex[byte_idx] = (d1 << 4) | d2;
864
865 ++byte_idx;
866
867 do
868 {
869 c = wchar_from_str(wide, &str, &len);
870 } while (c == '-' || c == ',');
871 }
872
873 while (c)
874 {
876 {
877 if (!hex)
878 *hex_len = 0;
879 return ERROR_INVALID_DATA;
880 }
881 c = wchar_from_str(wide, &str, &len);
882 }
883
884 if (hex && byte_idx > *hex_len)
885 return ERROR_MORE_DATA;
886
887 if (ret_flags)
888 *ret_flags = CRYPT_STRING_HEX;
889
890 *hex_len = byte_idx;
891
892 return ERROR_SUCCESS;
893}
894
896{
897 static const char *string_hex_tests[] =
898 {
899 "",
900 "-",
901 ",-",
902 "0",
903 "00",
904 "000",
905 "11220",
906 "1122q",
907 "q1122",
908 " aE\t\n\r\n",
909 "01-02",
910 "-,01-02",
911 "01-02-",
912 "aa,BB-ff,-,",
913 "1-2",
914 "010-02",
915 "aa,BBff,-,",
916 "aa,,-BB---ff,-,",
917 "010203040506070809q",
918 };
919
920 DWORD skipped, flags, expected_err, expected_len, expected_skipped, expected_flags;
921 BYTE buf[8], expected[8];
922 DWORD bufLen = 0, i;
923 WCHAR str_w[64];
924 BOOL ret, wide;
925
928 "Expected ERROR_INVALID_PARAMETER, got ret=%d le=%lu\n", ret, GetLastError());
929 ret = CryptStringToBinaryA(NULL, 0, 0, NULL, &bufLen, NULL, NULL);
931 "Expected ERROR_INVALID_PARAMETER, got ret=%d le=%lu\n", ret, GetLastError());
932 /* Bogus format */
933 ret = CryptStringToBinaryA(tests[0].base64, 0, 0, NULL, &bufLen, NULL,
934 NULL);
936 "Expected ERROR_INVALID_DATA, got ret=%d le=%lu\n", ret, GetLastError());
937 /* Decoding doesn't expect the NOCR flag to be specified */
938 ret = CryptStringToBinaryA(tests[0].base64, 1,
941 "Expected ERROR_INVALID_DATA, got ret=%d le=%lu\n", ret, GetLastError());
942 /* Bad strings */
943 for (i = 0; i < ARRAY_SIZE(badStrings); i++)
944 {
945 bufLen = 0;
947 NULL, &bufLen, NULL, NULL);
949 "%ld: Expected ERROR_INVALID_DATA, got ret=%d le=%lu\n", i, ret, GetLastError());
950 }
951 /* Weird base64 strings (invalid padding, extra white-space etc.) */
958 decodeBase64WithLenBroken("V", 0, "T", 0);
959 decodeBase64WithLenBroken("VV", 0, "U", 0);
960 decodeBase64WithLenBroken("VVV", 0, "UU", 0);
961 decodeBase64WithLen("V", 1, "T", 0);
962 decodeBase64WithLen("VV", 2, "U", 0);
963 decodeBase64WithLen("VVV", 3, "UU", 0);
964 decodeBase64WithLen("V===", 0, "T", 0);
965 decodeBase64WithLen("V========", 0, "T", 0);
966 decodeBase64WithLen("V===", 4, "T", 0);
967 decodeBase64WithLen("V\nVVV", 0, "UUU", 0);
968 decodeBase64WithLen("VV\nVV", 0, "UUU", 0);
969 decodeBase64WithLen("VVV\nV", 0, "UUU", 0);
970 decodeBase64WithLen("V\nVVV", 5, "UUU", 0);
971 decodeBase64WithLen("VV\nVV", 5, "UUU", 0);
972 decodeBase64WithLen("VVV\nV", 5, "UUU", 0);
973 decodeBase64WithLen("VV VV", 0, "UUU", 0);
974 decodeBase64WithLen("V===VVVV", 0, "T", 0);
975 decodeBase64WithLen("VV==VVVV", 0, "U", 0);
976 decodeBase64WithLen("VVV=VVVV", 0, "UU", 0);
977 decodeBase64WithLen("VVVV=VVVV", 0, "UUU", 0);
978 decodeBase64WithLen("V===VVVV", 8, "T", 0);
979 decodeBase64WithLen("VV==VVVV", 8, "U", 0);
980 decodeBase64WithLen("VVV=VVVV", 8, "UU", 0);
981 decodeBase64WithLen("VVVV=VVVV", 8, "UUU", 0);
982
983 decodeBase64WithFmt("-----BEGIN-----VVVV-----END-----", CRYPT_STRING_BASE64HEADER, 0, ERROR_INVALID_DATA);
984 decodeBase64WithFmt("-----BEGIN-----VVVV-----END -----", CRYPT_STRING_BASE64HEADER, 0, ERROR_INVALID_DATA);
985 decodeBase64WithFmt("-----BEGIN -----VVVV-----END-----", CRYPT_STRING_BASE64HEADER, 0, ERROR_INVALID_DATA);
986 decodeBase64WithFmt("-----BEGIN -----VVVV-----END -----", CRYPT_STRING_BASE64HEADER, "UUU", 0);
987
988 decodeBase64WithFmt("-----BEGIN -----V-----END -----", CRYPT_STRING_BASE64HEADER, "T", 0);
989 decodeBase64WithFmt("-----BEGIN foo-----V-----END -----", CRYPT_STRING_BASE64HEADER, "T", 0);
990 decodeBase64WithFmt("-----BEGIN foo-----V-----END foo-----", CRYPT_STRING_BASE64HEADER, "T", 0);
991 decodeBase64WithFmt("-----BEGIN -----V-----END foo-----", CRYPT_STRING_BASE64HEADER, "T", 0);
992 decodeBase64WithFmt("-----BEGIN -----V-----END -----", CRYPT_STRING_BASE64X509CRLHEADER, "T", 0);
993 decodeBase64WithFmt("-----BEGIN foo-----V-----END -----", CRYPT_STRING_BASE64X509CRLHEADER, "T", 0);
994 decodeBase64WithFmt("-----BEGIN foo-----V-----END foo-----", CRYPT_STRING_BASE64X509CRLHEADER, "T", 0);
995 decodeBase64WithFmt("-----BEGIN -----V-----END foo-----", CRYPT_STRING_BASE64X509CRLHEADER, "T", 0);
996 decodeBase64WithFmt("-----BEGIN -----V-----END -----", CRYPT_STRING_BASE64REQUESTHEADER, "T", 0);
997 decodeBase64WithFmt("-----BEGIN foo-----V-----END -----", CRYPT_STRING_BASE64REQUESTHEADER, "T", 0);
998 decodeBase64WithFmt("-----BEGIN foo-----V-----END foo-----", CRYPT_STRING_BASE64REQUESTHEADER, "T", 0);
999 decodeBase64WithFmt("-----BEGIN -----V-----END foo-----", CRYPT_STRING_BASE64REQUESTHEADER, "T", 0);
1000
1001 /* Too small buffer */
1002 buf[0] = 0;
1003 bufLen = 4;
1004 ret = CryptStringToBinaryA("VVVVVVVV", 8, CRYPT_STRING_BASE64, (BYTE*)buf, &bufLen, NULL, NULL);
1005 ok(!ret && bufLen == 4 && buf[0] == 0,
1006 "Expected ret 0, bufLen 4, buf[0] '\\0', got ret %d, bufLen %ld, buf[0] '%c'\n",
1007 ret, bufLen, buf[0]);
1008
1009 /* Good strings */
1010 for (i = 0; i < ARRAY_SIZE(tests); i++)
1011 {
1012 bufLen = 0;
1013 /* Bogus length--oddly enough, that succeeds, even though it's not
1014 * properly padded.
1015 */
1017 NULL, &bufLen, NULL, NULL);
1018 ok(ret, "CryptStringToBinaryA failed: %ld\n", GetLastError());
1019 /* Check with the precise format */
1022 tests[i].toEncodeLen);
1025 tests[i].toEncode, tests[i].toEncodeLen);
1028 tests[i].toEncode, tests[i].toEncodeLen);
1032 tests[i].toEncodeLen);
1035 tests[i].toEncode, tests[i].toEncodeLen);
1036 /* And check with the "any" formats */
1039 tests[i].toEncodeLen);
1040 /* Don't check with no header and the string_any format, that'll
1041 * always succeed.
1042 */
1045 tests[i].toEncodeLen);
1048 tests[i].toEncodeLen);
1049 /* oddly, these seem to decode using the wrong format
1050 decodeAndCompareBase64_A(tests[i].base64, CERT_REQUEST_HEADER,
1051 CERT_REQUEST_TRAILER, CRYPT_STRING_BASE64_ANY,
1052 CRYPT_STRING_BASE64REQUESTHEADER, tests[i].toEncode,
1053 tests[i].toEncodeLen);
1054 decodeAndCompareBase64_A(tests[i].base64, CERT_REQUEST_HEADER,
1055 CERT_REQUEST_TRAILER, CRYPT_STRING_ANY,
1056 CRYPT_STRING_BASE64REQUESTHEADER, tests[i].toEncode,
1057 tests[i].toEncodeLen);
1058 decodeAndCompareBase64_A(tests[i].base64, X509_HEADER, X509_TRAILER,
1059 CRYPT_STRING_BASE64_ANY, CRYPT_STRING_BASE64X509CRLHEADER,
1060 tests[i].toEncode, tests[i].toEncodeLen);
1061 decodeAndCompareBase64_A(tests[i].base64, X509_HEADER, X509_TRAILER,
1062 CRYPT_STRING_ANY, CRYPT_STRING_BASE64X509CRLHEADER, tests[i].toEncode,
1063 tests[i].toEncodeLen);
1064 */
1065 }
1066 /* And again, with no CR--decoding handles this automatically */
1067 for (i = 0; i < ARRAY_SIZE(testsNoCR); i++)
1068 {
1069 bufLen = 0;
1070 /* Bogus length--oddly enough, that succeeds, even though it's not
1071 * properly padded.
1072 */
1074 NULL, &bufLen, NULL, NULL);
1075 ok(ret, "CryptStringToBinaryA failed: %ld\n", GetLastError());
1076 /* Check with the precise format */
1079 testsNoCR[i].toEncodeLen);
1082 testsNoCR[i].toEncode, testsNoCR[i].toEncodeLen);
1086 testsNoCR[i].toEncodeLen);
1089 testsNoCR[i].toEncode, testsNoCR[i].toEncodeLen);
1090 /* And check with the "any" formats */
1093 testsNoCR[i].toEncodeLen);
1094 /* Don't check with no header and the string_any format, that'll
1095 * always succeed.
1096 */
1099 testsNoCR[i].toEncode, testsNoCR[i].toEncodeLen);
1102 testsNoCR[i].toEncodeLen);
1103 }
1104
1105 /* CRYPT_STRING_HEX */
1106
1108 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got ret %d, error %lu.\n", ret, GetLastError());
1109 if (0)
1110 {
1111 /* access violation on Windows. */
1113 }
1114
1115 bufLen = 8;
1116 ret = CryptStringToBinaryW(L"0102", 2, CRYPT_STRING_HEX, NULL, &bufLen, NULL, NULL);
1117 ok(ret, "got error %lu.\n", GetLastError());
1118 ok(bufLen == 1, "got length %lu.\n", bufLen);
1119
1120 bufLen = 8;
1122 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got ret %d, error %lu.\n", ret, GetLastError());
1123 ok(bufLen == 8, "got length %lu.\n", bufLen);
1124
1125 bufLen = 8;
1127 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got ret %d, error %lu.\n", ret, GetLastError());
1128 ok(bufLen == 8, "got length %lu.\n", bufLen);
1129
1130 bufLen = 8;
1131 ret = CryptStringToBinaryW(L"0102", 3, CRYPT_STRING_HEX, NULL, &bufLen, NULL, NULL);
1132 ok(!ret && GetLastError() == ERROR_INVALID_DATA, "got ret %d, error %lu.\n", ret, GetLastError());
1133 ok(!bufLen, "got length %lu.\n", bufLen);
1134
1135 bufLen = 8;
1136 buf[0] = 0xcc;
1137 ret = CryptStringToBinaryW(L"0102", 3, CRYPT_STRING_HEX, buf, &bufLen, NULL, NULL);
1138 ok(!ret && GetLastError() == ERROR_INVALID_DATA, "got ret %d, error %lu.\n", ret, GetLastError());
1139 ok(bufLen == 8, "got length %lu.\n", bufLen);
1140 ok(buf[0] == 1, "got buf[0] %#x.\n", buf[0]);
1141
1142 bufLen = 8;
1143 buf[0] = 0xcc;
1144 ret = CryptStringToBinaryW(L"0102", 2, CRYPT_STRING_HEX, buf, &bufLen, NULL, NULL);
1145 ok(ret, "got error %lu.\n", GetLastError());
1146 ok(bufLen == 1, "got length %lu.\n", bufLen);
1147 ok(buf[0] == 1, "got buf[0] %#x.\n", buf[0]);
1148
1149 bufLen = 8;
1150 buf[0] = buf[1] = 0xcc;
1151 ret = CryptStringToBinaryA("01\0 02", 4, CRYPT_STRING_HEX, buf, &bufLen, NULL, NULL);
1152 ok(!ret && GetLastError() == ERROR_INVALID_DATA, "got ret %d, error %lu.\n", ret, GetLastError());
1153 ok(bufLen == 8, "got length %lu.\n", bufLen);
1154 ok(buf[0] == 1, "got buf[0] %#x.\n", buf[0]);
1155 ok(buf[1] == 0xcc, "got buf[1] %#x.\n", buf[1]);
1156
1157 bufLen = 8;
1158 buf[0] = buf[1] = 0xcc;
1159 ret = CryptStringToBinaryW(L"01\0 02", 4, CRYPT_STRING_HEX, buf, &bufLen, NULL, NULL);
1160 ok(!ret && GetLastError() == ERROR_INVALID_DATA, "got ret %d, error %lu.\n", ret, GetLastError());
1161 ok(bufLen == 8, "got length %lu.\n", bufLen);
1162 ok(buf[0] == 1, "got buf[0] %#x.\n", buf[0]);
1163 ok(buf[1] == 0xcc, "got buf[1] %#x.\n", buf[1]);
1164
1165 bufLen = 1;
1166 buf[0] = 0xcc;
1167 skipped = 0xdeadbeef;
1168 flags = 0xdeadbeef;
1169 ret = CryptStringToBinaryW(L"0102", 4, CRYPT_STRING_HEX, buf, &bufLen, &skipped, &flags);
1170 ok(!ret && GetLastError() == ERROR_MORE_DATA, "got ret %d, error %lu.\n", ret, GetLastError());
1171 ok(bufLen == 1, "got length %lu.\n", bufLen);
1172 ok(buf[0] == 1, "got buf[0] %#x.\n", buf[0]);
1173 ok(!flags, "got flags %lu.\n", flags);
1174 ok(!skipped, "got skipped %lu.\n", skipped);
1175
1176 for (i = 0; i < ARRAY_SIZE(string_hex_tests); ++i)
1177 {
1178 for (wide = 0; wide < 2; ++wide)
1179 {
1180 if (wide)
1181 {
1182 unsigned int j = 0;
1183
1184 while ((str_w[j] = string_hex_tests[i][j]))
1185 ++j;
1186 }
1187 winetest_push_context("test %lu, %s", i, wide ? debugstr_w(str_w)
1188 : debugstr_a(string_hex_tests[i]));
1189
1190 expected_len = 0xdeadbeef;
1191 expected_skipped = 0xdeadbeef;
1192 expected_flags = 0xdeadbeef;
1193 expected_err = string_to_hex(wide ? (void *)str_w : (void *)string_hex_tests[i], wide, 0, NULL,
1194 &expected_len, &expected_skipped, &expected_flags);
1195
1196 bufLen = 0xdeadbeef;
1197 skipped = 0xdeadbeef;
1198 flags = 0xdeadbeef;
1199 SetLastError(0xdeadbeef);
1200 if (wide)
1201 ret = CryptStringToBinaryW(str_w, 0, CRYPT_STRING_HEX, NULL, &bufLen, &skipped, &flags);
1202 else
1203 ret = CryptStringToBinaryA(string_hex_tests[i], 0, CRYPT_STRING_HEX, NULL, &bufLen, &skipped, &flags);
1204
1205 ok(bufLen == expected_len, "got length %lu.\n", bufLen);
1206 ok(skipped == expected_skipped, "got skipped %lu.\n", skipped);
1207 ok(flags == expected_flags, "got flags %lu.\n", flags);
1208
1209 if (expected_err)
1210 ok(!ret && GetLastError() == expected_err, "got ret %d, error %lu.\n", ret, GetLastError());
1211 else
1212 ok(ret, "got error %lu.\n", GetLastError());
1213
1214 memset(expected, 0xcc, sizeof(expected));
1215 expected_len = 8;
1216 expected_skipped = 0xdeadbeef;
1217 expected_flags = 0xdeadbeef;
1218 expected_err = string_to_hex(wide ? (void *)str_w : (void *)string_hex_tests[i], wide, 0, expected,
1219 &expected_len, &expected_skipped, &expected_flags);
1220
1221 memset(buf, 0xcc, sizeof(buf));
1222 bufLen = 8;
1223 skipped = 0xdeadbeef;
1224 flags = 0xdeadbeef;
1225 SetLastError(0xdeadbeef);
1226 if (wide)
1227 ret = CryptStringToBinaryW(str_w, 0, CRYPT_STRING_HEX, buf, &bufLen, &skipped, &flags);
1228 else
1229 ret = CryptStringToBinaryA(string_hex_tests[i], 0, CRYPT_STRING_HEX, buf, &bufLen, &skipped, &flags);
1230
1231 ok(!memcmp(buf, expected, sizeof(buf)), "data does not match, buf[0] %#x, buf[1] %#x.\n", buf[0], buf[1]);
1232 ok(bufLen == expected_len, "got length %lu.\n", bufLen);
1233 if (expected_err)
1234 ok(!ret && GetLastError() == expected_err, "got ret %d, error %lu.\n", ret, GetLastError());
1235 else
1236 ok(ret, "got error %lu.\n", GetLastError());
1237
1238 ok(bufLen == expected_len, "got length %lu.\n", bufLen);
1239 ok(skipped == expected_skipped, "got skipped %lu.\n", skipped);
1240 ok(flags == expected_flags, "got flags %lu.\n", flags);
1241
1243 }
1244 }
1245
1246 bufLen = 1;
1247 SetLastError(0xdeadbeef);
1248 skipped = 0xdeadbeef;
1249 flags = 0xdeadbeef;
1250 memset(buf, 0xcc, sizeof(buf));
1251 ret = CryptStringToBinaryA("0102", 0, CRYPT_STRING_HEX, buf, &bufLen, &skipped, &flags);
1252 ok(!ret && GetLastError() == ERROR_MORE_DATA, "got ret %d, error %lu.\n", ret, GetLastError());
1253 ok(bufLen == 1, "got length %lu.\n", bufLen);
1254 ok(!skipped, "got skipped %lu.\n", skipped);
1255 ok(!flags, "got flags %lu.\n", flags);
1256 ok(buf[0] == 1, "got buf[0] %#x.\n", buf[0]);
1257 ok(buf[1] == 0xcc, "got buf[1] %#x.\n", buf[1]);
1258
1259 bufLen = 1;
1260 SetLastError(0xdeadbeef);
1261 skipped = 0xdeadbeef;
1262 flags = 0xdeadbeef;
1263 memset(buf, 0xcc, sizeof(buf));
1264 ret = CryptStringToBinaryA("0102q", 0, CRYPT_STRING_HEX, buf, &bufLen, &skipped, &flags);
1265 ok(!ret && GetLastError() == ERROR_INVALID_DATA, "got ret %d, error %lu.\n", ret, GetLastError());
1266 ok(bufLen == 1, "got length %lu.\n", bufLen);
1267 ok(!skipped, "got skipped %lu.\n", skipped);
1268 ok(!flags, "got flags %lu.\n", flags);
1269 ok(buf[0] == 1, "got buf[0] %#x.\n", buf[0]);
1270 ok(buf[1] == 0xcc, "got buf[1] %#x.\n", buf[1]);
1271
1272 bufLen = 1;
1273 SetLastError(0xdeadbeef);
1274 skipped = 0xdeadbeef;
1275 flags = 0xdeadbeef;
1276 memset(buf, 0xcc, sizeof(buf));
1277 ret = CryptStringToBinaryW(L"0102q", 0, CRYPT_STRING_HEX, buf, &bufLen, &skipped, &flags);
1278 ok(!ret && GetLastError() == ERROR_INVALID_DATA, "got ret %d, error %lu.\n", ret, GetLastError());
1279 ok(bufLen == 1, "got length %lu.\n", bufLen);
1280 ok(!skipped, "got skipped %lu.\n", skipped);
1281 ok(!flags, "got flags %lu.\n", flags);
1282 ok(buf[0] == 1, "got buf[0] %#x.\n", buf[0]);
1283 ok(buf[1] == 0xcc, "got buf[1] %#x.\n", buf[1]);
1284
1285 bufLen = 1;
1286 SetLastError(0xdeadbeef);
1287 skipped = 0xdeadbeef;
1288 flags = 0xdeadbeef;
1289 memset(buf, 0xcc, sizeof(buf));
1290 ret = CryptStringToBinaryW(L"0102", 0, CRYPT_STRING_HEX, buf, &bufLen, &skipped, &flags);
1291 ok(bufLen == 1, "got length %lu.\n", bufLen);
1292 ok(!ret && GetLastError() == ERROR_MORE_DATA, "got ret %d, error %lu.\n", ret, GetLastError());
1293 ok(buf[0] == 1, "got buf[0] %#x.\n", buf[0]);
1294 ok(buf[1] == 0xcc, "got buf[1] %#x.\n", buf[1]);
1295
1296 /* It looks like Windows is normalizing Unicode strings in some way which depending on locale may result in
1297 * some invalid characters in 128-255 range being converted into sequences starting with valid hex numbers.
1298 * Just avoiding characters in the 128-255 range in test. */
1299 for (i = 1; i < 128; ++i)
1300 {
1301 char str_a[16];
1302
1303 for (wide = 0; wide < 2; ++wide)
1304 {
1305 if (wide)
1306 {
1307 str_w[0] = i;
1308 wcscpy(str_w + 1, L"00");
1309 }
1310 else
1311 {
1312 str_a[0] = i;
1313 strcpy(str_a + 1, "00");
1314 }
1315
1316 winetest_push_context("char %#lx, %s", i, wide ? debugstr_w(str_w) : debugstr_a(str_a));
1317
1318 bufLen = 1;
1319 buf[0] = buf[1] = 0xcc;
1320 SetLastError(0xdeadbeef);
1321 if (wide)
1322 ret = CryptStringToBinaryW(str_w, 0, CRYPT_STRING_HEX, buf, &bufLen, &skipped, &flags);
1323 else
1324 ret = CryptStringToBinaryA(str_a, 0, CRYPT_STRING_HEX, buf, &bufLen, &skipped, &flags);
1325 ok(bufLen == 1, "got length %lu.\n", bufLen);
1327 {
1328 ok(ret, "got error %lu.\n", GetLastError());
1329 ok(!buf[0], "got buf[0] %#x.\n", buf[0]);
1330 ok(buf[1] == 0xcc, "got buf[1] %#x.\n", buf[1]);
1331 }
1332 else
1333 {
1334 ok(!ret && GetLastError() == ERROR_INVALID_DATA, "got ret %d, error %lu.\n", ret, GetLastError());
1335 if (isdigit(i) || (tolower(i) >= 'a' && tolower(i) <= 'f'))
1336 {
1337 ok(buf[0] == (digit_from_char(i) << 4), "got buf[0] %#x.\n", buf[0]);
1338 ok(buf[1] == 0xcc, "got buf[0] %#x.\n", buf[1]);
1339 }
1340 else
1341 {
1342 ok(buf[0] == 0xcc, "got buf[0] %#x.\n", buf[0]);
1343 }
1344 }
1346 }
1347 }
1348}
1349
1351{
1354}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define isdigit(c)
Definition: acclib.h:68
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
int tolower(int c)
Definition: utclib.c:902
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:20
wcscpy
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString)
Definition: base64.c:473
BOOL WINAPI CryptStringToBinaryW(LPCWSTR pszString, DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:983
#define X509_TRAILER
Definition: base64.c:40
BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString, DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:772
#define CERT_TRAILER
Definition: base64.c:35
#define CERT_REQUEST_HEADER
Definition: base64.c:37
#define X509_HEADER
Definition: base64.c:39
BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString)
Definition: base64.c:253
#define CERT_HEADER
Definition: base64.c:32
#define CERT_REQUEST_TRAILER
Definition: base64.c:38
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrlenW
Definition: compat.h:750
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
int hex(char ch)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define c
Definition: ke_i.h:80
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
#define win_skip
Definition: minitest.h:67
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
static PVOID ptr
Definition: dispmode.c:27
static const BYTE toEncode4[]
Definition: base64.c:53
static void decodeBase64WithLen(LPCSTR str, int len, LPCSTR expected, int le)
Definition: base64.c:766
static void encodeAndCompareBase64_A(const BYTE *toEncode, DWORD toEncodeLen, DWORD format, const char *expected, const char *header, const char *trailer)
Definition: base64.c:109
static void test_CryptStringToBinary(void)
Definition: base64.c:895
static const struct BinTests tests[]
Definition: base64.c:62
#define CERT_REQUEST_HEADER_NOCR
Definition: base64.c:38
static DWORD binary_to_hex_len(DWORD binary_len, DWORD flags)
Definition: base64.c:246
#define X509_HEADER_NOCR
Definition: base64.c:40
static const BYTE toEncode6[]
Definition: base64.c:60
static void decodeBase64WithFmt(LPCSTR str, DWORD fmt, LPCSTR expected, int le)
Definition: base64.c:771
#define CERT_TRAILER_NOCR
Definition: base64.c:37
static const BYTE toEncode1[]
Definition: base64.c:50
static void encode_compare_base64_W(const BYTE *toEncode, DWORD toEncodeLen, DWORD format, const WCHAR *expected, const char *header, const char *trailer)
Definition: base64.c:170
static const struct BadString badStrings[]
Definition: base64.c:782
static void decodeBase64WithLenFmt(LPCSTR str, int len, DWORD fmt, LPCSTR expected, int le, BOOL isBroken)
Definition: base64.c:736
static const BYTE toEncode2[]
Definition: base64.c:51
static const BYTE toEncode5[]
Definition: base64.c:57
static void decodeAndCompareBase64_A(LPCSTR toDecode, LPCSTR header, LPCSTR trailer, DWORD useFormat, DWORD expectedFormat, const BYTE *expected, DWORD expectedLen)
Definition: base64.c:636
static BOOL is_hex_string_special_char(WCHAR c)
Definition: base64.c:786
static BYTE digit_from_char(WCHAR c)
Definition: base64.c:819
static void decodeBase64WithLenFmtW(LPCSTR strA, int len, DWORD fmt, BOOL retA, const BYTE *bufA, DWORD bufLenA, DWORD fmtUsedA)
Definition: base64.c:722
#define CERT_HEADER_NOCR
Definition: base64.c:36
#define ALT_CERT_TRAILER
Definition: base64.c:31
static WCHAR * strdupAtoW(const char *str)
Definition: base64.c:96
static const struct BinTests testsNoCR[]
Definition: base64.c:79
static LONG string_to_hex(const void *str, BOOL wide, DWORD len, BYTE *hex, DWORD *hex_len, DWORD *skipped, DWORD *ret_flags)
Definition: base64.c:829
static void decodeBase64WithLenBroken(LPCSTR str, int len, LPCSTR expected, int le)
Definition: base64.c:761
#define CERT_REQUEST_TRAILER_NOCR
Definition: base64.c:39
static WCHAR wchar_from_str(BOOL wide, const void **str, DWORD *len)
Definition: base64.c:803
static void test_CryptBinaryToString(void)
Definition: base64.c:269
#define X509_TRAILER_NOCR
Definition: base64.c:41
#define ALT_CERT_HEADER
Definition: base64.c:29
BOOL expected
Definition: store.c:2000
#define cmp(status, error)
Definition: error.c:114
WCHAR strW[12]
Definition: clipboard.c:2025
char strA[12]
Definition: clipboard.c:2024
int k
Definition: mpi.c:3369
static const struct @594 sizes[]
long LONG
Definition: pedump.c:60
#define wine_dbgstr_wn
Definition: testlist.c:2
const WCHAR * str
strcat
Definition: string.h:92
strcpy
Definition: string.h:131
#define memset(x, y, z)
Definition: compat.h:39
const char * str
Definition: base64.c:778
DWORD format
Definition: base64.c:779
const BYTE * toEncode
Definition: base64.c:45
DWORD toEncodeLen
Definition: base64.c:46
const char * base64
Definition: base64.c:47
Definition: dsound.c:943
Definition: format.c:58
#define towlower(c)
Definition: wctype.h:97
unsigned char * LPBYTE
Definition: typedefs.h:53
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CRYPT_STRING_BINARY
Definition: wincrypt.h:3133
#define CRYPT_STRING_BASE64X509CRLHEADER
Definition: wincrypt.h:3140
#define CRYPT_STRING_BASE64REQUESTHEADER
Definition: wincrypt.h:3134
#define CRYPT_STRING_BASE64HEADER
Definition: wincrypt.h:3131
#define CRYPT_STRING_HEX
Definition: wincrypt.h:3135
#define CRYPT_STRING_BASE64
Definition: wincrypt.h:3132
#define CRYPT_STRING_BASE64_ANY
Definition: wincrypt.h:3137
#define CRYPT_STRING_HEXRAW
Definition: wincrypt.h:3143
#define CRYPT_STRING_NOCRLF
Definition: wincrypt.h:3149
#define CRYPT_STRING_ANY
Definition: wincrypt.h:3138
#define CRYPT_STRING_NOCR
Definition: wincrypt.h:3150
#define ERROR_INVALID_DATA
Definition: winerror.h:238
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
char * LPSTR
Definition: xmlstorage.h:182
unsigned char BYTE
Definition: xxhash.c:193