ReactOS 0.4.16-dev-197-g92996da
base64.c
Go to the documentation of this file.
1/*
2 * base64 encoder/decoder
3 *
4 * Copyright 2005 by Kai Blin
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
22#include <stdarg.h>
23#include "windef.h"
24#include "winbase.h"
25#include "winerror.h"
26#include "wincrypt.h"
27#include "wine/debug.h"
28#include "wine/unicode.h"
29
31
32#define CERT_HEADER "-----BEGIN CERTIFICATE-----"
33#define CERT_HEADER_START "-----BEGIN "
34#define CERT_DELIMITER "-----"
35#define CERT_TRAILER "-----END CERTIFICATE-----"
36#define CERT_TRAILER_START "-----END "
37#define CERT_REQUEST_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----"
38#define CERT_REQUEST_TRAILER "-----END NEW CERTIFICATE REQUEST-----"
39#define X509_HEADER "-----BEGIN X509 CRL-----"
40#define X509_TRAILER "-----END X509 CRL-----"
41
42static const WCHAR CERT_HEADER_W[] = {
43'-','-','-','-','-','B','E','G','I','N',' ','C','E','R','T','I','F','I','C',
44'A','T','E','-','-','-','-','-',0 };
45static const WCHAR CERT_HEADER_START_W[] = {
46'-','-','-','-','-','B','E','G','I','N',' ',0 };
47static const WCHAR CERT_DELIMITER_W[] = {
48'-','-','-','-','-',0 };
49static const WCHAR CERT_TRAILER_W[] = {
50'-','-','-','-','-','E','N','D',' ','C','E','R','T','I','F','I','C','A','T',
51'E','-','-','-','-','-',0 };
52static const WCHAR CERT_TRAILER_START_W[] = {
53'-','-','-','-','-','E','N','D',' ',0 };
54static const WCHAR CERT_REQUEST_HEADER_W[] = {
55'-','-','-','-','-','B','E','G','I','N',' ','N','E','W',' ','C','E','R','T',
56'I','F','I','C','A','T','E',' ','R','E','Q','U','E','S','T','-','-','-','-','-',0 };
57static const WCHAR CERT_REQUEST_TRAILER_W[] = {
58'-','-','-','-','-','E','N','D',' ','N','E','W',' ','C','E','R','T','I','F',
59'I','C','A','T','E',' ','R','E','Q','U','E','S','T','-','-','-','-','-',0 };
60static const WCHAR X509_HEADER_W[] = {
61'-','-','-','-','-','B','E','G','I','N',' ','X','5','0','9',' ','C','R','L',
62'-','-','-','-','-',0 };
63static const WCHAR X509_TRAILER_W[] = {
64'-','-','-','-','-','E','N','D',' ','X','5','0','9',' ','C','R','L','-','-',
65'-','-','-',0 };
66
67static const char b64[] =
68"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
69
70typedef BOOL (*BinaryToStringAFunc)(const BYTE *pbBinary,
72typedef BOOL (*BinaryToStringWFunc)(const BYTE *pbBinary,
74
75static BOOL EncodeBinaryToBinaryA(const BYTE *pbBinary,
77{
78 BOOL ret = TRUE;
79
80 if (pszString)
81 {
82 if (*pcchString < cbBinary)
83 {
85 ret = FALSE;
86 }
87 else if (cbBinary)
88 memcpy(pszString, pbBinary, cbBinary);
89 }
90 else
92
93 return ret;
94}
95
96static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep,
97 char* out_buf, DWORD *out_len)
98{
99 int div, i;
100 const BYTE *d = in_buf;
101 int bytes = (in_len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0;
102 DWORD needed;
103 LPSTR ptr;
104
105 TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes);
106 needed = bytes + pad_bytes;
107 needed += (needed / 64 + (needed % 64 ? 1 : 0)) * strlen(sep);
108 needed++;
109
110 if (needed > *out_len)
111 {
112 *out_len = needed;
114 }
115 else
116 *out_len = needed;
117
118 /* Three bytes of input give 4 chars of output */
119 div = in_len / 3;
120
121 ptr = out_buf;
122 i = 0;
123 while (div > 0)
124 {
125 if (i && i % 64 == 0)
126 {
127 strcpy(ptr, sep);
128 ptr += strlen(sep);
129 }
130 /* first char is the first 6 bits of the first byte*/
131 *ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
132 /* second char is the last 2 bits of the first byte and the first 4
133 * bits of the second byte */
134 *ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)];
135 /* third char is the last 4 bits of the second byte and the first 2
136 * bits of the third byte */
137 *ptr++ = b64[ ((d[1] << 2) & 0x3c) | (d[2] >> 6 & 0x03)];
138 /* fourth char is the remaining 6 bits of the third byte */
139 *ptr++ = b64[ d[2] & 0x3f];
140 i += 4;
141 d += 3;
142 div--;
143 }
144
145 switch(pad_bytes)
146 {
147 case 1:
148 /* first char is the first 6 bits of the first byte*/
149 *ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
150 /* second char is the last 2 bits of the first byte and the first 4
151 * bits of the second byte */
152 *ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)];
153 /* third char is the last 4 bits of the second byte padded with
154 * two zeroes */
155 *ptr++ = b64[ ((d[1] << 2) & 0x3c) ];
156 /* fourth char is a = to indicate one byte of padding */
157 *ptr++ = '=';
158 break;
159 case 2:
160 /* first char is the first 6 bits of the first byte*/
161 *ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
162 /* second char is the last 2 bits of the first byte padded with
163 * four zeroes*/
164 *ptr++ = b64[ ((d[0] << 4) & 0x30)];
165 /* third char is = to indicate padding */
166 *ptr++ = '=';
167 /* fourth char is = to indicate padding */
168 *ptr++ = '=';
169 break;
170 }
171 strcpy(ptr, sep);
172
173 return ERROR_SUCCESS;
174}
175
176static BOOL BinaryToBase64A(const BYTE *pbBinary,
178{
179 static const char crlf[] = "\r\n", lf[] = "\n";
180 BOOL ret = TRUE;
181 LPCSTR header = NULL, trailer = NULL, sep;
182 DWORD charsNeeded;
183
185 sep = lf;
186 else if (dwFlags & CRYPT_STRING_NOCRLF)
187 sep = "";
188 else
189 sep = crlf;
190 switch (dwFlags & 0x0fffffff)
191 {
193 /* no header or footer */
194 break;
197 trailer = CERT_TRAILER;
198 break;
201 trailer = CERT_REQUEST_TRAILER;
202 break;
205 trailer = X509_TRAILER;
206 break;
207 }
208
209 charsNeeded = 0;
210 encodeBase64A(pbBinary, cbBinary, sep, NULL, &charsNeeded);
211 if (header)
212 charsNeeded += strlen(header) + strlen(sep);
213 if (trailer)
214 charsNeeded += strlen(trailer) + strlen(sep);
215
216 if (pszString)
217 {
218 if (charsNeeded <= *pcchString)
219 {
221 DWORD size = charsNeeded;
222
223 if (header)
224 {
225 strcpy(ptr, header);
226 ptr += strlen(ptr);
227 strcpy(ptr, sep);
228 ptr += strlen(sep);
229 }
230 encodeBase64A(pbBinary, cbBinary, sep, ptr, &size);
231 ptr += size - 1;
232 if (trailer)
233 {
234 strcpy(ptr, trailer);
235 ptr += strlen(ptr);
236 strcpy(ptr, sep);
237 }
238 *pcchString = charsNeeded - 1;
239 }
240 else
241 {
242 *pcchString = charsNeeded;
244 ret = FALSE;
245 }
246 }
247 else
248 *pcchString = charsNeeded;
249
250 return ret;
251}
252
255{
256 BinaryToStringAFunc encoder = NULL;
257
258 TRACE("(%p, %d, %08x, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString,
259 pcchString);
260
261 if (!pbBinary)
262 {
264 return FALSE;
265 }
266 if (!pcchString)
267 {
269 return FALSE;
270 }
271
272 switch (dwFlags & 0x0fffffff)
273 {
275 encoder = EncodeBinaryToBinaryA;
276 break;
281 encoder = BinaryToBase64A;
282 break;
283 case CRYPT_STRING_HEX:
287 FIXME("Unimplemented type %d\n", dwFlags & 0x0fffffff);
288 /* fall through */
289 default:
291 return FALSE;
292 }
293 return encoder(pbBinary, cbBinary, dwFlags, pszString, pcchString);
294}
295
296static BOOL EncodeBinaryToBinaryW(const BYTE *in_buf, DWORD in_len, DWORD flags, WCHAR *out_buf, DWORD *out_len)
297{
298 BOOL ret = TRUE;
299
300 if (out_buf)
301 {
302 if (*out_len < in_len)
303 {
305 ret = FALSE;
306 }
307 else if (in_len)
308 memcpy(out_buf, in_buf, in_len);
309 }
310 else
311 *out_len = in_len;
312
313 return ret;
314}
315
316static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep,
317 WCHAR* out_buf, DWORD *out_len)
318{
319 int div, i;
320 const BYTE *d = in_buf;
321 int bytes = (in_len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0;
322 DWORD needed;
323 LPWSTR ptr;
324
325 TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes);
326 needed = bytes + pad_bytes;
327 needed += (needed / 64 + (needed % 64 ? 1 : 0)) * strlenW(sep);
328 needed++;
329
330 if (needed > *out_len)
331 {
332 *out_len = needed;
334 }
335 else
336 *out_len = needed;
337
338 /* Three bytes of input give 4 chars of output */
339 div = in_len / 3;
340
341 ptr = out_buf;
342 i = 0;
343 while (div > 0)
344 {
345 if (i && i % 64 == 0)
346 {
347 strcpyW(ptr, sep);
348 ptr += strlenW(sep);
349 }
350 /* first char is the first 6 bits of the first byte*/
351 *ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
352 /* second char is the last 2 bits of the first byte and the first 4
353 * bits of the second byte */
354 *ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)];
355 /* third char is the last 4 bits of the second byte and the first 2
356 * bits of the third byte */
357 *ptr++ = b64[ ((d[1] << 2) & 0x3c) | (d[2] >> 6 & 0x03)];
358 /* fourth char is the remaining 6 bits of the third byte */
359 *ptr++ = b64[ d[2] & 0x3f];
360 i += 4;
361 d += 3;
362 div--;
363 }
364
365 switch(pad_bytes)
366 {
367 case 1:
368 /* first char is the first 6 bits of the first byte*/
369 *ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
370 /* second char is the last 2 bits of the first byte and the first 4
371 * bits of the second byte */
372 *ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)];
373 /* third char is the last 4 bits of the second byte padded with
374 * two zeroes */
375 *ptr++ = b64[ ((d[1] << 2) & 0x3c) ];
376 /* fourth char is a = to indicate one byte of padding */
377 *ptr++ = '=';
378 break;
379 case 2:
380 /* first char is the first 6 bits of the first byte*/
381 *ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
382 /* second char is the last 2 bits of the first byte padded with
383 * four zeroes*/
384 *ptr++ = b64[ ((d[0] << 4) & 0x30)];
385 /* third char is = to indicate padding */
386 *ptr++ = '=';
387 /* fourth char is = to indicate padding */
388 *ptr++ = '=';
389 break;
390 }
391 strcpyW(ptr, sep);
392
393 return ERROR_SUCCESS;
394}
395
396static BOOL BinaryToBase64W(const BYTE *pbBinary,
398{
399 static const WCHAR crlf[] = { '\r','\n',0 }, lf[] = { '\n',0 }, empty[] = {0};
400 BOOL ret = TRUE;
401 LPCWSTR header = NULL, trailer = NULL, sep;
402 DWORD charsNeeded;
403
405 sep = lf;
406 else if (dwFlags & CRYPT_STRING_NOCRLF)
407 sep = empty;
408 else
409 sep = crlf;
410 switch (dwFlags & 0x0fffffff)
411 {
413 /* no header or footer */
414 break;
417 trailer = CERT_TRAILER_W;
418 break;
421 trailer = CERT_REQUEST_TRAILER_W;
422 break;
425 trailer = X509_TRAILER_W;
426 break;
427 }
428
429 charsNeeded = 0;
430 encodeBase64W(pbBinary, cbBinary, sep, NULL, &charsNeeded);
431 if (header)
432 charsNeeded += strlenW(header) + strlenW(sep);
433 if (trailer)
434 charsNeeded += strlenW(trailer) + strlenW(sep);
435
436 if (pszString)
437 {
438 if (charsNeeded <= *pcchString)
439 {
441 DWORD size = charsNeeded;
442
443 if (header)
444 {
446 ptr += strlenW(ptr);
447 strcpyW(ptr, sep);
448 ptr += strlenW(sep);
449 }
450 encodeBase64W(pbBinary, cbBinary, sep, ptr, &size);
451 ptr += size - 1;
452 if (trailer)
453 {
454 strcpyW(ptr, trailer);
455 ptr += strlenW(ptr);
456 strcpyW(ptr, sep);
457 }
458 *pcchString = charsNeeded - 1;
459 }
460 else
461 {
462 *pcchString = charsNeeded;
464 ret = FALSE;
465 }
466 }
467 else
468 *pcchString = charsNeeded;
469
470 return ret;
471}
472
475{
476 BinaryToStringWFunc encoder = NULL;
477
478 TRACE("(%p, %d, %08x, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString,
479 pcchString);
480
481 if (!pbBinary)
482 {
484 return FALSE;
485 }
486 if (!pcchString)
487 {
489 return FALSE;
490 }
491
492 switch (dwFlags & 0x0fffffff)
493 {
495 encoder = EncodeBinaryToBinaryW;
496 break;
501 encoder = BinaryToBase64W;
502 break;
503 case CRYPT_STRING_HEX:
507 FIXME("Unimplemented type %d\n", dwFlags & 0x0fffffff);
508 /* fall through */
509 default:
511 return FALSE;
512 }
513 return encoder(pbBinary, cbBinary, dwFlags, pszString, pcchString);
514}
515
516#define BASE64_DECODE_PADDING 0x100
517#define BASE64_DECODE_WHITESPACE 0x200
518#define BASE64_DECODE_INVALID 0x300
519
520static inline int decodeBase64Byte(int c)
521{
523
524 if (c >= 'A' && c <= 'Z')
525 ret = c - 'A';
526 else if (c >= 'a' && c <= 'z')
527 ret = c - 'a' + 26;
528 else if (c >= '0' && c <= '9')
529 ret = c - '0' + 52;
530 else if (c == '+')
531 ret = 62;
532 else if (c == '/')
533 ret = 63;
534 else if (c == '=')
536 else if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
538 return ret;
539}
540
541/* Unlike CryptStringToBinaryA, cchString is guaranteed to be the length of the
542 * string to convert.
543 */
545 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags);
546
547static LONG Base64ToBinary(const void* pszString, BOOL wide, DWORD cchString,
548 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
549{
550 DWORD cbIn, cbValid, cbOut, hasPadding;
551 BYTE block[4];
552 for (cbIn = cbValid = cbOut = hasPadding = 0; cbIn < cchString; ++cbIn)
553 {
554 int c = wide ? (int)((WCHAR*)pszString)[cbIn] : (int)((char*)pszString)[cbIn];
555 int d = decodeBase64Byte(c);
557 goto invalid;
559 continue;
560
561 /* When padding starts, data is not acceptable */
562 if (hasPadding && d != BASE64_DECODE_PADDING)
563 goto invalid;
564
565 /* Padding after a full block (like "VVVV=") is ok and stops decoding */
566 if (d == BASE64_DECODE_PADDING && (cbValid & 3) == 0)
567 break;
568
569 cbValid += 1;
570
572 {
573 hasPadding = 1;
574 /* When padding reaches a full block, stop decoding */
575 if ((cbValid & 3) == 0)
576 break;
577 continue;
578 }
579
580 /* cbOut is incremented in the 4-char block as follows: "1-23" */
581 if ((cbValid & 3) != 2)
582 cbOut += 1;
583 }
584 /* Fail if the block has bad padding; omitting padding is fine */
585 if ((cbValid & 3) != 0 && hasPadding)
586 goto invalid;
587 /* Check available buffer size */
588 if (pbBinary && *pcbBinary && cbOut > *pcbBinary)
589 goto overflow;
590 /* Convert the data; this step depends on the validity checks above! */
591 if (pbBinary) for (cbIn = cbValid = cbOut = 0; cbIn < cchString; ++cbIn)
592 {
593 int c = wide ? (int)((WCHAR*)pszString)[cbIn] : (int)((char*)pszString)[cbIn];
594 int d = decodeBase64Byte(c);
596 continue;
598 break;
599 block[cbValid & 3] = d;
600 cbValid += 1;
601 switch (cbValid & 3) {
602 case 1:
603 pbBinary[cbOut++] = (block[0] << 2);
604 break;
605 case 2:
606 pbBinary[cbOut-1] = (block[0] << 2) | (block[1] >> 4);
607 break;
608 case 3:
609 pbBinary[cbOut++] = (block[1] << 4) | (block[2] >> 2);
610 break;
611 case 0:
612 pbBinary[cbOut++] = (block[2] << 6) | (block[3] >> 0);
613 break;
614 }
615 }
616 *pcbBinary = cbOut;
617 if (pdwSkip)
618 *pdwSkip = 0;
619 if (pdwFlags)
620 *pdwFlags = CRYPT_STRING_BASE64;
621 return ERROR_SUCCESS;
622overflow:
624invalid:
625 *pcbBinary = cbOut;
626 return ERROR_INVALID_DATA;
627}
628
630 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
631{
632 return Base64ToBinary(pszString, FALSE, cchString, pbBinary, pcbBinary, pdwSkip, pdwFlags);
633}
634
636 DWORD cchString, BYTE *pbBinary,
637 DWORD *pcbBinary, DWORD *pdwSkip)
638{
639 LONG ret;
641 LPCSTR trailer = CERT_TRAILER_START;
642
643 LPCSTR headerBegins;
644 LPCSTR dataBegins;
645 LPCSTR trailerBegins;
646 size_t dataLength;
647
648 if ((strlen(header) + strlen(trailer)) > cchString)
649 {
650 return ERROR_INVALID_DATA;
651 }
652
653 if (!(headerBegins = strstr(pszString, header)))
654 {
655 TRACE("Can't find %s in %s.\n", header, debugstr_an(pszString, cchString));
656 return ERROR_INVALID_DATA;
657 }
658
659 dataBegins = headerBegins + strlen(header);
660 if (!(dataBegins = strstr(dataBegins, CERT_DELIMITER)))
661 {
662 return ERROR_INVALID_DATA;
663 }
664 dataBegins += strlen(CERT_DELIMITER);
665 if (*dataBegins == '\r') dataBegins++;
666 if (*dataBegins == '\n') dataBegins++;
667
668 if (!(trailerBegins = strstr(dataBegins, trailer)))
669 {
670 return ERROR_INVALID_DATA;
671 }
672 if (*(trailerBegins-1) == '\n') trailerBegins--;
673 if (*(trailerBegins-1) == '\r') trailerBegins--;
674
675 if (pdwSkip)
676 *pdwSkip = headerBegins - pszString;
677
678 dataLength = trailerBegins - dataBegins;
679
680 ret = Base64ToBinaryA(dataBegins, dataLength, pbBinary, pcbBinary, NULL,
681 NULL);
682
683 return ret;
684}
685
687 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
688{
690 pbBinary, pcbBinary, pdwSkip);
691
692 if (!ret && pdwFlags)
693 *pdwFlags = CRYPT_STRING_BASE64HEADER;
694 return ret;
695}
696
698 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
699{
701 pbBinary, pcbBinary, pdwSkip);
702
703 if (!ret && pdwFlags)
705 return ret;
706}
707
709 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
710{
712 pbBinary, pcbBinary, pdwSkip);
713
714 if (!ret && pdwFlags)
716 return ret;
717}
718
720 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
721{
722 LONG ret;
723
724 ret = Base64HeaderToBinaryA(pszString, cchString, pbBinary, pcbBinary,
725 pdwSkip, pdwFlags);
726 if (ret == ERROR_INVALID_DATA)
727 ret = Base64ToBinaryA(pszString, cchString, pbBinary, pcbBinary,
728 pdwSkip, pdwFlags);
729 return ret;
730}
731
733 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
734{
736
737 if (*pcbBinary < cchString)
738 {
739 if (!pbBinary)
740 *pcbBinary = cchString;
741 else
742 {
744 *pcbBinary = cchString;
745 }
746 }
747 else
748 {
749 if (cchString)
750 memcpy(pbBinary, pszString, cchString);
751 *pcbBinary = cchString;
752 }
753 return ret;
754}
755
757 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
758{
759 LONG ret;
760
761 ret = Base64HeaderToBinaryA(pszString, cchString, pbBinary, pcbBinary,
762 pdwSkip, pdwFlags);
763 if (ret == ERROR_INVALID_DATA)
764 ret = Base64ToBinaryA(pszString, cchString, pbBinary, pcbBinary,
765 pdwSkip, pdwFlags);
766 if (ret == ERROR_INVALID_DATA)
767 ret = DecodeBinaryToBinaryA(pszString, cchString, pbBinary, pcbBinary,
768 pdwSkip, pdwFlags);
769 return ret;
770}
771
773 DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary,
774 DWORD *pdwSkip, DWORD *pdwFlags)
775{
776 StringToBinaryAFunc decoder;
777 LONG ret;
778
779 TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_an(pszString, cchString ? cchString : -1),
780 cchString, dwFlags, pbBinary, pcbBinary, pdwSkip, pdwFlags);
781
782 if (!pszString)
783 {
785 return FALSE;
786 }
787 /* Only the bottom byte contains valid types */
788 if (dwFlags & 0xfffffff0)
789 {
791 return FALSE;
792 }
793 switch (dwFlags)
794 {
796 decoder = Base64AnyToBinaryA;
797 break;
799 decoder = Base64ToBinaryA;
800 break;
802 decoder = Base64HeaderToBinaryA;
803 break;
806 break;
809 break;
811 decoder = DecodeBinaryToBinaryA;
812 break;
813 case CRYPT_STRING_ANY:
814 decoder = DecodeAnyA;
815 break;
816 case CRYPT_STRING_HEX:
820 FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff);
821 /* fall through */
822 default:
824 return FALSE;
825 }
826 if (!cchString)
827 cchString = strlen(pszString);
828 ret = decoder(pszString, cchString, pbBinary, pcbBinary, pdwSkip, pdwFlags);
829 if (ret)
831 return ret == ERROR_SUCCESS;
832}
833
834/* Unlike CryptStringToBinaryW, cchString is guaranteed to be the length of the
835 * string to convert.
836 */
838 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags);
839
841 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
842{
843 return Base64ToBinary(pszString, TRUE, cchString, pbBinary, pcbBinary, pdwSkip, pdwFlags);
844}
845
847 DWORD cchString, BYTE *pbBinary,
848 DWORD *pcbBinary, DWORD *pdwSkip)
849{
850 LONG ret;
853
854 LPCWSTR headerBegins;
855 LPCWSTR dataBegins;
856 LPCWSTR trailerBegins;
857 size_t dataLength;
858
859 if ((strlenW(header) + strlenW(trailer)) > cchString)
860 {
861 return ERROR_INVALID_DATA;
862 }
863
864 if (!(headerBegins = strstrW(pszString, header)))
865 {
866 TRACE("Can't find %s in %s.\n", debugstr_w(header), debugstr_wn(pszString, cchString));
867 return ERROR_INVALID_DATA;
868 }
869
870 dataBegins = headerBegins + strlenW(header);
871 if (!(dataBegins = strstrW(dataBegins, CERT_DELIMITER_W)))
872 {
873 return ERROR_INVALID_DATA;
874 }
875 dataBegins += strlenW(CERT_DELIMITER_W);
876 if (*dataBegins == '\r') dataBegins++;
877 if (*dataBegins == '\n') dataBegins++;
878
879 if (!(trailerBegins = strstrW(dataBegins, trailer)))
880 {
881 return ERROR_INVALID_DATA;
882 }
883 if (*(trailerBegins-1) == '\n') trailerBegins--;
884 if (*(trailerBegins-1) == '\r') trailerBegins--;
885
886 if (pdwSkip)
887 *pdwSkip = headerBegins - pszString;
888
889 dataLength = trailerBegins - dataBegins;
890
891 ret = Base64ToBinaryW(dataBegins, dataLength, pbBinary, pcbBinary, NULL,
892 NULL);
893
894 return ret;
895}
896
898 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
899{
901 pbBinary, pcbBinary, pdwSkip);
902
903 if (!ret && pdwFlags)
904 *pdwFlags = CRYPT_STRING_BASE64HEADER;
905 return ret;
906}
907
909 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
910{
912 pbBinary, pcbBinary, pdwSkip);
913
914 if (!ret && pdwFlags)
916 return ret;
917}
918
920 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
921{
923 pbBinary, pcbBinary, pdwSkip);
924
925 if (!ret && pdwFlags)
927 return ret;
928}
929
931 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
932{
933 LONG ret;
934
935 ret = Base64HeaderToBinaryW(pszString, cchString, pbBinary, pcbBinary,
936 pdwSkip, pdwFlags);
937 if (ret == ERROR_INVALID_DATA)
938 ret = Base64ToBinaryW(pszString, cchString, pbBinary, pcbBinary,
939 pdwSkip, pdwFlags);
940 return ret;
941}
942
944 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
945{
947
948 if (*pcbBinary < cchString)
949 {
950 if (!pbBinary)
951 *pcbBinary = cchString;
952 else
953 {
955 *pcbBinary = cchString;
956 }
957 }
958 else
959 {
960 if (cchString)
961 memcpy(pbBinary, pszString, cchString * sizeof(WCHAR));
962 *pcbBinary = cchString * sizeof(WCHAR);
963 }
964 return ret;
965}
966
968 BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
969{
970 LONG ret;
971
972 ret = Base64HeaderToBinaryW(pszString, cchString, pbBinary, pcbBinary,
973 pdwSkip, pdwFlags);
974 if (ret == ERROR_INVALID_DATA)
975 ret = Base64ToBinaryW(pszString, cchString, pbBinary, pcbBinary,
976 pdwSkip, pdwFlags);
977 if (ret == ERROR_INVALID_DATA)
978 ret = DecodeBinaryToBinaryW(pszString, cchString, pbBinary, pcbBinary,
979 pdwSkip, pdwFlags);
980 return ret;
981}
982
984 DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary,
985 DWORD *pdwSkip, DWORD *pdwFlags)
986{
987 StringToBinaryWFunc decoder;
988 LONG ret;
989
990 TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_wn(pszString, cchString ? cchString : -1),
991 cchString, dwFlags, pbBinary, pcbBinary, pdwSkip, pdwFlags);
992
993 if (!pszString)
994 {
996 return FALSE;
997 }
998 /* Only the bottom byte contains valid types */
999 if (dwFlags & 0xfffffff0)
1000 {
1002 return FALSE;
1003 }
1004 switch (dwFlags)
1005 {
1007 decoder = Base64AnyToBinaryW;
1008 break;
1010 decoder = Base64ToBinaryW;
1011 break;
1013 decoder = Base64HeaderToBinaryW;
1014 break;
1017 break;
1019 decoder = Base64X509HeaderToBinaryW;
1020 break;
1022 decoder = DecodeBinaryToBinaryW;
1023 break;
1024 case CRYPT_STRING_ANY:
1025 decoder = DecodeAnyW;
1026 break;
1027 case CRYPT_STRING_HEX:
1031 FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff);
1032 /* fall through */
1033 default:
1035 return FALSE;
1036 }
1037 if (!cchString)
1038 cchString = strlenW(pszString);
1039 ret = decoder(pszString, cchString, pbBinary, pcbBinary, pdwSkip, pdwFlags);
1040 if (ret)
1042 return ret == ERROR_SUCCESS;
1043}
_STLP_VENDOR_CSTD::ldiv_t div(long __x, long __y)
Definition: _cstdlib.h:137
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#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
static const WCHAR CERT_REQUEST_TRAILER_W[]
Definition: base64.c:57
static const WCHAR CERT_TRAILER_W[]
Definition: base64.c:49
BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString)
Definition: base64.c:473
static LONG Base64HeaderToBinaryW(LPCWSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:897
static LONG Base64RequestHeaderToBinaryA(LPCSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:697
#define CERT_HEADER_START
Definition: base64.c:33
static const WCHAR CERT_DELIMITER_W[]
Definition: base64.c:47
LONG(* StringToBinaryWFunc)(LPCWSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:837
BOOL WINAPI CryptStringToBinaryW(LPCWSTR pszString, DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:983
static LONG Base64HeaderToBinaryA(LPCSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:686
static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep, char *out_buf, DWORD *out_len)
Definition: base64.c:96
LONG(* StringToBinaryAFunc)(LPCSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:544
static LONG Base64ToBinaryA(LPCSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:629
static BOOL EncodeBinaryToBinaryW(const BYTE *in_buf, DWORD in_len, DWORD flags, WCHAR *out_buf, DWORD *out_len)
Definition: base64.c:296
#define X509_TRAILER
Definition: base64.c:40
#define BASE64_DECODE_PADDING
Definition: base64.c:516
static const WCHAR CERT_HEADER_W[]
Definition: base64.c:42
static LONG Base64WithHeaderAndTrailerToBinaryW(LPCWSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip)
Definition: base64.c:846
BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString, DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:772
static LONG Base64AnyToBinaryA(LPCSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:719
#define CERT_TRAILER_START
Definition: base64.c:36
static LONG Base64RequestHeaderToBinaryW(LPCWSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:908
static LONG DecodeAnyA(LPCSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:756
static LONG Base64AnyToBinaryW(LPCWSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:930
static LONG Base64X509HeaderToBinaryW(LPCWSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:919
static LONG Base64ToBinaryW(LPCWSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:840
#define CERT_TRAILER
Definition: base64.c:35
static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep, WCHAR *out_buf, DWORD *out_len)
Definition: base64.c:316
BOOL(* BinaryToStringAFunc)(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString)
Definition: base64.c:70
static LONG DecodeBinaryToBinaryW(LPCWSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:943
static BOOL EncodeBinaryToBinaryA(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString)
Definition: base64.c:75
static int decodeBase64Byte(int c)
Definition: base64.c:520
static LONG Base64ToBinary(const void *pszString, BOOL wide, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:547
static const WCHAR X509_HEADER_W[]
Definition: base64.c:60
static const WCHAR X509_TRAILER_W[]
Definition: base64.c:63
static LONG Base64X509HeaderToBinaryA(LPCSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:708
#define BASE64_DECODE_WHITESPACE
Definition: base64.c:517
#define CERT_REQUEST_HEADER
Definition: base64.c:37
static BOOL BinaryToBase64W(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString)
Definition: base64.c:396
static LONG Base64WithHeaderAndTrailerToBinaryA(LPCSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip)
Definition: base64.c:635
#define X509_HEADER
Definition: base64.c:39
static const char b64[]
Definition: base64.c:67
#define BASE64_DECODE_INVALID
Definition: base64.c:518
static LONG DecodeAnyW(LPCWSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:967
BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString)
Definition: base64.c:253
static LONG DecodeBinaryToBinaryA(LPCSTR pszString, DWORD cchString, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
Definition: base64.c:732
static const WCHAR CERT_TRAILER_START_W[]
Definition: base64.c:52
static const WCHAR CERT_REQUEST_HEADER_W[]
Definition: base64.c:54
#define CERT_DELIMITER
Definition: base64.c:34
static const WCHAR CERT_HEADER_START_W[]
Definition: base64.c:45
#define CERT_HEADER
Definition: base64.c:32
static BOOL BinaryToBase64A(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString)
Definition: base64.c:176
BOOL(* BinaryToStringWFunc)(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString)
Definition: base64.c:72
#define CERT_REQUEST_TRAILER
Definition: base64.c:38
static const WCHAR crlf[]
Definition: object.c:1018
static const WCHAR empty[]
Definition: main.c:47
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLbitfield flags
Definition: glext.h:7161
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
#define d
Definition: ke_i.h:81
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR invalid[]
Definition: assoc.c:39
#define BOOL
Definition: nt_native.h:43
long LONG
Definition: pedump.c:60
#define strstrW(d, s)
Definition: unicode.h:38
#define strlenW(s)
Definition: unicode.h:34
#define strcpyW(d, s)
Definition: unicode.h:35
ULONG dataLength
Definition: scsi.h:3751
#define TRACE(s)
Definition: solgame.cpp:4
int ret
#define CRYPT_STRING_BINARY
Definition: wincrypt.h:2986
#define CRYPT_STRING_BASE64X509CRLHEADER
Definition: wincrypt.h:2993
_In_ DWORD cbBinary
Definition: wincrypt.h:4503
#define CRYPT_STRING_HEXADDR
Definition: wincrypt.h:2994
#define CRYPT_STRING_BASE64REQUESTHEADER
Definition: wincrypt.h:2987
#define CRYPT_STRING_BASE64HEADER
Definition: wincrypt.h:2984
#define CRYPT_STRING_HEX
Definition: wincrypt.h:2988
#define CRYPT_STRING_BASE64
Definition: wincrypt.h:2985
#define CRYPT_STRING_BASE64_ANY
Definition: wincrypt.h:2990
_In_ DWORD _In_ DWORD _Out_writes_to_opt_ pcchString LPSTR pszString
Definition: wincrypt.h:4505
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define CRYPT_STRING_HEXASCII
Definition: wincrypt.h:2989
#define CRYPT_STRING_NOCRLF
Definition: wincrypt.h:2996
_In_ DWORD _In_ DWORD _Out_writes_to_opt_ pcchString LPSTR _Inout_ DWORD * pcchString
Definition: wincrypt.h:4506
#define CRYPT_STRING_ANY
Definition: wincrypt.h:2991
#define CRYPT_STRING_NOCR
Definition: wincrypt.h:2997
#define CRYPT_STRING_HEXASCIIADDR
Definition: wincrypt.h:2995
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_DATA
Definition: winerror.h:116
static unsigned int block
Definition: xmlmemory.c:101
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193