1 /* ///////////////////////////////////////////////////////////////////////////// 
   4  * Purpose:     Header file for the b64 library 
   6  * Created:     18th October 2004 
   7  * Updated:     2nd August 2006 
   9  * Thanks:      To Adam McLaurin, for ideas regarding the SecBase64Decode2() and SecBase64Encode2(). 
  11  * Home:        http://synesis.com.au/software/ 
  13  * Copyright (c) 2004-2006, Matthew Wilson and Synesis Software 
  14  * All rights reserved. 
  16  * Redistribution and use in source and binary forms, with or without 
  17  * modification, are permitted provided that the following conditions are met: 
  19  * - Redistributions of source code must retain the above copyright notice, this 
  20  *   list of conditions and the following disclaimer. 
  21  * - Redistributions in binary form must reproduce the above copyright notice, 
  22  *   this list of conditions and the following disclaimer in the documentation 
  23  *   and/or other materials provided with the distribution. 
  24  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of 
  25  *   any contributors may be used to endorse or promote products derived from 
  26  *   this software without specific prior written permission. 
  28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
  29  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  31  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
  32  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
  33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
  34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
  35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
  36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
  38  * POSSIBILITY OF SUCH DAMAGE. 
  40  * ////////////////////////////////////////////////////////////////////////// */ 
  45  * \brief [C/C++] Header file for the b64 library. 
  48 #ifndef _SEC_BASE64_H_ 
  49 #define _SEC_BASE64_H_ 
  56 #endif /* __cplusplus */ 
  58 /* ///////////////////////////////////////////////////////////////////////////// 
  62 /** \brief Return codes (from SecBase64Encode2() / SecBase64Decode2()) 
  66     kSecB64_R_OK                   
=   0,   /*!< operation was successful. */ 
  67     kSecB64_R_INSUFFICIENT_BUFFER  
=   1,   /*!< The given translation buffer was not of sufficient size. */ 
  68     kSecB64_R_TRUNCATED_INPUT      
=   2,   /*!< The input did not represent a fully formed stream of octet couplings. */ 
  69     kSecB64_R_DATA_ERROR           
=   3   /*!< invalid data. */ 
  72 typedef uint32_t SecBase64Result
; 
  74 /** \brief Coding behaviour modification flags (for SecBase64Encode2() / SecBase64Decode2()) 
  78         kSecB64_F_LINE_LEN_USE_PARAM    
=   0x0000  /*!< Uses the lineLen parameter to SecBase64Encode2(). Ignored by SecBase64Decode2(). */ 
  79     ,   kSecB64_F_LINE_LEN_INFINITE     
=   0x0001  /*!< Ignores the lineLen parameter to SecBase64Encode2(). Line length is infinite. Ignored by SecBase64Decode2(). */ 
  80     ,   kSecB64_F_LINE_LEN_64           
=   0x0002  /*!< Ignores the lineLen parameter to SecBase64Encode2(). Line length is 64. Ignored by SecBase64Decode2(). */ 
  81     ,   kSecB64_F_LINE_LEN_76           
=   0x0003  /*!< Ignores the lineLen parameter to SecBase64Encode2(). Line length is 76. Ignored by SecBase64Decode2(). */ 
  82     ,   kSecB64_F_LINE_LEN_MASK         
=   0x000f  /*!< Mask for testing line length flags to SecBase64Encode2(). Ignored by SecBase64Encode2(). */ 
  83     ,   kSecB64_F_STOP_ON_NOTHING       
=   0x0000  /*!< Decoding ignores all invalid characters in the input data. Ignored by SecBase64Encode2(). */ 
  84     ,   kSecB64_F_STOP_ON_UNKNOWN_CHAR  
=   0x0100  /*!< Causes decoding to break if any non-Base-64 [a-zA-Z0-9=+/], non-whitespace character is encountered. Ignored by SecBase64Encode2(). */ 
  85     ,   kSecB64_F_STOP_ON_UNEXPECTED_WS 
=   0x0200  /*!< Causes decoding to break if any unexpected whitespace is encountered. Ignored by SecBase64Encode2(). */ 
  86     ,   kSecB64_F_STOP_ON_BAD_CHAR      
=   0x0300  /*!< Causes decoding to break if any non-Base-64 [a-zA-Z0-9=+/] character is encountered. Ignored by SecBase64Encode2(). */ 
  89 typedef uint32_t SecBase64Flags
; 
  91 /* ///////////////////////////////////////////////////////////////////////////// 
  96 static inline size_t SecBase64EncodedSize(size_t srcSize
, size_t lineLen
) { 
  97     size_t total 
= (((srcSize
) + 2) / 3) * 4; 
  98     size_t lineLen 
= (lineLen
); 
 100         size_t numLines 
= (total 
+ (lineLen 
- 1)) / lineLen
; 
 101         total 
+= 2 * (numLines 
- 1); 
 107 /** \brief Encodes a block of binary data into base64 
 109  * \param src Pointer to the block to be encoded. May not be NULL, except when 
 110  *   \c dest is NULL, in which case it is ignored. 
 111  * \param srcSize Length of block to be encoded 
 112  * \param dest Pointer to the buffer into which the result is to be written. May 
 113  *   be NULL, in which case the function returns the required length 
 114  * \param destLen Length of the buffer into which the result is to be written. Must 
 115  *   be at least as large as that indicated by the return value from 
 116  * \c SecBase64Encode()(NULL, srcSize, NULL, 0). 
 118  * \return 0 if the size of the buffer was insufficient, or the length of the 
 119  * converted buffer was longer than \c destLen 
 121  * \note The function returns the required length if \c dest is NULL 
 123  * \note The function returns the required length if \c dest is NULL. The returned size 
 124  *   might be larger than the actual required size, but will never be smaller. 
 126  * \note Threading: The function is fully re-entrant. 
 128 size_t SecBase64Encode(void const *src
, size_t srcSize
, char *dest
, size_t destLen
); 
 130 /** \brief Encodes a block of binary data into base64 
 132  * \param src Pointer to the block to be encoded. May not be NULL, except when 
 133  *   \c dest is NULL, in which case it is ignored. 
 134  * \param srcSize Length of block to be encoded 
 135  * \param dest Pointer to the buffer into which the result is to be written. May 
 136  *   be NULL, in which case the function returns the required length 
 137  * \param destLen Length of the buffer into which the result is to be written. Must 
 138  *   be at least as large as that indicated by the return value from 
 139  *   \c SecBase64Encode()(NULL, srcSize, NULL, 0). 
 140  * \param flags A combination of the SecBase64Flags enumeration, that moderate the 
 141  *   behaviour of the function 
 142  * \param lineLen If the flags parameter contains kSecB64_F_LINE_LEN_USE_PARAM, then 
 143  *   this parameter represents the length of the lines into which the encoded form is split, 
 144  *   with a hard line break ('\\r\\n'). If this value is 0, then the line is not 
 145  *   split. If it is <0, then the RFC-1113 recommended line length of 64 is used 
 146  * \param rc The return code representing the status of the operation. May be NULL. 
 148  * \return 0 if the size of the buffer was insufficient, or the length of the 
 149  *   converted buffer was longer than \c destLen 
 151  * \note The function returns the required length if \c dest is NULL. The returned size 
 152  *   might be larger than the actual required size, but will never be smaller. 
 154  * \note Threading: The function is fully re-entrant. 
 156 size_t SecBase64Encode2( void const  *src
 
 161                 ,   int         lineLen 
/* = 0 */ 
 162                 ,   SecBase64Result      
*rc     
/* = NULL */); 
 164 /** \brief Decodes a sequence of base64 into a block of binary data 
 166  * \param src Pointer to the base64 block to be decoded. May not be NULL, except when 
 167  *   \c dest is NULL, in which case it is ignored. If \c dest is NULL, and \c src is 
 168  *   <b>not</b> NULL, then the returned value is calculated exactly, otherwise a value 
 169  *   is returned that is guaranteed to be large enough to hold the decoded block. 
 171  * \param srcLen Length of block to be encoded. Must be an integral of 4, the base64 
 172  *   encoding quantum, otherwise the base64 block is assumed to be invalid 
 173  * \param dest Pointer to the buffer into which the result is to be written. May 
 174  *   be NULL, in which case the function returns the required length 
 175  * \param destSize Length of the buffer into which the result is to be written. Must 
 176  *   be at least as large as that indicated by the return value from 
 177  *   \c SecBase64Decode(src, srcSize, NULL, 0), even in the case where the encoded form 
 178  *   contains a number of characters that will be ignored, resulting in a lower total 
 179  *   length of converted form. 
 181  * \return 0 if the size of the buffer was insufficient, or the length of the 
 182  *   converted buffer was longer than \c destSize 
 184  * \note The function returns the required length if \c dest is NULL. The returned size 
 185  *   might be larger than the actual required size, but will never be smaller. 
 187  * \note \anchor anchor__4_characters The behaviour of both 
 188  * \link b64::SecBase64Encode2 SecBase64Encode2()\endlink 
 190  * \link b64::SecBase64Decode2 SecBase64Decode2()\endlink 
 191  * are undefined if the line length is not a multiple of 4. 
 193  * \note Threading: The function is fully re-entrant. 
 195 size_t SecBase64Decode(char const *src
, size_t srcLen
, void *dest
, size_t destSize
); 
 197 /** \brief Decodes a sequence of base64 into a block of binary data 
 199  * \param src Pointer to the base64 block to be decoded. May not be NULL, except when 
 200  * \c dest is NULL, in which case it is ignored. If \c dest is NULL, and \c src is 
 201  * <b>not</b> NULL, then the returned value is calculated exactly, otherwise a value 
 202  * is returned that is guaranteed to be large enough to hold the decoded block. 
 204  * \param srcLen Length of block to be encoded. Must be an integral of 4, the base64 
 205  *   encoding quantum, otherwise the base64 block is assumed to be invalid 
 206  * \param dest Pointer to the buffer into which the result is to be written. May 
 207  *   be NULL, in which case the function returns the required length 
 208  * \param destSize Length of the buffer into which the result is to be written. Must 
 209  *   be at least as large as that indicated by the return value from 
 210  *   \c SecBase64Decode(src, srcSize, NULL, 0), even in the case where the encoded form 
 211  *   contains a number of characters that will be ignored, resulting in a lower total 
 212  *   length of converted form. 
 213  * \param flags A combination of the SecBase64Flags enumeration, that moderate the 
 214  *   behaviour of the function. 
 215  * \param rc The return code representing the status of the operation. May be NULL. 
 216  * \param badChar If the flags parameter does not contain kSecB64_F_STOP_ON_NOTHING, this 
 217  *   parameter specifies the address of a pointer that will be set to point to any 
 218  *   character in the sequence that stops the parsing, as dictated by the flags 
 219  *   parameter. May be NULL. 
 221  * \return 0 if the size of the buffer was insufficient, or the length of the 
 222  * converted buffer was longer than \c destSize, or a bad character stopped parsing. 
 224  * \note The function returns the required length if \c dest is NULL. The returned size 
 225  *   might be larger than the actual required size, but will never be smaller. 
 227  * \note The behaviour of both 
 228  * \link b64::SecBase64Encode2 SecBase64Encode2()\endlink 
 230  * \link b64::SecBase64Decode2 SecBase64Decode2()\endlink 
 231  * are undefined if the line length is not a multiple of 4. 
 233  * \note Threading: The function is fully re-entrant. 
 235 size_t SecBase64Decode2( char const  *src
 
 240                 ,   char const  **badChar   
/* = NULL */ 
 241                 ,   SecBase64Result      
*rc         
/* = NULL */); 
 245 #endif /* __cplusplus */ 
 247 #endif /* _SEC_BASE64_H_ */