1 /*
2  * ImapProxy - a caching IMAP proxy daemon
3  * Copyright (C) 2002 Steven Van Acker
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  */
20 
21 
22 /*
23  * Ripped from http://www.episec.com/people/edelkind/arc/c/misc/base64.c
24  * Written by ari edelkind <edelkind-w@iownanisp.com>
25  *
26  */
27 
28 #include <string.h>
29 
30 char b64string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
31 
base64encode(char * to,char * from,unsigned int len)32 int base64encode (char *to, char *from, unsigned int len)
33 {
34 	char *fromp = from;
35 	char *top = to;
36 	unsigned char cbyte;
37 	unsigned char obyte;
38 	char end[3];
39 
40 	for (; len >= 3; len -= 3)
41 	{
42 	    cbyte = *fromp++;
43 		*top++ = b64string[(int)(cbyte >> 2)];
44 		obyte = (cbyte << 4) & 0x30;		/* 0011 0000 */
45 
46 		cbyte = *fromp++;
47 		obyte |= (cbyte >> 4);			/* 0000 1111 */
48 		*top++ = b64string[(int)obyte];
49 		obyte = (cbyte << 2) & 0x3C;		/* 0011 1100 */
50 
51 		cbyte = *fromp++;
52 		obyte |= (cbyte >> 6);			/* 0000 0011 */
53 		*top++ = b64string[(int)obyte];
54 		*top++ = b64string[(int)(cbyte & 0x3F)];/* 0011 1111 */
55 	}
56 
57 	if (len) {
58 		end[0] = *fromp++;
59 		if (--len) end[1] = *fromp++; else end[1] = 0;
60 		end[2] = 0;
61 
62 		cbyte = end[0];
63 		*top++ = b64string[(int)(cbyte >> 2)];
64 		obyte = (cbyte << 4) & 0x30;		/* 0011 0000 */
65 
66 		cbyte = end[1];
67 		obyte |= (cbyte >> 4);
68 		*top++ = b64string[(int)obyte];
69 		obyte = (cbyte << 2) & 0x3C;		/* 0011 1100 */
70 
71 		if (len) *top++ = b64string[(int)obyte];
72 		else *top++ = '=';
73 		*top++ = '=';
74 	}
75 	*top = 0;
76 	return top - to;
77 }
78 
79 /* badchar(): check if c is decent; puts either the */
80 /* location of c or null into p.                  */
81 #define badchar(c,p) (!(p = memchr(b64string, c, 64)))
82 
base64decode(char * to,char * from,unsigned int len)83 int base64decode (char *to, char *from, unsigned int len)
84 {
85 	char *fromp = from;
86 	char *top = to;
87 	char *p;
88 	unsigned char cbyte;
89 	unsigned char obyte;
90 	int padding = 0;
91 
92 	for (; len >= 4; len -= 4) {
93 		if ((cbyte = *fromp++) == '=') cbyte = 0;
94 		else {
95 			if (badchar(cbyte, p)) return -1;
96 			cbyte = (p - b64string);
97 		}
98 		obyte = cbyte << 2;		/* 1111 1100 */
99 
100 		if ((cbyte = *fromp++) == '=') cbyte = 0;
101 		else {
102 			if (badchar(cbyte, p)) return -1;
103 			cbyte = p - b64string;
104 		}
105 		obyte |= cbyte >> 4;		/* 0000 0011 */
106 		*top++ = obyte;
107 
108 		obyte = cbyte << 4;		/* 1111 0000 */
109 		if ((cbyte = *fromp++) == '=') { cbyte = 0; padding++; }
110 		else {
111 			padding = 0;
112 			if (badchar (cbyte, p)) return -1;
113 			cbyte = p - b64string;
114 		}
115 		obyte |= cbyte >> 2;		/* 0000 1111 */
116 		*top++ = obyte;
117 
118 		obyte = cbyte << 6;		/* 1100 0000 */
119 		if ((cbyte = *fromp++) == '=') { cbyte = 0; padding++; }
120 		else {
121 			padding = 0;
122 			if (badchar (cbyte, p)) return -1;
123 			cbyte = p - b64string;
124 		}
125 		obyte |= cbyte;			/* 0011 1111 */
126 		*top++ = obyte;
127 	}
128 
129 	*top = 0;
130 	if (len) return -1;
131 	return (top - to) - padding;
132 }
133 
134 
135