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