PageRenderTime 174ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/alcoext/tags/0.1.0/generic/alcoEncoding.c

http://nxscripts.googlecode.com/
C | 272 lines | 147 code | 26 blank | 99 comment | 21 complexity | 726f83cfa6c31a7ee47d76ccbca7d914 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause
  1. /*++
  2. AlcoExt - Alcoholicz Tcl extension.
  3. Copyright (c) 2005 Alcoholicz Scripting Team
  4. Module Name:
  5. alcoEncoding.c
  6. Author:
  7. neoxed (neoxed@gmail.com) May 21, 2005
  8. Abstract:
  9. This module implements a interface to process base64 and hex encodings.
  10. encode <encoding> <data>
  11. - Encodes the given data in the specified format.
  12. - The 'encoding' parameter must be 'base64' or 'hex'.
  13. decode <encoding> <data>
  14. - Decodes the given data from the specified format.
  15. - The 'encoding' parameter must be 'base64' or 'hex'.
  16. - An error is raised if the given data cannot be decoded.
  17. --*/
  18. #include <alcoExt.h>
  19. static EncLengthProc Base64DecodeGetDestLength;
  20. static EncLengthProc Base64EncodeGetDestLength;
  21. static EncLengthProc HexDecodeGetDestLength;
  22. static EncLengthProc HexEncodeGetDestLength;
  23. static EncProcessProc HexDecode;
  24. static EncProcessProc HexEncode;
  25. inline char HexDecodeChar(char c);
  26. const EncodingFuncts encodeFuncts[ENCODING_TYPES] = {
  27. {"base64", Base64EncodeGetDestLength, base64_encode},
  28. {"hex", HexEncodeGetDestLength, HexEncode},
  29. {NULL}
  30. };
  31. const EncodingFuncts decodeFuncts[ENCODING_TYPES] = {
  32. {"base64", Base64DecodeGetDestLength, base64_decode},
  33. {"hex", HexDecodeGetDestLength, HexDecode},
  34. {NULL}
  35. };
  36. /*++
  37. Base64DecodeGetDestLength
  38. Base64EncodeGetDestLength
  39. HexDecodeGetDestLength
  40. HexEncodeGetDestLength
  41. Calculate the required destination buffer size for various encodings.
  42. Arguments:
  43. sourceLength - The length of the source buffer.
  44. Return Value:
  45. The required destination buffer size to hold the encoded or decoded data.
  46. --*/
  47. static unsigned long
  48. Base64DecodeGetDestLength(unsigned long sourceLength)
  49. {
  50. return sourceLength;
  51. }
  52. static unsigned long
  53. Base64EncodeGetDestLength(unsigned long sourceLength)
  54. {
  55. return (4 * ((sourceLength + 2) / 3)) + 1;
  56. }
  57. static unsigned long
  58. HexDecodeGetDestLength(unsigned long sourceLength)
  59. {
  60. return (sourceLength / 2) + 1;
  61. }
  62. static unsigned long
  63. HexEncodeGetDestLength(unsigned long sourceLength)
  64. {
  65. return (sourceLength * 2) + 1;
  66. }
  67. /*++
  68. HexDecode
  69. Decode a buffer of hex data.
  70. Arguments:
  71. source - Source buffer containing the hex data to decode.
  72. sourceLength - Length of the source buffer.
  73. dest - Destination buffer of the binary decoded data.
  74. destLength - The max size of the destination buffer and resulting size.
  75. Return Value:
  76. A LibTomCrypt status code; CRYPT_OK will be returned if successful.
  77. --*/
  78. static int
  79. HexDecode(
  80. const unsigned char *source,
  81. unsigned long sourceLength,
  82. unsigned char *dest,
  83. unsigned long *destLength
  84. )
  85. {
  86. char c1;
  87. char c2;
  88. unsigned long i;
  89. unsigned long length = 0;
  90. if (*destLength < (sourceLength / 2) + 1) {
  91. return CRYPT_BUFFER_OVERFLOW;
  92. }
  93. for (i = 0; i < sourceLength; i += 2) {
  94. c1 = HexDecodeChar((char) *source++);
  95. c2 = HexDecodeChar((char) *source++);
  96. if (c1 < 0 || c2 < 0) {
  97. return CRYPT_INVALID_PACKET;
  98. }
  99. *dest++ = (unsigned char)(16 * c1 + c2);
  100. length++;
  101. }
  102. *destLength = length;
  103. return CRYPT_OK;
  104. }
  105. inline char
  106. HexDecodeChar(
  107. char ch
  108. )
  109. {
  110. if (ch >= '0' && ch <= '9') {
  111. return (ch - '0');
  112. }
  113. if (ch >= 'A' && ch <= 'F') {
  114. return (ch - 'A' + 10);
  115. }
  116. if (ch >= 'a' && ch <= 'f') {
  117. return (ch - 'a' + 10);
  118. }
  119. return -1;
  120. }
  121. /*++
  122. HexEncode
  123. Encode a buffer of data in hex.
  124. Arguments:
  125. source - Source buffer to encode.
  126. sourceLength - Length of the source buffer.
  127. dest - Destination buffer for the hex encoded data.
  128. destLength - The max size of the destination buffer and resulting size.
  129. Return Value:
  130. A LibTomCrypt status code; CRYPT_OK will be returned if successful.
  131. --*/
  132. static int
  133. HexEncode(
  134. const unsigned char *source,
  135. unsigned long sourceLength,
  136. unsigned char *dest,
  137. unsigned long *destLength
  138. )
  139. {
  140. unsigned char c;
  141. unsigned long i;
  142. unsigned long length = 0;
  143. static const char hexChars[16] = {
  144. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  145. 'A', 'B', 'C', 'D', 'E', 'F'
  146. };
  147. if (*destLength < (sourceLength * 2) + 1) {
  148. return CRYPT_BUFFER_OVERFLOW;
  149. }
  150. for (i = 0; i < sourceLength; i++) {
  151. c = *source++;
  152. *dest++ = hexChars[(c >> 4) & 0x0F];
  153. *dest++ = hexChars[c & 0x0F];
  154. length += 2;
  155. }
  156. *destLength = length;
  157. return CRYPT_OK;
  158. }
  159. /*++
  160. EncodingObjCmd
  161. This function provides the "encode" and "decode" Tcl commands.
  162. Arguments:
  163. clientData - Pointer to an array of 'EncodingFuncts'.
  164. interp - Current interpreter.
  165. objc - Number of arguments.
  166. objv - Argument objects.
  167. Return Value:
  168. A standard Tcl result.
  169. --*/
  170. int
  171. EncodingObjCmd(
  172. ClientData clientData,
  173. Tcl_Interp *interp,
  174. int objc,
  175. Tcl_Obj *CONST objv[]
  176. )
  177. {
  178. int index;
  179. int sourceLength;
  180. int status;
  181. unsigned char *dest;
  182. unsigned char *source;
  183. unsigned long destLength;
  184. EncodingFuncts *functTable;
  185. if (objc != 3) {
  186. Tcl_WrongNumArgs(interp, 1, objv, "encoding data");
  187. return TCL_ERROR;
  188. }
  189. functTable = (EncodingFuncts *) clientData;
  190. assert(functTable == decodeFuncts || functTable == encodeFuncts);
  191. if (Tcl_GetIndexFromObjStruct(interp, objv[1], functTable,
  192. sizeof(EncodingFuncts), "encoding", TCL_EXACT, &index) != TCL_OK) {
  193. return TCL_ERROR;
  194. }
  195. source = Tcl_GetByteArrayFromObj(objv[2], &sourceLength);
  196. // Create a byte object for the output data.
  197. destLength = functTable[index].GetDestLength(sourceLength);
  198. dest = Tcl_SetByteArrayLength(Tcl_GetObjResult(interp), (int)destLength);
  199. status = functTable[index].Process(source, (unsigned long)sourceLength, dest, &destLength);
  200. if (status != CRYPT_OK) {
  201. Tcl_ResetResult(interp);
  202. Tcl_AppendResult(interp, "unable to process data: ",
  203. error_to_string(status), NULL);
  204. return TCL_ERROR;
  205. }
  206. // Update the object's length.
  207. Tcl_SetByteArrayLength(Tcl_GetObjResult(interp), (int)destLength);
  208. return TCL_OK;
  209. }