PageRenderTime 55ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/easytag-2.1.7/src/base64.c

#
C | 218 lines | 102 code | 16 blank | 100 comment | 34 complexity | 26388f2e254e46bf8bb0ec2a8b85033d MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. /*
  2. * Copyright (c) 1995 - 1999 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. Neither the name of the Institute nor the names of its contributors
  18. * may be used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
  22. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
  25. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. */
  33. /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
  34. The following encoding technique is taken from RFC 1521 by Borenstein
  35. and Freed. It is reproduced here in a slightly edited form for
  36. convenience.
  37. A 65-character subset of US-ASCII is used, enabling 6 bits to be
  38. represented per printable character. (The extra 65th character, "=",
  39. is used to signify a special processing function.)
  40. The encoding process represents 24-bit groups of input bits as output
  41. strings of 4 encoded characters. Proceeding from left to right, a
  42. 24-bit input group is formed by concatenating 3 8-bit input groups.
  43. These 24 bits are then treated as 4 concatenated 6-bit groups, each
  44. of which is translated into a single digit in the base64 alphabet.
  45. Each 6-bit group is used as an index into an array of 64 printable
  46. characters. The character referenced by the index is placed in the
  47. output string.
  48. Table 1: The Base64 Alphabet
  49. Value Encoding Value Encoding Value Encoding Value Encoding
  50. 0 A 17 R 34 i 51 z
  51. 1 B 18 S 35 j 52 0
  52. 2 C 19 T 36 k 53 1
  53. 3 D 20 U 37 l 54 2
  54. 4 E 21 V 38 m 55 3
  55. 5 F 22 W 39 n 56 4
  56. 6 G 23 X 40 o 57 5
  57. 7 H 24 Y 41 p 58 6
  58. 8 I 25 Z 42 q 59 7
  59. 9 J 26 a 43 r 60 8
  60. 10 K 27 b 44 s 61 9
  61. 11 L 28 c 45 t 62 +
  62. 12 M 29 d 46 u 63 /
  63. 13 N 30 e 47 v
  64. 14 O 31 f 48 w (pad) =
  65. 15 P 32 g 49 x
  66. 16 Q 33 h 50 y
  67. Special processing is performed if fewer than 24 bits are available
  68. at the end of the data being encoded. A full encoding quantum is
  69. always completed at the end of a quantity. When fewer than 24 input
  70. bits are available in an input group, zero bits are added (on the
  71. right) to form an integral number of 6-bit groups. Padding at the
  72. end of the data is performed using the '=' character.
  73. Since all base64 input is an integral number of octets, only the
  74. -------------------------------------------------
  75. following cases can arise:
  76. (1) the final quantum of encoding input is an integral
  77. multiple of 24 bits; here, the final unit of encoded
  78. output will be an integral multiple of 4 characters
  79. with no "=" padding,
  80. (2) the final quantum of encoding input is exactly 8 bits;
  81. here, the final unit of encoded output will be two
  82. characters followed by two "=" padding characters, or
  83. (3) the final quantum of encoding input is exactly 16 bits;
  84. here, the final unit of encoded output will be three
  85. characters followed by one "=" padding character.
  86. */
  87. /* $Id: base64.c,v 1.5 2001/05/28 17:33:41 joda Exp $ */
  88. /*
  89. * Code taken from Kerberos krb4-1.2.2
  90. */
  91. #include <stdlib.h>
  92. #include <string.h>
  93. #include "base64.h"
  94. /* Useful for encoding */
  95. static char base64_chars[] =
  96. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  97. /* For constant time lookups */
  98. static int
  99. is_base64_char(char c)
  100. {
  101. return (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') ||
  102. ('0' <= c && c <= '9') || (c == '+' || c == '/'));
  103. }
  104. static int
  105. pos(char c)
  106. {
  107. char *p;
  108. for (p = base64_chars; *p; p++)
  109. if (*p == c)
  110. return p - base64_chars;
  111. return -1;
  112. }
  113. int
  114. base64_encode(const void *data, int size, char **str)
  115. {
  116. char *s, *p;
  117. int i;
  118. int c;
  119. const unsigned char *q;
  120. p = s = (char *) malloc(size * 4 / 3 + 4);
  121. if (p == NULL)
  122. return -1;
  123. q = (const unsigned char *) data;
  124. i = 0;
  125. for (i = 0; i < size;)
  126. {
  127. c = q[i++];
  128. c *= 256;
  129. if (i < size)
  130. c += q[i];
  131. i++;
  132. c *= 256;
  133. if (i < size)
  134. c += q[i];
  135. i++;
  136. p[0] = base64_chars[(c & 0x00fc0000) >> 18];
  137. p[1] = base64_chars[(c & 0x0003f000) >> 12];
  138. p[2] = base64_chars[(c & 0x00000fc0) >> 6];
  139. p[3] = base64_chars[(c & 0x0000003f) >> 0];
  140. if (i > size)
  141. p[3] = '=';
  142. if (i > size + 1)
  143. p[2] = '=';
  144. p += 4;
  145. }
  146. *p = 0;
  147. *str = s;
  148. return strlen(s);
  149. }
  150. #define DECODE_ERROR ((unsigned) -1)
  151. static unsigned int
  152. token_decode(const char *token, const size_t size)
  153. {
  154. int i;
  155. unsigned int val = 0;
  156. int marker = 0;
  157. if (size < 4)
  158. return DECODE_ERROR;
  159. for (i = 0; i < 4; i++)
  160. {
  161. val *= 64;
  162. if (token[i] == '=')
  163. marker++;
  164. else if (marker > 0)
  165. return DECODE_ERROR;
  166. else
  167. val += pos(token[i]);
  168. }
  169. if (marker > 2)
  170. return DECODE_ERROR;
  171. return (marker << 24) | val;
  172. }
  173. int
  174. base64_decode(const char *str, void *data)
  175. {
  176. const char *p;
  177. unsigned char *q;
  178. unsigned int size;
  179. q = data;
  180. size = strlen(str);
  181. for (p = str; *p && (*p == '=' || is_base64_char(*p)); p += 4, size -= 4)
  182. {
  183. unsigned int val = token_decode(p, size);
  184. unsigned int marker = (val >> 24) & 0xff;
  185. if (val == DECODE_ERROR)
  186. return -1;
  187. *q++ = (val >> 16) & 0xff;
  188. if (marker < 2)
  189. *q++ = (val >> 8) & 0xff;
  190. if (marker < 1)
  191. *q++ = val & 0xff;
  192. }
  193. return q - (unsigned char *) data;
  194. }