1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ 2 /* vi: set expandtab shiftwidth=4 tabstop=4: */ 3 4 /** 5 * \file 6 * <PRE> 7 * High performance base64 encoder / decoder 8 * Version 1.3 -- 17-Mar-2006 9 * 10 * Copyright © 2005, 2006, Nick Galbreath -- nickg [at] modp [dot] com 11 * All rights reserved. 12 * 13 * http://modp.com/release/base64 14 * 15 * Released under bsd license. See modp_b64.c for details. 16 * </pre> 17 * 18 * The default implementation is the standard b64 encoding with padding. 19 * It's easy to change this to use "URL safe" characters and to remove 20 * padding. See the modp_b64.c source code for details. 21 * 22 */ 23 24 #ifndef MODP_B64 25 #define MODP_B64 26 27 #include <limits.h> 28 #include <stddef.h> 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 /** 35 * Encode a raw binary string into base 64. 36 * src contains the bytes 37 * len contains the number of bytes in the src 38 * dest should be allocated by the caller to contain 39 * at least modp_b64_encode_len(len) bytes (see below) 40 * This will contain the (non-null terminated) b64 bytes. 41 * returns length of the destination string. 42 * 43 * Example 44 * 45 * \code 46 * char* src = ...; 47 * int srclen = ...; //the length of number of bytes in src 48 * char* dest = (char*) malloc(modp_b64_encode_len); 49 * int len = modp_b64_encode_data(dest, src, sourcelen); 50 * if (len == -1) { 51 * printf("Error\n"); 52 * } else { 53 * printf("b64 = %s\n", dest); 54 * } 55 * \endcode 56 * 57 */ 58 size_t modp_b64_encode_data(char* dest, const char* str, size_t len); 59 60 /** 61 * Same as modp_b64_encode_data, but additionally sets a null terminator at the 62 * end of `dest` (i.e. at dest[output_size]). 63 * Like modp_b64_encode_data, returns the length of the destination string (i.e. 64 * not counting the null terminator). 65 * 66 * TODO(csharrison): Consider removing this once all callers migrate to 67 * modp_b64_encode_data. 68 */ 69 size_t modp_b64_encode(char* dest, const char* str, size_t len); 70 71 /** 72 * Decode a base64 encoded string 73 * 74 * src should contain exactly len bytes of b64 characters. 75 * if src contains -any- non-base characters (such as white 76 * space, -1 is returned. 77 * 78 * dest should be allocated by the caller to contain at least 79 * len * 3 / 4 bytes. 80 * 81 * Returns the length (strlen) of the output, or -1 if unable to 82 * decode 83 * 84 * \code 85 * char* src = ...; 86 * int srclen = ...; // or if you don't know use strlen(src) 87 * char* dest = (char*) malloc(modp_b64_decode_len(srclen)); 88 * int len = modp_b64_decode(dest, src, sourcelen); 89 * if (len == -1) { error } 90 * \endcode 91 */ 92 enum class ModpDecodePolicy { 93 // src length must be divisible by 4, with a max of 2 pad chars. 94 kStrict, 95 96 // Matches the infra spec: https://infra.spec.whatwg.org/#forgiving-base64 97 // _except_ for ignoring whitespace (Step 1). 98 kForgiving, 99 100 // src length % 4 must not equal 1, after stripping all pad chars. 101 // Accepts any number of pad chars. 102 kNoPaddingValidation, 103 }; 104 size_t modp_b64_decode( 105 char* dest, 106 const char* src, 107 size_t len, 108 ModpDecodePolicy policy = ModpDecodePolicy::kStrict); 109 110 /** 111 * The maximum input that can be passed into modp_b64_encode{_data}. 112 * Lengths beyond this will overflow modp_b64_encode_len. 113 * 114 * This works because modp_b64_encode_len(A) computes: 115 * ceiling[max_len / 3] * 4 + 1 116 * = ceiling[floor[(SIZE_MAX-1)/4]*3 / 3] * 4 + 1 117 * = floor[(SIZE_MAX-1)/4] * 4 + 1 118 * <= SIZE_MAX-1 + 1 119 * = SIZE_MAX 120 * 121 * Note: technically modp_b64_encode_data can take one extra byte, but for 122 * simplicity the bound is shared between the two functions. 123 */ 124 #define MODP_B64_MAX_INPUT_LEN ((SIZE_MAX - 1) / 4 * 3) 125 126 /** 127 * Given a source string of length len, this returns the amount of 128 * memory the destination string should have, for modp_b64_encode_data and 129 * modp_b64_encode, respectively. 130 * 131 * remember, this is integer math 132 * 3 bytes turn into 4 chars 133 * ceiling[len / 3] * 4 134 * 135 * 136 * WARNING: These expressions will overflow if the A is above 137 * MODP_B64_MAX_INPUT_LEN. The caller must check this bound first. 138 */ 139 #define modp_b64_encode_data_len(A) ((A + 2) / 3 * 4) 140 #define modp_b64_encode_len(A) (modp_b64_encode_data_len(A) + 1) 141 142 /** 143 * Given a base64 string of length len, 144 * this returns the amount of memory required for output string 145 * It maybe be more than the actual number of bytes written. 146 * NOTE: remember this is integer math 147 * this allocates a bit more memory than traditional versions of b64 148 * decode 4 chars turn into 3 bytes 149 * floor[len * 3/4] + 2 150 */ 151 #define modp_b64_decode_len(A) (A / 4 * 3 + 2) 152 153 #define MODP_B64_ERROR ((size_t)-1) 154 155 #ifdef __cplusplus 156 } 157 #endif /* __cplusplus */ 158 159 #endif /* MODP_B64 */ 160