2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
4 * Author: Nikos Mavroyanopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 #include <gnutls_int.h>
26 #include <gnutls_errors.h>
27 #include <gnutls_datum.h>
31 /* this a modified base64 for srp !!!
32 * It seems that everybody makes an own base64 conversion.
34 static const uint8_t b64table
[] =
35 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
37 static const uint8_t asciitable
[128] = {
38 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
39 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
40 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
41 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
42 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
43 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
44 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
45 0xff, 0xff, 0xff, 0xff, 0x3e, 0x3f,
46 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
47 0x06, 0x07, 0x08, 0x09, 0xff, 0xff,
48 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a,
49 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
50 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
51 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
52 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
53 0x23, 0xff, 0xff, 0xff, 0xff, 0xff,
54 0xff, 0x24, 0x25, 0x26, 0x27, 0x28,
55 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
56 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
57 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
58 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff,
63 encode (uint8_t * result
, const uint8_t * rdata
, int left
)
75 data
[0] = data
[1] = data
[2] = 0;
76 memcpy (data
, rdata
, data_len
);
81 result
[0] = b64table
[((data
[0] & 0xfc) >> 2)];
83 b64table
[(((((data
[0] & 0x03) & 0xff) << 4) & 0xff) |
84 ((data
[1] & 0xf0) >> 4))];
86 b64table
[((((data
[1] & 0x0f) << 2) & 0xff) |
87 ((data
[2] & 0xc0) >> 6))];
88 result
[3] = b64table
[(data
[2] & 0x3f) & 0xff];
91 if ((c
= ((data
[0] & 0xf0) >> 4)) != 0)
93 result
[0] = b64table
[c
];
95 b64table
[((((data
[0] & 0x0f) << 2) & 0xff) |
96 ((data
[1] & 0xc0) >> 6))];
97 result
[2] = b64table
[(data
[1] & 0x3f) & 0xff];
103 if ((c
= ((data
[0] & 0x0f) << 2) | ((data
[1] & 0xc0) >> 6)) != 0)
105 result
[0] = b64table
[c
];
106 result
[1] = b64table
[data
[1] & 0x3f];
113 result
[0] = b64table
[data
[0] & 0x3f];
122 if ((c
= ((data
[0] & 0xc0) >> 6)) != 0)
124 result
[0] = b64table
[c
];
125 result
[1] = b64table
[(data
[0] & 0x3f) & 0xff];
132 result
[0] = b64table
[(data
[0] & 0x3f) & 0xff];
147 /* encodes data and puts the result into result (locally allocated)
148 * The result_size is the return value
151 _gnutls_sbase64_encode (uint8_t * data
, size_t data_size
, uint8_t ** result
)
156 int mod
= data_size
% 3;
164 ret
+= (data_size
* 4) / 3;
166 (*result
) = gnutls_calloc (1, ret
+ 1);
167 if ((*result
) == NULL
)
171 /* encode the bytes that are not a multiple of 3
175 tmp
= encode (tmpres
, &data
[0], mod
);
178 gnutls_free ((*result
));
182 memcpy (&(*result
)[0], tmpres
, tmp
);
189 for (; i
< data_size
; i
+= 3, j
+= 4)
191 tmp
= encode (tmpres
, &data
[i
], data_size
- i
);
194 gnutls_free ((*result
));
197 memcpy (&(*result
)[j
], tmpres
, tmp
);
200 return strlen (*result
);
204 /* data must be 4 bytes
205 * result should be 3 bytes
207 #define TOASCII(c) (c < 127 ? asciitable[c] : 0xff)
209 decode (uint8_t * result
, const uint8_t * data
)
214 memset (result
, 0, 3);
216 a1
= TOASCII (data
[3]);
217 a2
= TOASCII (data
[2]);
219 result
[2] = a1
& 0xff;
223 result
[2] |= ((a2
& 0x03) << 6) & 0xff;
226 a2
= TOASCII (data
[1]);
228 result
[1] = ((a1
& 0x3c) >> 2);
230 result
[1] |= ((a2
& 0x0f) << 4);
231 else if (a1
== 0xff || result
[1] == 0)
235 a2
= TOASCII (data
[0]);
237 result
[0] = (((a1
& 0x30) >> 4) & 0xff);
239 result
[0] |= ((a2
<< 2) & 0xff);
240 else if (a1
== 0xff || result
[0] == 0)
246 /* decodes data and puts the result into result (locally allocated)
247 * The result_size is the return value.
248 * That function does not ignore newlines tabs etc. You should remove them
252 _gnutls_sbase64_decode (uint8_t * data
, size_t idata_size
, uint8_t ** result
)
260 data_size
= (idata_size
/ 4) * 4;
261 left
= idata_size
% 4;
263 ret
= (data_size
/ 4) * 3;
268 (*result
) = gnutls_malloc (ret
+ 1);
269 if ((*result
) == NULL
)
272 /* the first "block" is treated with special care */
276 memset (datrev
, 0, 4);
277 memcpy (&datrev
[4 - left
], data
, left
);
279 tmp
= decode (tmpres
, datrev
);
282 gnutls_free ((*result
));
287 memcpy (*result
, &tmpres
[3 - tmp
], tmp
);
293 for (i
= left
, j
= tmp
; i
< idata_size
; i
+= 4)
295 tmp
= decode (tmpres
, &data
[i
]);
298 gnutls_free ((*result
));
302 memcpy (&(*result
)[j
], tmpres
, tmp
);
312 * gnutls_srp_base64_encode - This function will convert raw data to base64 encoded
313 * @data: contain the raw data
314 * @result: the place where base64 data will be copied
315 * @result_size: holds the size of the result
317 * This function will convert the given data to printable data, using the base64
318 * encoding, as used in the libsrp. This is the encoding used in SRP password files.
319 * If the provided buffer is not long enough GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
323 gnutls_srp_base64_encode (const gnutls_datum_t
* data
, char *result
,
324 size_t * result_size
)
329 size
= _gnutls_sbase64_encode (data
->data
, data
->size
, &ret
);
333 if (result
== NULL
|| *result_size
< (size_t) size
)
337 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
341 memcpy (result
, ret
, size
);
350 * gnutls_srp_base64_encode_alloc - This function will convert raw data to Base64 encoded
351 * @data: contains the raw data
352 * @result: will hold the newly allocated encoded data
354 * This function will convert the given data to printable data, using the base64
355 * encoding. This is the encoding used in SRP password files. This function will
356 * allocate the required memory to hold the encoded data.
358 * You should use gnutls_free() to free the returned data.
362 gnutls_srp_base64_encode_alloc (const gnutls_datum_t
* data
,
363 gnutls_datum_t
* result
)
368 size
= _gnutls_sbase64_encode (data
->data
, data
->size
, &ret
);
375 return GNUTLS_E_INVALID_REQUEST
;
387 * gnutls_srp_base64_decode - This function will decode base64 encoded data
388 * @b64_data: contain the encoded data
389 * @result: the place where decoded data will be copied
390 * @result_size: holds the size of the result
392 * This function will decode the given encoded data, using the base64 encoding
395 * Note that b64_data should be null terminated.
397 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not long enough,
401 gnutls_srp_base64_decode (const gnutls_datum_t
* b64_data
, char *result
,
402 size_t * result_size
)
407 size
= _gnutls_sbase64_decode (b64_data
->data
, b64_data
->size
, &ret
);
411 if (result
== NULL
|| *result_size
< (size_t) size
)
415 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
419 memcpy (result
, ret
, size
);
428 * gnutls_srp_base64_decode_alloc - This function will decode base64 encoded data
429 * @b64_data: contains the encoded data
430 * @result: the place where decoded data lie
432 * This function will decode the given encoded data. The decoded data
433 * will be allocated, and stored into result.
434 * It will decode using the base64 algorithm found in libsrp.
436 * You should use gnutls_free() to free the returned data.
440 gnutls_srp_base64_decode_alloc (const gnutls_datum_t
* b64_data
,
441 gnutls_datum_t
* result
)
446 size
= _gnutls_sbase64_decode (b64_data
->data
, b64_data
->size
, &ret
);
453 return GNUTLS_E_INVALID_REQUEST
;
464 #endif /* ENABLE_SRP */