/ OSX / libsecurity_keychain / lib / SecBase64P.h
SecBase64P.h
  1  /* /////////////////////////////////////////////////////////////////////////////
  2   * File:        b64/b64.h
  3   *
  4   * Purpose:     Header file for the b64 library
  5   *
  6   * Created:     18th October 2004
  7   * Updated:     2nd August 2006
  8   *
  9   * Thanks:      To Adam McLaurin, for ideas regarding the SecBase64Decode2() and SecBase64Encode2().
 10   *
 11   * Home:        http://synesis.com.au/software/
 12   *
 13   * Copyright (c) 2004-2006, Matthew Wilson and Synesis Software
 14   * All rights reserved.
 15   *
 16   * Redistribution and use in source and binary forms, with or without
 17   * modification, are permitted provided that the following conditions are met:
 18   *
 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.
 27   *
 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.
 39   *
 40   * ////////////////////////////////////////////////////////////////////////// */
 41  
 42  
 43  /** \file b64/b64.h
 44   *
 45   * \brief [C/C++] Header file for the b64 library.
 46   */
 47  
 48  #ifndef _SEC_BASE64_H_
 49  #define _SEC_BASE64_H_
 50  
 51  #include <stdint.h>
 52  #include <stddef.h>
 53  
 54  #ifdef __cplusplus
 55  extern "C" {
 56  #endif /* __cplusplus */
 57  
 58  /* /////////////////////////////////////////////////////////////////////////////
 59   * Enumerations
 60   */
 61  
 62  /** \brief Return codes (from SecBase64Encode2() / SecBase64Decode2())
 63   */
 64  enum
 65  {
 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. */
 70  };
 71  
 72  typedef uint32_t SecBase64Result;
 73  
 74  /** \brief Coding behaviour modification flags (for SecBase64Encode2() / SecBase64Decode2())
 75   */
 76  enum
 77  {
 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(). */
 87  };
 88  
 89  typedef uint32_t SecBase64Flags;
 90  
 91  /* /////////////////////////////////////////////////////////////////////////////
 92   * Functions
 93   */
 94  
 95  #if 0
 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);
 99      if (lineLen > 0) {
100          size_t numLines = (total + (lineLen - 1)) / lineLen;
101          total += 2 * (numLines - 1);
102      }
103      return total;
104  }
105  #endif
106  
107  /** \brief Encodes a block of binary data into base64
108   *
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).
117   *
118   * \return 0 if the size of the buffer was insufficient, or the length of the
119   * converted buffer was longer than \c destLen
120   *
121   * \note The function returns the required length if \c dest is NULL
122   *
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.
125   *
126   * \note Threading: The function is fully re-entrant.
127   */
128  size_t SecBase64Encode(void const *src, size_t srcSize, char *dest, size_t destLen);
129  
130  /** \brief Encodes a block of binary data into base64
131   *
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.
147   *
148   * \return 0 if the size of the buffer was insufficient, or the length of the
149   *   converted buffer was longer than \c destLen
150   *
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.
153   *
154   * \note Threading: The function is fully re-entrant.
155   */
156  size_t SecBase64Encode2( void const  *src
157                  ,   size_t      srcSize
158                  ,   char        *dest
159                  ,   size_t      destLen
160                  ,   unsigned    flags
161                  ,   int         lineLen /* = 0 */
162                  ,   SecBase64Result      *rc     /* = NULL */);
163  
164  /** \brief Decodes a sequence of base64 into a block of binary data
165   *
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.
170   *
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.
180   *
181   * \return 0 if the size of the buffer was insufficient, or the length of the
182   *   converted buffer was longer than \c destSize
183   *
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.
186   *
187   * \note \anchor anchor__4_characters The behaviour of both
188   * \link b64::SecBase64Encode2 SecBase64Encode2()\endlink
189   * and
190   * \link b64::SecBase64Decode2 SecBase64Decode2()\endlink
191   * are undefined if the line length is not a multiple of 4.
192   *
193   * \note Threading: The function is fully re-entrant.
194   */
195  size_t SecBase64Decode(char const *src, size_t srcLen, void *dest, size_t destSize);
196  
197  /** \brief Decodes a sequence of base64 into a block of binary data
198   *
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.
203   *
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.
220   *
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.
223   *
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.
226   *
227   * \note The behaviour of both
228   * \link b64::SecBase64Encode2 SecBase64Encode2()\endlink
229   * and
230   * \link b64::SecBase64Decode2 SecBase64Decode2()\endlink
231   * are undefined if the line length is not a multiple of 4.
232   *
233   * \note Threading: The function is fully re-entrant.
234   */
235  size_t SecBase64Decode2( char const  *src
236                  ,   size_t      srcLen
237                  ,   void        *dest
238                  ,   size_t      destSize
239                  ,   unsigned    flags
240                  ,   char const  **badChar   /* = NULL */
241                  ,   SecBase64Result      *rc         /* = NULL */);
242  
243  #ifdef __cplusplus
244  }
245  #endif /* __cplusplus */
246  
247  #endif /* _SEC_BASE64_H_ */