/* * b64dec.c * this file contains source to decode MIME base64 encoded strings. * * Author(s) * Unknown, hacked by Scott A. Leerssen, leerssen@issl.atl.hp.com * * Protection Notice * Copyright (c) 1997, Scott Leerssen, All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Last Update * 08 Aug 1998 * fixed whitespace skipping in rm_wspace * * 11 Aug 2000 * optimized a very stupid rm_wspace (thanks Rob) */ #include #include #include #include #if defined(WIN32) #define NULL 0 #endif #ifdef DMALLOC #include "dmalloc.h" #endif /* * rm_wspace * removes the whitespace from the string * * returns * malloc'd, whitespaceless string on success, NULL on failure * * arguments * s - string to smash whitspace from */ static char *rm_wspace(char *s) { char *newstr, *t, *p; int len = strlen(s); if (!(newstr = strdup(s))) { return(NULL); } for (p=s, t=newstr; *p; p++) { if (!isspace(*p)) { *t++ = *p; } } *t=0; return(newstr); } /* * b64ctoi * decodes a single MIME base64-encoded character * * returns * 6-bit value represented by the given MIME base64-encoded * character, 0 on pad character, EOF if not a valid encoding * character. * * arguments * c - 7-bit ascii character to be decoded */ static int b64ctoi(int c) { if (isupper(c)) return c - 'A'; else if (islower(c)) return c - 'a' + 26; else if (isdigit(c)) return c - '0' + 52; else if (c == '+') return 62; else if (c == '/') return 63; else if (c == '=') return 0; else return EOF; } /* * b64decode * Convert a base64-encoded string to plain-old-text. * * returns * Decoded string length as the return value, and the malloc'd, * base64 decoded string in the passed parameter. * * arguments * instr - string to decode * outstr - decoded string */ int b64decode(char *instr, char **outstr) { int val; char *cp; int i, c; char *xp; int outstr_len = 0; instr = rm_wspace(instr); i = strlen(instr); if (i <= 0 || (i % 4) != 0) { free(instr); return(NULL); } /* * For each 4 input chars, we get 3 output chars plus 1 more for * a terminator. */ outstr_len = ((i / 4) * 3) + 1; *outstr = (char *)malloc(outstr_len); if (!*outstr) { free(instr); return(NULL); } xp = *outstr; for (cp = instr; *cp; ) { val = 0; for (i = 0; i < 4; ++i) { if ((c = b64ctoi(*cp++)) == EOF) { free(*outstr); free(instr); return(NULL); } val |= c << ((3 -i) * 6); } for (i = 0; i < 3; ++i) *xp++ = (val >> (8 * (2 - i))) & 0xff; } *xp++ = '\0'; free(instr); return(outstr_len); }