base64.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /* Licensed under BSD-MIT - see LICENSE file for details */
  2. #ifndef CCAN_BASE64_H
  3. #define CCAN_BASE64_H
  4. #include <stddef.h>
  5. #include <stdbool.h>
  6. #include <sys/types.h>
  7. /**
  8. * base64_maps_t - structure to hold maps for encode/decode
  9. */
  10. typedef struct {
  11. char encode_map[64];
  12. signed char decode_map[256];
  13. } base64_maps_t;
  14. /**
  15. * base64_encoded_length - Calculate encode buffer length
  16. * @param srclen the size of the data to be encoded
  17. * @note add 1 to this to get null-termination
  18. * @return Buffer length required for encode
  19. */
  20. size_t base64_encoded_length(size_t srclen);
  21. /**
  22. * base64_decoded_length - Calculate decode buffer length
  23. * @param srclen Length of the data to be decoded
  24. * @note This does not return the size of the decoded data! see base64_decode
  25. * @return Minimum buffer length for safe decode
  26. */
  27. size_t base64_decoded_length(size_t srclen);
  28. /**
  29. * base64_init_maps - populate a base64_maps_t based on a supplied alphabet
  30. * @param dest A base64 maps object
  31. * @param src Alphabet to populate the maps from (e.g. base64_alphabet_rfc4648)
  32. */
  33. void base64_init_maps(base64_maps_t *dest, const char src[64]);
  34. /**
  35. * base64_encode_triplet_using_maps - encode 3 bytes into base64 using a specific alphabet
  36. * @param maps Maps to use for encoding (see base64_init_maps)
  37. * @param dest Buffer containing 3 bytes
  38. * @param src Buffer containing 4 characters
  39. */
  40. void base64_encode_triplet_using_maps(const base64_maps_t *maps,
  41. char dest[4], const char src[3]);
  42. /**
  43. * base64_encode_tail_using_maps - encode the final bytes of a source using a specific alphabet
  44. * @param maps Maps to use for encoding (see base64_init_maps)
  45. * @param dest Buffer containing 4 bytes
  46. * @param src Buffer containing srclen bytes
  47. * @param srclen Number of bytes (<= 3) to encode in src
  48. */
  49. void base64_encode_tail_using_maps(const base64_maps_t *maps, char dest[4],
  50. const char *src, size_t srclen);
  51. /**
  52. * base64_encode_using_maps - encode a buffer into base64 using a specific alphabet
  53. * @param maps Maps to use for encoding (see base64_init_maps)
  54. * @param dest Buffer to encode into
  55. * @param destlen Length of dest
  56. * @param src Buffer to encode
  57. * @param srclen Length of the data to encode
  58. * @return Number of encoded bytes set in dest. -1 on error (and errno set)
  59. * @note dest will be nul-padded to destlen (past any required padding)
  60. * @note sets errno = EOVERFLOW if destlen is too small
  61. */
  62. ssize_t base64_encode_using_maps(const base64_maps_t *maps,
  63. char *dest, size_t destlen,
  64. const char *src, size_t srclen);
  65. /*
  66. * base64_char_in_alphabet - returns true if character can be part of an encoded string
  67. * @param maps A base64 maps object (see base64_init_maps)
  68. * @param b64char Character to check
  69. */
  70. bool base64_char_in_alphabet(const base64_maps_t *maps, char b64char);
  71. /**
  72. * base64_decode_using_maps - decode a base64-encoded string using a specific alphabet
  73. * @param maps A base64 maps object (see base64_init_maps)
  74. * @param dest Buffer to decode into
  75. * @param destlen length of dest
  76. * @param src the buffer to decode
  77. * @param srclen the length of the data to decode
  78. * @return Number of decoded bytes set in dest. -1 on error (and errno set)
  79. * @note dest will be nul-padded to destlen
  80. * @note sets errno = EOVERFLOW if destlen is too small
  81. * @note sets errno = EDOM if src contains invalid characters
  82. */
  83. ssize_t base64_decode_using_maps(const base64_maps_t *maps,
  84. char *dest, size_t destlen,
  85. const char *src, size_t srclen);
  86. /**
  87. * base64_decode_quartet_using_maps - decode 4 bytes from base64 using a specific alphabet
  88. * @param maps A base64 maps object (see base64_init_maps)
  89. * @param dest Buffer containing 3 bytes
  90. * @param src Buffer containing 4 bytes
  91. * @return Number of decoded bytes set in dest. -1 on error (and errno set)
  92. * @note sets errno = EDOM if src contains invalid characters
  93. */
  94. int base64_decode_quartet_using_maps(const base64_maps_t *maps,
  95. char dest[3], const char src[4]);
  96. /**
  97. * base64_decode_tail_using_maps - decode the final bytes of a base64 string using a specific alphabet
  98. * @param maps A base64 maps object (see base64_init_maps)
  99. * @param dest Buffer containing 3 bytes
  100. * @param src Buffer containing 4 bytes - padded with '=' as required
  101. * @param srclen Number of bytes to decode in src
  102. * @return Number of decoded bytes set in dest. -1 on error (and errno set)
  103. * @note sets errno = EDOM if src contains invalid characters
  104. * @note sets errno = EINVAL if src is an invalid base64 tail
  105. */
  106. int base64_decode_tail_using_maps(const base64_maps_t *maps, char *dest,
  107. const char *src, size_t srclen);
  108. /* the rfc4648 functions: */
  109. extern const base64_maps_t base64_maps_rfc4648;
  110. /**
  111. * base64_encode - Encode a buffer into base64 according to rfc4648
  112. * @param dest Buffer to encode into
  113. * @param destlen Length of the destination buffer
  114. * @param src Buffer to encode
  115. * @param srclen Length of the data to encode
  116. * @return Number of encoded bytes set in dest. -1 on error (and errno set)
  117. * @note dest will be nul-padded to destlen (past any required padding)
  118. * @note sets errno = EOVERFLOW if destlen is too small
  119. *
  120. * This function encodes src according to http://tools.ietf.org/html/rfc4648
  121. *
  122. * Example:
  123. * size_t encoded_length;
  124. * char dest[100];
  125. * const char *src = "This string gets encoded";
  126. * encoded_length = base64_encode(dest, sizeof(dest), src, strlen(src));
  127. * printf("Returned data of length %zd @%p\n", encoded_length, &dest);
  128. */
  129. static inline
  130. ssize_t base64_encode(char *dest, size_t destlen,
  131. const char *src, size_t srclen)
  132. {
  133. return base64_encode_using_maps(&base64_maps_rfc4648,
  134. dest, destlen, src, srclen);
  135. }
  136. /**
  137. * base64_encode_triplet - encode 3 bytes into base64 according to rfc4648
  138. * @param dest Buffer containing 4 bytes
  139. * @param src Buffer containing 3 bytes
  140. */
  141. static inline
  142. void base64_encode_triplet(char dest[4], const char src[3])
  143. {
  144. base64_encode_triplet_using_maps(&base64_maps_rfc4648, dest, src);
  145. }
  146. /**
  147. * base64_encode_tail - encode the final bytes of a source according to rfc4648
  148. * @param dest Buffer containing 4 bytes
  149. * @param src Buffer containing srclen bytes
  150. * @param srclen Number of bytes (<= 3) to encode in src
  151. */
  152. static inline
  153. void base64_encode_tail(char dest[4], const char *src, size_t srclen)
  154. {
  155. base64_encode_tail_using_maps(&base64_maps_rfc4648, dest, src, srclen);
  156. }
  157. /**
  158. * base64_decode - decode An rfc4648 base64-encoded string
  159. * @param dest Buffer to decode into
  160. * @param destlen Length of the destination buffer
  161. * @param src Buffer to decode
  162. * @param srclen Length of the data to decode
  163. * @return Number of decoded bytes set in dest. -1 on error (and errno set)
  164. * @note dest will be nul-padded to destlen
  165. * @note sets errno = EOVERFLOW if destlen is too small
  166. * @note sets errno = EDOM if src contains invalid characters
  167. *
  168. * This function decodes the buffer according to
  169. * http://tools.ietf.org/html/rfc4648
  170. *
  171. * Example:
  172. * size_t decoded_length;
  173. * char ret[100];
  174. * const char *src = "Zm9vYmFyYmF6";
  175. * decoded_length = base64_decode(ret, sizeof(ret), src, strlen(src));
  176. * printf("Returned data of length %zd @%p\n", decoded_length, &ret);
  177. */
  178. static inline
  179. ssize_t base64_decode(char *dest, size_t destlen,
  180. const char *src, size_t srclen)
  181. {
  182. return base64_decode_using_maps(&base64_maps_rfc4648,
  183. dest, destlen, src, srclen);
  184. }
  185. /**
  186. * base64_decode_quartet - decode the first 4 characters in src into dest
  187. * @param dest Buffer containing 3 bytes
  188. * @param src Buffer containing 4 characters
  189. * @return Number of decoded bytes set in dest. -1 on error (and errno set)
  190. * @note sets errno = EDOM if src contains invalid characters
  191. */
  192. static inline
  193. int base64_decode_quartet(char dest[3], const char src[4])
  194. {
  195. return base64_decode_quartet_using_maps(&base64_maps_rfc4648,
  196. dest, src);
  197. }
  198. /**
  199. * @brief decode the final bytes of a base64 string from src into dest
  200. * @param dest Buffer containing 3 bytes
  201. * @param src Buffer containing 4 bytes - padded with '=' as required
  202. * @param srclen Number of bytes to decode in src
  203. * @return Number of decoded bytes set in dest. -1 on error (and errno set)
  204. * @note sets errno = EDOM if src contains invalid characters
  205. * @note sets errno = EINVAL if src is an invalid base64 tail
  206. */
  207. static inline
  208. ssize_t base64_decode_tail(char dest[3], const char *src, size_t srclen)
  209. {
  210. return base64_decode_tail_using_maps(&base64_maps_rfc4648,
  211. dest, src, srclen);
  212. }
  213. /* end rfc4648 functions */
  214. #endif /* CCAN_BASE64_H */