import cyrus-sasl-2.1.23
[cyrus-sasl.git] / java / CyrusSasl / SaslUtils.java
1 package CyrusSasl;
2
3 public abstract class SaslUtils
4 {
5
6         /**
7          * a static array that maps 6 bit integers to a specific char
8          */
9         private final static char enc_table[] = 
10         { 
11         //   0   1   2   3   4   5   6   7 
12                 'A','B','C','D','E','F','G','H', // 0 
13                 'I','J','K','L','M','N','O','P', // 1 
14                 'Q','R','S','T','U','V','W','X', // 2 
15                 'Y','Z','a','b','c','d','e','f', // 3 
16                 'g','h','i','j','k','l','m','n', // 4 
17                 'o','p','q','r','s','t','u','v', // 5 
18                 'w','x','y','z','0','1','2','3', // 6 
19                 '4','5','6','7','8','9','+','/'  // 7 
20         }; 
21         private final static byte dec_table[] = 
22         { 
23                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
24                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
25                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
26                 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
27                 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
28                 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
29                 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
30                 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
31                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
32                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
33                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
34                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
35                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
36                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
37                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
38                 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
39         }; 
40
41     /**
42      * Base 64 Encodes a String in byte[] form
43      *
44      * @param buf String to be encoded
45      *
46      * @return the encoded value in string form
47      */
48
49  
50         public static String 
51         encode64( byte buf[] ) 
52         {
53                 int i = 0; 
54                 StringBuffer buffer = new StringBuffer(); 
55                 int len = buf.length; 
56                 int delta =     len % 3; 
57                 byte a, b, c;
58                 for (int count = len / 3; count > 0; count--) 
59                 {
60                         a = buf[i++];
61                         b = buf[i++];
62                         c = buf[i++];
63                         buffer.append(enc_table[(a >>> 2) & 0x3F]); 
64                         buffer.append(enc_table[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); 
65                         buffer.append(enc_table[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]); 
66                         buffer.append(enc_table[c & 0x3F]); 
67
68                         /*                      if (i != 0 && i%57 == 0)
69                                                 buffer.append("\r\n");*/
70                 }
71
72                 if (delta == 1) 
73                 {
74                         a = buf[i++];
75                         buffer.append(enc_table[(a >>> 2) & 0x3F]); 
76                         buffer.append(enc_table[((a << 4) & 0x30)]); 
77                         buffer.append('='); 
78                         buffer.append('='); 
79                 }
80                 if (delta == 2) 
81                 {
82                         a = buf[i++];
83                         b = buf[i++];
84                         buffer.append(enc_table[(a >>> 2) & 0x3F]); 
85                         buffer.append(enc_table[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); 
86                         buffer.append(enc_table[((b << 2) & 0x3c)]); 
87                         buffer.append('='); 
88                 }
89
90                 /*buffer.append("\r\n");*/
91                 return buffer.toString(); 
92         }
93
94     /**
95      * Base 64 Encodes a String in String form
96      *
97      * @param s String to be encoded
98      *
99      * @return the encoded value in string form
100      */
101
102     public static String encode64( String s ) 
103     {
104       return encode64( s.getBytes() );  
105     }
106
107
108     /**
109      * Base 64 Decodes a byte[] string
110      * Ignores trailing whitespace and newlines
111      *
112      * @param buf buffer to be decoded
113      *
114      * @return the decoded value in byte[] form
115      */
116
117
118         public static byte[]
119         decode64( byte buf[] ) 
120         {
121                 int padCount = 0;
122                 int i, len = buf.length;
123                 int real_len = 0;
124
125                 for (i=len-1; i >= 0; --i)
126                 {
127                         if (buf[i] > ' ')
128                                 real_len++;
129
130                         if (buf[i] == 0x3D)
131                                 padCount++;
132                 }
133
134                 // Hmm - should this be a "bad format MIME" exception instead?
135                 if (real_len%4 != 0)
136                         throw new IllegalArgumentException("Length not a multiple of 4");
137
138                 int ret_len = (real_len/4)*3 - padCount;
139                 byte ret[] = new byte[ret_len];
140
141                 i = 0;
142                 byte[] t = new byte[4];
143                 int output_index = 0;
144                 int j = 0;
145                 t[0] = t[1] = t[2] = t[3] = 61; // Ascii =
146                 while (i < len)
147                 {
148                         byte c =  buf[i++];
149                         if (c > ' ')
150                                 t[j++] = c;
151
152                         if (j == 4)
153                         {
154                                 output_index += decode64(ret, output_index, t[0], t[1], t[2], t[3]);
155                                 j = 0;
156                                 t[0] = t[1] = t[2] = t[3] = 61; // Ascii =
157                         }
158                 }
159                 if (j > 0)
160                         decode64(ret, output_index, t[0], t[1], t[2], t[3]);
161
162                 return ret;
163         }
164
165     /**
166      * Base 64 Decodes a String
167      * Ignores trailing whitespace and newlines
168      *
169      * @param msg String to be decoded
170      *
171      * @return the decoded value in byte[] form
172      */
173
174     public static byte[] decode64( String msg ) 
175     {
176       return decode64( msg.getBytes());
177     }
178
179         // Returns the number of bytes converted
180         private static int
181         decode64( byte ret[], int ret_off, byte a, byte b, byte c, byte d )
182         {
183                 byte da = dec_table[a];
184                 byte db = dec_table[b];
185                 byte dc = dec_table[c];
186                 byte dd = dec_table[d];
187
188                 if (da == -1 || db == -1 || (dc == -1 && c != 0x3d) || (dd == -1 && d != 0x3d))
189                         throw new IllegalArgumentException("Invalid character ["+a+", "+b+", "+c+", "+d+"]");
190
191                 ret[ret_off++] = (byte)(da << 2 | db >>> 4);
192                 if (c == 0x3d)  // Ascii =
193                         return 1;
194                 ret[ret_off++] = (byte)(db << 4 | dc >>> 2);
195                 if (d == 0x3d)  // Ascii =
196                         return 2;
197                 ret[ret_off++] = (byte)(dc << 6 | dd);
198                         return 3;
199         }
200
201
202 }