~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/crypt32/base64.c

Version: ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  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 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 
 29 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
 30 
 31 #define CERT_HEADER          "-----BEGIN CERTIFICATE-----"
 32 #define CERT_TRAILER         "-----END CERTIFICATE-----"
 33 #define CERT_REQUEST_HEADER  "-----BEGIN NEW CERTIFICATE REQUEST-----"
 34 #define CERT_REQUEST_TRAILER "-----END NEW CERTIFICATE REQUEST-----"
 35 #define X509_HEADER          "-----BEGIN X509 CRL-----"
 36 #define X509_TRAILER         "-----END X509 CRL-----"
 37 
 38 static const char b64[] =
 39 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 40 
 41 typedef BOOL (*BinaryToStringAFunc)(const BYTE *pbBinary,
 42  DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString);
 43 
 44 static BOOL EncodeBinaryToBinaryA(const BYTE *pbBinary,
 45  DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString)
 46 {
 47     BOOL ret = TRUE;
 48 
 49     if (*pcchString < cbBinary)
 50     {
 51         if (!pszString)
 52             *pcchString = cbBinary;
 53         else
 54         {
 55             SetLastError(ERROR_INSUFFICIENT_BUFFER);
 56             *pcchString = cbBinary;
 57             ret = FALSE;
 58         }
 59     }
 60     else
 61     {
 62         if (cbBinary)
 63             memcpy(pszString, pbBinary, cbBinary);
 64         *pcchString = cbBinary;
 65     }
 66     return ret;
 67 }
 68 
 69 static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep,
 70  char* out_buf, DWORD *out_len)
 71 {
 72     int div, i;
 73     const BYTE *d = in_buf;
 74     int bytes = (in_len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0;
 75     DWORD needed;
 76     LPSTR ptr;
 77 
 78     TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes);
 79     needed = bytes + pad_bytes + 1;
 80     needed += (needed / 64 + 1) * strlen(sep);
 81 
 82     if (needed > *out_len)
 83     {
 84         *out_len = needed;
 85         return ERROR_INSUFFICIENT_BUFFER;
 86     }
 87     else
 88         *out_len = needed;
 89 
 90     /* Three bytes of input give 4 chars of output */
 91     div = in_len / 3;
 92 
 93     ptr = out_buf;
 94     i = 0;
 95     while (div > 0)
 96     {
 97         if (i && i % 64 == 0)
 98         {
 99             strcpy(ptr, sep);
100             ptr += strlen(sep);
101         }
102         /* first char is the first 6 bits of the first byte*/
103         *ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
104         /* second char is the last 2 bits of the first byte and the first 4
105          * bits of the second byte */
106         *ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)];
107         /* third char is the last 4 bits of the second byte and the first 2
108          * bits of the third byte */
109         *ptr++ = b64[ ((d[1] << 2) & 0x3c) | (d[2] >> 6 & 0x03)];
110         /* fourth char is the remaining 6 bits of the third byte */
111         *ptr++ = b64[   d[2]       & 0x3f];
112         i += 4;
113         d += 3;
114         div--;
115     }
116 
117     switch(pad_bytes)
118     {
119         case 1:
120             /* first char is the first 6 bits of the first byte*/
121             *ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
122             /* second char is the last 2 bits of the first byte and the first 4
123              * bits of the second byte */
124             *ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)];
125             /* third char is the last 4 bits of the second byte padded with
126              * two zeroes */
127             *ptr++ = b64[ ((d[1] << 2) & 0x3c) ];
128             /* fourth char is a = to indicate one byte of padding */
129             *ptr++ = '=';
130             break;
131         case 2:
132             /* first char is the first 6 bits of the first byte*/
133             *ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
134             /* second char is the last 2 bits of the first byte padded with
135              * four zeroes*/
136             *ptr++ = b64[ ((d[0] << 4) & 0x30)];
137             /* third char is = to indicate padding */
138             *ptr++ = '=';
139             /* fourth char is = to indicate padding */
140             *ptr++ = '=';
141             break;
142     }
143     strcpy(ptr, sep);
144 
145     return ERROR_SUCCESS;
146 }
147 
148 static BOOL BinaryToBase64A(const BYTE *pbBinary,
149  DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString)
150 {
151     static const char crlf[] = "\r\n", lf[] = "\n";
152     BOOL ret = TRUE;
153     LPCSTR header = NULL, trailer = NULL, sep = NULL;
154     DWORD charsNeeded;
155 
156     if (dwFlags & CRYPT_STRING_NOCR)
157         sep = lf;
158     else
159         sep = crlf;
160     switch (dwFlags & 0x7fffffff)
161     {
162     case CRYPT_STRING_BASE64:
163         /* no header or footer */
164         break;
165     case CRYPT_STRING_BASE64HEADER:
166         header = CERT_HEADER;
167         trailer = CERT_TRAILER;
168         break;
169     case CRYPT_STRING_BASE64REQUESTHEADER:
170         header = CERT_REQUEST_HEADER;
171         trailer = CERT_REQUEST_TRAILER;
172         break;
173     case CRYPT_STRING_BASE64X509CRLHEADER:
174         header = X509_HEADER;
175         trailer = X509_TRAILER;
176         break;
177     }
178 
179     charsNeeded = 0;
180     encodeBase64A(pbBinary, cbBinary, sep, NULL, &charsNeeded);
181     charsNeeded += strlen(sep);
182     if (header)
183         charsNeeded += strlen(header) + strlen(sep);
184     if (trailer)
185         charsNeeded += strlen(trailer) + strlen(sep);
186     if (charsNeeded <= *pcchString)
187     {
188         LPSTR ptr = pszString;
189         DWORD size = charsNeeded;
190 
191         if (header)
192         {
193             strcpy(ptr, header);
194             ptr += strlen(ptr);
195             strcpy(ptr, sep);
196             ptr += strlen(sep);
197         }
198         encodeBase64A(pbBinary, cbBinary, sep, ptr, &size);
199         ptr += size - 1;
200         if (trailer)
201         {
202             strcpy(ptr, trailer);
203             ptr += strlen(ptr);
204             strcpy(ptr, sep);
205             ptr += strlen(sep);
206         }
207         *pcchString = charsNeeded - 1;
208     }
209     else if (pszString)
210     {
211         *pcchString = charsNeeded;
212         SetLastError(ERROR_INSUFFICIENT_BUFFER);
213         ret = FALSE;
214     }
215     else
216         *pcchString = charsNeeded;
217     return ret;
218 }
219 
220 BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary,
221  DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString)
222 {
223     BinaryToStringAFunc encoder = NULL;
224 
225     TRACE("(%p, %d, %08x, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString,
226      pcchString);
227 
228     if (!pbBinary)
229     {
230         SetLastError(ERROR_INVALID_PARAMETER);
231         return FALSE;
232     }
233     if (!pcchString)
234     {
235         SetLastError(ERROR_INVALID_PARAMETER);
236         return FALSE;
237     }
238 
239     switch (dwFlags & 0x7fffffff)
240     {
241     case CRYPT_STRING_BINARY:
242         encoder = EncodeBinaryToBinaryA;
243         break;
244     case CRYPT_STRING_BASE64:
245     case CRYPT_STRING_BASE64HEADER:
246     case CRYPT_STRING_BASE64REQUESTHEADER:
247     case CRYPT_STRING_BASE64X509CRLHEADER:
248         encoder = BinaryToBase64A;
249         break;
250     case CRYPT_STRING_HEX:
251     case CRYPT_STRING_HEXASCII:
252     case CRYPT_STRING_HEXADDR:
253     case CRYPT_STRING_HEXASCIIADDR:
254         FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff);
255         /* fall through */
256     default:
257         SetLastError(ERROR_INVALID_PARAMETER);
258         return FALSE;
259     }
260     return encoder(pbBinary, cbBinary, dwFlags, pszString, pcchString);
261 }
262 
263 static inline BYTE decodeBase64Byte(char c)
264 {
265     BYTE ret;
266 
267     if (c >= 'A' && c <= 'Z')
268         ret = c - 'A';
269     else if (c >= 'a' && c <= 'z')
270         ret = c - 'a' + 26;
271     else if (c >= '' && c <= '9')
272         ret = c - '' + 52;
273     else if (c == '+')
274         ret = 62;
275     else if (c == '/')
276         ret = 63;
277     else
278         ret = 64;
279     return ret;
280 }
281 
282 static LONG decodeBase64Block(const char *in_buf, int in_len,
283  const char **nextBlock, PBYTE out_buf, DWORD *out_len)
284 {
285     int len = in_len, i;
286     const char *d = in_buf;
287     int  ip0, ip1, ip2, ip3;
288 
289     if (len < 4)
290         return ERROR_INVALID_DATA;
291 
292     i = 0;
293     if (d[2] == '=')
294     {
295         if ((ip0 = decodeBase64Byte(d[0])) > 63)
296             return ERROR_INVALID_DATA;
297         if ((ip1 = decodeBase64Byte(d[1])) > 63)
298             return ERROR_INVALID_DATA;
299 
300         if (out_buf)
301             out_buf[i] = (ip0 << 2) | (ip1 >> 4);
302         i++;
303     }
304     else if (d[3] == '=')
305     {
306         if ((ip0 = decodeBase64Byte(d[0])) > 63)
307             return ERROR_INVALID_DATA;
308         if ((ip1 = decodeBase64Byte(d[1])) > 63)
309             return ERROR_INVALID_DATA;
310         if ((ip2 = decodeBase64Byte(d[2])) > 63)
311             return ERROR_INVALID_DATA;
312 
313         if (out_buf)
314         {
315             out_buf[i + 0] = (ip0 << 2) | (ip1 >> 4);
316             out_buf[i + 1] = (ip1 << 4) | (ip2 >> 2);
317         }
318         i += 2;
319     }
320     else
321     {
322         if ((ip0 = decodeBase64Byte(d[0])) > 63)
323             return ERROR_INVALID_DATA;
324         if ((ip1 = decodeBase64Byte(d[1])) > 63)
325             return ERROR_INVALID_DATA;
326         if ((ip2 = decodeBase64Byte(d[2])) > 63)
327             return ERROR_INVALID_DATA;
328         if ((ip3 = decodeBase64Byte(d[3])) > 63)
329             return ERROR_INVALID_DATA;
330 
331         if (out_buf)
332         {
333             out_buf[i + 0] = (ip0 << 2) | (ip1 >> 4);
334             out_buf[i + 1] = (ip1 << 4) | (ip2 >> 2);
335             out_buf[i + 2] = (ip2 << 6) |  ip3;
336         }
337         i += 3;
338     }
339     if (len >= 6 && d[4] == '\r' && d[5] == '\n')
340         *nextBlock = d + 6;
341     else if (len >= 5 && d[4] == '\n')
342         *nextBlock = d + 5;
343     else if (len >= 4 && d[4])
344         *nextBlock = d + 4;
345     else
346         *nextBlock = NULL;
347     *out_len = i;
348     return ERROR_SUCCESS;
349 }
350 
351 /* Unlike CryptStringToBinaryA, cchString is guaranteed to be the length of the
352  * string to convert.
353  */
354 typedef LONG (*StringToBinaryAFunc)(LPCSTR pszString, DWORD cchString,
355  BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags);
356 
357 static LONG Base64ToBinaryA(LPCSTR pszString, DWORD cchString,
358  BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
359 {
360     LONG ret = ERROR_SUCCESS;
361     const char *nextBlock;
362     DWORD outLen = 0;
363 
364     nextBlock = pszString;
365     while (nextBlock && !ret)
366     {
367         DWORD len = 0;
368 
369         ret = decodeBase64Block(nextBlock, cchString - (nextBlock - pszString),
370          &nextBlock, pbBinary ? pbBinary + outLen : NULL, &len);
371         if (!ret)
372             outLen += len;
373         if (cchString - (nextBlock - pszString) <= 0)
374             nextBlock = NULL;
375     }
376     *pcbBinary = outLen;
377     if (!ret)
378     {
379         if (pdwSkip)
380             *pdwSkip = 0;
381         if (pdwFlags)
382             *pdwFlags = CRYPT_STRING_BASE64;
383     }
384     else if (ret == ERROR_INSUFFICIENT_BUFFER)
385     {
386         if (!pbBinary)
387             ret = ERROR_SUCCESS;
388     }
389     return ret;
390 }
391 
392 static LONG Base64WithHeaderAndTrailerToBinaryA(LPCSTR pszString,
393  DWORD cchString, LPCSTR header, LPCSTR trailer, BYTE *pbBinary,
394  DWORD *pcbBinary, DWORD *pdwSkip)
395 {
396     LONG ret;
397     LPCSTR ptr;
398 
399     if (cchString > strlen(header) + strlen(trailer)
400      && (ptr = strstr(pszString, header)) != NULL)
401     {
402         LPCSTR trailerSpot = pszString + cchString - strlen(trailer);
403 
404         if (pszString[cchString - 1] == '\n')
405         {
406             cchString--;
407             trailerSpot--;
408         }
409         if (pszString[cchString - 1] == '\r')
410         {
411             cchString--;
412             trailerSpot--;
413         }
414         if (!strncmp(trailerSpot, trailer, strlen(trailer)))
415         {
416             if (pdwSkip)
417                 *pdwSkip = ptr - pszString;
418             ptr += strlen(header);
419             if (*ptr == '\r') ptr++;
420             if (*ptr == '\n') ptr++;
421             cchString -= ptr - pszString + strlen(trailer);
422             ret = Base64ToBinaryA(ptr, cchString, pbBinary, pcbBinary, NULL,
423              NULL);
424         }
425         else
426             ret = ERROR_INVALID_DATA;
427     }
428     else
429         ret = ERROR_INVALID_DATA;
430     return ret;
431 }
432 
433 static LONG Base64HeaderToBinaryA(LPCSTR pszString, DWORD cchString,
434  BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
435 {
436     LONG ret = Base64WithHeaderAndTrailerToBinaryA(pszString, cchString,
437      CERT_HEADER, CERT_TRAILER, pbBinary, pcbBinary, pdwSkip);
438 
439     if (!ret && pdwFlags)
440         *pdwFlags = CRYPT_STRING_BASE64HEADER;
441     return ret;
442 }
443 
444 static LONG Base64RequestHeaderToBinaryA(LPCSTR pszString, DWORD cchString,
445  BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
446 {
447     LONG ret = Base64WithHeaderAndTrailerToBinaryA(pszString, cchString,
448      CERT_REQUEST_HEADER, CERT_REQUEST_TRAILER, pbBinary, pcbBinary, pdwSkip);
449 
450     if (!ret && pdwFlags)
451         *pdwFlags = CRYPT_STRING_BASE64REQUESTHEADER;
452     return ret;
453 }
454 
455 static LONG Base64X509HeaderToBinaryA(LPCSTR pszString, DWORD cchString,
456  BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
457 {
458     LONG ret = Base64WithHeaderAndTrailerToBinaryA(pszString, cchString,
459      X509_HEADER, X509_TRAILER, pbBinary, pcbBinary, pdwSkip);
460 
461     if (!ret && pdwFlags)
462         *pdwFlags = CRYPT_STRING_BASE64X509CRLHEADER;
463     return ret;
464 }
465 
466 static LONG Base64AnyToBinaryA(LPCSTR pszString, DWORD cchString,
467  BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
468 {
469     LONG ret;
470 
471     ret = Base64HeaderToBinaryA(pszString, cchString, pbBinary, pcbBinary,
472      pdwSkip, pdwFlags);
473     if (ret == ERROR_INVALID_DATA)
474         ret = Base64ToBinaryA(pszString, cchString, pbBinary, pcbBinary,
475          pdwSkip, pdwFlags);
476     return ret;
477 }
478 
479 static LONG DecodeBinaryToBinaryA(LPCSTR pszString, DWORD cchString,
480  BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
481 {
482     LONG ret = ERROR_SUCCESS;
483 
484     if (*pcbBinary < cchString)
485     {
486         if (!pbBinary)
487             *pcbBinary = cchString;
488         else
489         {
490             ret = ERROR_INSUFFICIENT_BUFFER;
491             *pcbBinary = cchString;
492         }
493     }
494     else
495     {
496         if (cchString)
497             memcpy(pbBinary, pszString, cchString);
498         *pcbBinary = cchString;
499     }
500     return ret;
501 }
502 
503 static LONG DecodeAnyA(LPCSTR pszString, DWORD cchString,
504  BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
505 {
506     LONG ret;
507 
508     ret = Base64HeaderToBinaryA(pszString, cchString, pbBinary, pcbBinary,
509      pdwSkip, pdwFlags);
510     if (ret == ERROR_INVALID_DATA)
511         ret = Base64ToBinaryA(pszString, cchString, pbBinary, pcbBinary,
512          pdwSkip, pdwFlags);
513     if (ret == ERROR_INVALID_DATA)
514         ret = DecodeBinaryToBinaryA(pszString, cchString, pbBinary, pcbBinary,
515          pdwSkip, pdwFlags);
516     return ret;
517 }
518 
519 BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString,
520  DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary,
521  DWORD *pdwSkip, DWORD *pdwFlags)
522 {
523     StringToBinaryAFunc decoder;
524     LONG ret;
525 
526     TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_a(pszString),
527      cchString, dwFlags, pbBinary, pcbBinary, pdwSkip, pdwFlags);
528 
529     if (!pszString)
530     {
531         SetLastError(ERROR_INVALID_PARAMETER);
532         return FALSE;
533     }
534     /* Only the bottom byte contains valid types */
535     if (dwFlags & 0xfffffff0)
536     {
537         SetLastError(ERROR_INVALID_DATA);
538         return FALSE;
539     }
540     switch (dwFlags)
541     {
542     case CRYPT_STRING_BASE64_ANY:
543         decoder = Base64AnyToBinaryA;
544         break;
545     case CRYPT_STRING_BASE64:
546         decoder = Base64ToBinaryA;
547         break;
548     case CRYPT_STRING_BASE64HEADER:
549         decoder = Base64HeaderToBinaryA;
550         break;
551     case CRYPT_STRING_BASE64REQUESTHEADER:
552         decoder = Base64RequestHeaderToBinaryA;
553         break;
554     case CRYPT_STRING_BASE64X509CRLHEADER:
555         decoder = Base64X509HeaderToBinaryA;
556         break;
557     case CRYPT_STRING_BINARY:
558         decoder = DecodeBinaryToBinaryA;
559         break;
560     case CRYPT_STRING_ANY:
561         decoder = DecodeAnyA;
562         break;
563     case CRYPT_STRING_HEX:
564     case CRYPT_STRING_HEXASCII:
565     case CRYPT_STRING_HEXADDR:
566     case CRYPT_STRING_HEXASCIIADDR:
567         FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff);
568         /* fall through */
569     default:
570         SetLastError(ERROR_INVALID_PARAMETER);
571         return FALSE;
572     }
573     if (!cchString)
574         cchString = strlen(pszString);
575     ret = decoder(pszString, cchString, pbBinary, pcbBinary, pdwSkip, pdwFlags);
576     if (ret)
577         SetLastError(ret);
578     return (ret == ERROR_SUCCESS) ? TRUE : FALSE;
579 }
580 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.