*** empty log message ***
[gnutls.git] / libextra / auth_srp_sb64.c
blobf3b90fb550fd8a59249a9a7f366f64ac3253eb5b
1 /*
2 * Copyright (C) 2001 Nikos Mavroyanopoulos <nmav@hellug.gr>
4 * This file is part of GNUTLS.
6 * GNUTLS-EXTRA is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNUTLS-EXTRA is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 #include "gnutls_int.h"
23 #ifdef ENABLE_SRP
25 /* this a modified base64 for srp !!!
26 * It seems that everybody makes it's own base64 convertion.
28 const static uint8 b64table[64] =
29 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
31 const static uint8 asciitable[128] = {
32 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
33 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
34 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
35 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
36 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
37 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
38 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
39 0xff, 0xff, 0xff, 0xff, 0x3e, 0x3f,
40 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
41 0x06, 0x07, 0x08, 0x09, 0xff, 0xff,
42 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a,
43 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
44 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
45 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
46 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
47 0x23, 0xff, 0xff, 0xff, 0xff, 0xff,
48 0xff, 0x24, 0x25, 0x26, 0x27, 0x28,
49 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
50 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
51 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
52 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff,
53 0xff, 0xff
56 inline static int encode(uint8 * result, const uint8 * rdata, int left)
59 int data_len;
60 int c, ret = 4;
61 uint8 data[3];
63 if (left > 3)
64 data_len = 3;
65 else
66 data_len = left;
68 data[0] = data[1] = data[2] = 0;
69 memcpy(data, rdata, data_len);
71 switch (data_len) {
72 case 3:
73 result[0] = b64table[((data[0] & 0xfc) >> 2)];
74 result[1] =
75 b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff) |
76 ((data[1] & 0xf0) >> 4))];
77 result[2] =
78 b64table[((((data[1] & 0x0f) << 2) & 0xff) |
79 ((data[2] & 0xc0) >> 6))];
80 result[3] = b64table[(data[2] & 0x3f) & 0xff];
81 break;
82 case 2:
83 if ((c = ((data[0] & 0xf0) >> 4)) != 0) {
84 result[0] = b64table[c];
85 result[1] =
86 b64table[((((data[0] & 0x0f) << 2) & 0xff) |
87 ((data[1] & 0xc0) >> 6))];
88 result[2] = b64table[(data[1] & 0x3f) & 0xff];
89 result[3] = '\0';
90 ret -= 1;
91 } else {
92 if ((c =
93 ((data[0] & 0x0f) << 2) | ((data[1] & 0xc0) >>
94 6)) != 0) {
95 result[0] = b64table[c];
96 result[1] = b64table[data[1] & 0x3f];
97 result[2] = '\0';
98 result[3] = '\0';
99 ret -= 2;
100 } else {
101 result[0] = b64table[data[0] & 0x3f];
102 result[1] = '\0';
103 result[2] = '\0';
104 result[3] = '\0';
105 ret -= 3;
108 break;
109 case 1:
110 if ((c = ((data[0] & 0xc0) >> 6)) != 0) {
111 result[0] = b64table[c];
112 result[1] = b64table[(data[0] & 0x3f) & 0xff];
113 result[2] = '\0';
114 result[3] = '\0';
115 ret -= 2;
116 } else {
117 result[0] = b64table[(data[0] & 0x3f) & 0xff];
118 result[1] = '\0';
119 result[2] = '\0';
120 result[3] = '\0';
121 ret -= 3;
123 break;
124 default:
125 return -1;
128 return ret;
132 /* encodes data and puts the result into result (localy alocated)
133 * The result_size is the return value
135 int _gnutls_sbase64_encode(uint8 * data, int data_size, uint8 ** result)
137 int ret, tmp, j, i;
138 char tmpres[4];
139 int mod = data_size % 3;
141 ret = mod;
142 if (ret != 0)
143 ret = 4;
144 else
145 ret = 0;
147 ret += (data_size * 4) / 3;
149 (*result) = gnutls_calloc( 1, ret + 1);
150 if ((*result) == NULL)
151 return -1;
153 i = j = 0;
154 /* encode the bytes that are not a multiple of 3
156 if (mod > 0) {
157 tmp = encode(tmpres, &data[0], mod);
158 if (tmp < 0) {
159 gnutls_free( (*result));
160 return tmp;
163 memcpy(&(*result)[0], tmpres, tmp);
164 i = mod;
165 j = tmp;
168 /* encode the rest
170 for (; i < data_size; i += 3, j += 4) {
171 tmp = encode(tmpres, &data[i], data_size - i);
172 if (tmp < 0) {
173 gnutls_free( (*result));
174 return tmp;
176 memcpy(&(*result)[j], tmpres, tmp);
179 return strlen(*result);
183 /* data must be 4 bytes
184 * result should be 3 bytes
186 #define TOASCII(c) (c < 127 ? asciitable[c] : 0xff)
187 inline static int decode(uint8 * result, const uint8 * data)
189 uint8 a1, a2;
190 int ret = 3;
192 memset( result, 0, 3);
194 a1 = TOASCII(data[3]);
195 a2 = TOASCII(data[2]);
196 if (a1 != 0xff) result[2] = a1 & 0xff;
197 else return -1;
198 if (a2 != 0xff) result[2] |= ((a2 & 0x03) << 6) & 0xff;
200 a1 = a2;
201 a2 = TOASCII(data[1]);
202 if (a1 != 0xff) result[1] = ((a1 & 0x3c) >> 2);
203 if (a2 != 0xff) result[1] |= ((a2 & 0x0f) << 4);
204 else if (a1==0xff || result[1] == 0) ret--;
206 a1 = a2;
207 a2 = TOASCII(data[0]);
208 if (a1 != 0xff) result[0] = (((a1 & 0x30) >> 4) & 0xff);
209 if (a2 != 0xff) result[0] |= ((a2 << 2) & 0xff);
210 else if (a1==0xff || result[0] == 0) ret--;
212 return ret;
215 /* decodes data and puts the result into result (localy alocated)
216 * The result_size is the return value.
217 * That function does not ignore newlines tabs etc. You should remove them
218 * before calling it.
220 int _gnutls_sbase64_decode(uint8 * data, int idata_size, uint8 ** result)
222 int i, ret, j, left;
223 int data_size, tmp;
224 uint8 datrev[4];
225 uint8 tmpres[3];
227 data_size = (idata_size/4)*4;
228 left = idata_size % 4;
230 ret = (data_size / 4) * 3;
232 if (left > 0)
233 ret += 3;
235 (*result) = gnutls_malloc(ret+1);
236 if ((*result) == NULL)
237 return -1;
239 /* the first "block" is treated with special care */
240 tmp = 0;
241 if (left > 0) {
242 memset( datrev, 0, 4);
243 memcpy( &datrev[4-left], data, left);
245 tmp = decode( tmpres, datrev);
246 if (tmp < 0) {
247 gnutls_free( (*result));
248 return tmp;
251 memcpy( *result, &tmpres[3-tmp], tmp);
252 if (tmp < 3)
253 ret -= (3 - tmp);
256 /* rest data */
257 for (i = left, j = tmp; i < idata_size; i += 4) {
258 tmp = decode(tmpres, &data[i]);
259 if (tmp < 0) {
260 gnutls_free( (*result));
261 return tmp;
263 memcpy(&(*result)[j], tmpres, tmp);
264 if (tmp < 3)
265 ret -= (3 - tmp);
266 j += 3;
269 return ret;
272 #ifdef B64_TEST
273 int main()
275 char x[100 * 1024];
276 int siz;
277 uint8 *b64;
279 /* for (i = 0; i < 128; i++) {
280 if (i % 6 == 0)
281 fprintf(stdout, "\n");
282 if (strchr(b64table, i) == NULL)
283 fprintf(stdout, "0x%.2x, ", 0xff);
284 else
285 fprintf(stdout, "0x%.2x, ",
286 (int) ((int) index(b64table, i) -
287 (int) b64table));
291 return 0;*/
292 siz = fread(x, 1, sizeof(x), stdin);
294 // siz = _gnutls_sbase64_encode(x, siz, &b64);
295 siz = _gnutls_sbase64_decode(x, siz, &b64);
298 if (siz < 0) {
299 _gnutls_log( "ERROR %d\n", siz);
300 exit(1);
303 fwrite(b64, siz, 1, stdout);
304 return 0;
308 #endif
310 #endif /* ENABLE_SRP */