Initial import from FreeBSD RELENG_4:
[dragonfly.git] / crypto / kerberosIV / appl / ftp / common / base64.c
1 /*
2  * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  * 
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by the Kungliga Tekniska
20  *      Högskolan and its contributors.
21  * 
22  * 4. Neither the name of the Institute nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  * 
26  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 RCSID("$Id: base64.c,v 1.6 1997/05/30 17:24:06 assar Exp $");
42 #endif
43 #include <stdlib.h>
44 #include <string.h>
45 #include "base64.h"
46
47 static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
48
49 static int pos(char c)
50 {
51   char *p;
52   for(p = base64; *p; p++)
53     if(*p == c)
54       return p - base64;
55   return -1;
56 }
57
58 int base64_encode(const void *data, int size, char **str)
59 {
60   char *s, *p;
61   int i;
62   int c;
63   unsigned char *q;
64
65   p = s = (char*)malloc(size*4/3+4);
66   q = (unsigned char*)data;
67   i=0;
68   for(i = 0; i < size;){
69     c=q[i++];
70     c*=256;
71     if(i < size)
72       c+=q[i];
73     i++;
74     c*=256;
75     if(i < size)
76       c+=q[i];
77     i++;
78     p[0]=base64[(c&0x00fc0000) >> 18];
79     p[1]=base64[(c&0x0003f000) >> 12];
80     p[2]=base64[(c&0x00000fc0) >> 6];
81     p[3]=base64[(c&0x0000003f) >> 0];
82     if(i > size)
83       p[3]='=';
84     if(i > size+1)
85       p[2]='=';
86     p+=4;
87   }
88   *p=0;
89   *str = s;
90   return strlen(s);
91 }
92
93 int base64_decode(const char *str, void *data)
94 {
95   const char *p;
96   unsigned char *q;
97   int c;
98   int x;
99   int done = 0;
100   q=(unsigned char*)data;
101   for(p=str; *p && !done; p+=4){
102     x = pos(p[0]);
103     if(x >= 0)
104       c = x;
105     else{
106       done = 3;
107       break;
108     }
109     c*=64;
110     
111     x = pos(p[1]);
112     if(x >= 0)
113       c += x;
114     else
115       return -1;
116     c*=64;
117     
118     if(p[2] == '=')
119       done++;
120     else{
121       x = pos(p[2]);
122       if(x >= 0)
123         c += x;
124       else
125         return -1;
126     }
127     c*=64;
128     
129     if(p[3] == '=')
130       done++;
131     else{
132       if(done)
133         return -1;
134       x = pos(p[3]);
135       if(x >= 0)
136         c += x;
137       else
138         return -1;
139     }
140     if(done < 3)
141       *q++=(c&0x00ff0000)>>16;
142       
143     if(done < 2)
144       *q++=(c&0x0000ff00)>>8;
145     if(done < 1)
146       *q++=(c&0x000000ff)>>0;
147   }
148   return q - (unsigned char*)data;
149 }