1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 * @brief APR-UTIL Encoding
25 #include "apr_general.h"
32 * @defgroup APR_Util_Encode Base64/Base64Url/Base32/Base32Hex/Base16 Encoding
38 * RFC4648 and RFC7515 compliant BASE64, BASE64URL, BASE32, BASE32HEX
39 * and BASE16 encode/decode functions.
41 * The following encodings are supported:
45 * o Use flag APR_ENCODE_NONE
46 * o https://tools.ietf.org/html/rfc4648#section-4
48 * - Base 64 Encoding with URL and Filename Safe Alphabet
50 * o Use flag APR_ENCODE_URL
51 * o https://tools.ietf.org/html/rfc4648#section-5
53 * - Base 64 URL Encoding without Padding
55 * o Use flag APR_ENCODE_BASE64URL
56 * o https://tools.ietf.org/html/rfc7515#appendix-C
60 * o Use flag APR_ENCODE_NONE
61 * o https://tools.ietf.org/html/rfc4648#section-6
63 * - Base 32 Encoding with Extended Hex Alphabet
65 * o Use flag APR_ENCODE_BASE32HEX
66 * o https://tools.ietf.org/html/rfc4648#section-7
70 * o Use flags APR_ENCODE_NONE/APR_ENCODE_COLON
71 * o https://tools.ietf.org/html/rfc4648#section-8
73 * If a non valid character of any kind including whitespace is passed to any
74 * of the decoder functions, APR_BADCH will be returned. In this case decoding
75 * will still take place, but the results can not be trusted.
77 * If APR_ENCODE_RELAXED is passed to the decoder functions, decoding will be
78 * attempted up until the first non valid character. If this results in an
79 * invalid state in the decoder, such as but not limited to an odd number of
80 * base16 characters, APR_BADCH will still be returned.
82 * If APR_ENCODE_RELAXED is not passed to a decoder function, the decoding will
83 * be done in constant time regardless of whether the result returns APR_SUCCESS
86 * If the dest parameter is NULL, the maximum theoretical buffer size is
87 * returned in the len field, including space for a terminating zero character
88 * if the destination is a string. This value can be used to allocate buffers
89 * of a suitable safe size.
91 * If the dest parameter is provided, the encoding or decoding will take place,
92 * and the actual number of characters written is returned in the len field,
93 * ignoring any terminating zero.
95 * Plain strings are not assumed '\0' terminated unless APR_ENCODE_STRING is
101 * When passing a string to one of the encode functions, this value can be
102 * passed to indicate a string-valued key, and have the length computed
105 #define APR_ENCODE_STRING (-1)
108 * Generate RFC4648 base16/base32/base64.
110 #define APR_ENCODE_NONE 0
113 * If relaxed, decode up until the first non base16/base32/base64 character.
115 #define APR_ENCODE_RELAXED 1
118 * Omit the padding character (=) while encoding.
120 #define APR_ENCODE_NOPADDING 2
123 * Generate RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet
125 #define APR_ENCODE_URL 4
128 * Generate RFC7515 BASE64URL
130 #define APR_ENCODE_BASE64URL (APR_ENCODE_NOPADDING | APR_ENCODE_URL)
133 * Generate base32hex encoding instead of base32 encoding
135 #define APR_ENCODE_BASE32HEX 8
138 * Generate base16 with colons between each token.
140 #define APR_ENCODE_COLON 16
143 * Generate base16 with lower case characters.
145 #define APR_ENCODE_LOWER 32
148 * Convert text data to base64.
149 * @param dest The destination string, can be NULL.
150 * @param src The original string.
151 * @param slen The length of the original string, or APR_ENCODE_STRING if
153 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
154 * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_URL,
155 * use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
156 * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
157 * @param len If present and src is NULL, returns the maximum possible length
158 * of the destination string, including a zero pad. If present and src is
159 * not NULL, returns the number of characters actually written.
160 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL.
162 APR_DECLARE(apr_status_t) apr_encode_base64(char *dest, const char *src,
163 apr_ssize_t slen, int flags, apr_size_t * len);
166 * Convert binary data to base64.
167 * @param dest The destination string, can be NULL.
168 * @param src The original buffer.
169 * @param slen The length of the original buffer.
170 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
171 * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_URL,
172 * use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
173 * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
174 * @param len If present and src is NULL, returns the maximum possible length
175 * of the destination string, including a zero pad. If present and src is
176 * not NULL, returns the number of characters actually written.
177 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL.
179 APR_DECLARE(apr_status_t) apr_encode_base64_binary(char *dest, const unsigned char *src,
180 apr_ssize_t slen, int flags, apr_size_t * len);
183 * Convert text data to base64, and return the results from a pool.
184 * @param p Pool to allocate from.
185 * @param src The original string.
186 * @param slen The length of the original string, or APR_ENCODE_STRING if
188 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
189 * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_URL,
190 * use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
191 * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
192 * @param len If present, returns the number of characters written excluding
194 * @return A zero padded string allocated from the pool on success, or
195 * NULL if src was NULL.
197 APR_DECLARE(const char *)apr_pencode_base64(apr_pool_t * p, const char *src,
198 apr_ssize_t slen, int flags, apr_size_t * len)__attribute__((nonnull(1)));
201 * Convert binary data to base64, and return the results from a pool.
202 * @param p Pool to allocate from.
203 * @param src The original buffer.
204 * @param slen The length of the original buffer.
205 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
206 * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_URL,
207 * use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
208 * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
209 * @param len If present, returns the number of characters written excluding
211 * @return A zero padded string allocated from the pool on success, or
212 * NULL if src was NULL.
214 APR_DECLARE(const char *)apr_pencode_base64_binary(apr_pool_t * p, const unsigned char *src,
215 apr_ssize_t slen, int flags, apr_size_t * len)__attribute__((nonnull(1)));
218 * Convert base64 or base64url with or without padding to text data.
219 * @param dest The destination string, can be NULL.
220 * @param src The original string.
221 * @param slen The length of the original string, or APR_ENCODE_STRING if
223 * @param flags If APR_ENCODE_NONE, attempt to decode the full original buffer,
224 * and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
225 * decode until the first non base64/base64url character.
226 * @param len If present and src is NULL, returns the maximum possible length
227 * of the destination string, including a zero pad. If present and src is
228 * not NULL, returns the number of characters actually written.
229 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL, or APR_BADCH
230 * if a non hex character is present.
232 APR_DECLARE(apr_status_t) apr_decode_base64(char *dest, const char *src,
233 apr_ssize_t slen, int flags, apr_size_t * len);
236 * Convert base64 or base64url with or without padding to binary data.
237 * @param dest The destination buffer, can be NULL.
238 * @param src The original string.
239 * @param slen The length of the original string, or APR_ENCODE_STRING if
241 * @param flags If APR_ENCODE_NONE, attempt to decode the full original buffer,
242 * and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
243 * decode until the first non base64/base64url character.
244 * @param len If present and src is NULL, returns the maximum possible length
245 * of the destination buffer, including a zero pad. If present and src is
246 * not NULL, returns the number of characters actually written.
247 * @return APR_SUCCESS, or APR_NOTFOUND if the src was NULL, or APR_BADCH
248 * if a non base64 character is present.
250 APR_DECLARE(apr_status_t) apr_decode_base64_binary(unsigned char *dest,
251 const char *src, apr_ssize_t slen, int flags, apr_size_t * len);
254 * Convert base64 or base64url with or without padding to text data, and
255 * return the results from a pool.
256 * @param p Pool to allocate from.
257 * @param src The base64 string to decode.
258 * @param slen The length of the base64 string, or APR_ENCODE_STRING if
260 * @param flags If APR_ENCODE_NONE, attempt to decode the full original buffer,
261 * and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
262 * decode until the first non base64/base64url character.
263 * @param len If present, returns the number of characters written, excluding
265 * @return A string allocated from the pool containing the result with a zero
266 * pad. If src was NULL, or an error occurred, NULL is returned.
268 APR_DECLARE(const char *)apr_pdecode_base64(apr_pool_t * p, const char *src,
269 apr_ssize_t slen, int flags, apr_size_t * len)
270 __attribute__((nonnull(1)));
273 * Convert base64 or base64url with or without padding to binary data, and
274 * return the results from a pool.
275 * @param p Pool to allocate from.
276 * @param src The original string.
277 * @param slen The length of the original string, or APR_ENCODE_STRING if
279 * @param flags If APR_ENCODE_NONE, attempt to decode the full original buffer,
280 * and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
281 * decode until the first non base64/base64url character.
282 * @param len If present, returns the number of characters written, excluding
284 * @return A buffer allocated from the pool containing the result with a zero
285 * pad. If src was NULL, or an error occurred, NULL is returned.
287 APR_DECLARE(const unsigned char *)apr_pdecode_base64_binary(apr_pool_t * p,
288 const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
289 __attribute__((nonnull(1)));
292 * Convert text data to base32.
293 * @param dest The destination string, can be NULL.
294 * @param src The original string.
295 * @param slen The length of the original string, or APR_ENCODE_STRING if
297 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
298 * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_BASE32HEX,
299 * use RFC4648 base32hex Encoding.
300 * @param len If present and src is NULL, returns the maximum possible length
301 * of the destination string, including a zero pad. If present and src is
302 * not NULL, returns the number of characters actually written.
303 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL.
305 APR_DECLARE(apr_status_t) apr_encode_base32(char *dest, const char *src,
306 apr_ssize_t slen, int flags, apr_size_t * len);
309 * Convert binary data to base32.
310 * @param dest The destination string, can be NULL.
311 * @param src The original buffer.
312 * @param slen The length of the original buffer.
313 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
314 * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_BASE32HEX,
315 * use RFC4648 base32hex Encoding.
316 * @param len If present and src is NULL, returns the maximum possible length
317 * of the destination string, including a zero pad. If present and src is
318 * not NULL, returns the number of characters actually written.
319 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL.
321 APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned char *src,
322 apr_ssize_t slen, int flags, apr_size_t * len);
325 * Convert text data to base32, and return the results from a pool.
326 * @param p Pool to allocate from.
327 * @param src The original string.
328 * @param slen The length of the original string, or APR_ENCODE_STRING if
330 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
331 * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_BASE32HEX,
332 * use RFC4648 base32hex Encoding.
333 * @param len If present, returns the number of characters written excluding
335 * @return A zero padded string allocated from the pool on success, or
336 * NULL if src was NULL.
338 APR_DECLARE(const char *)apr_pencode_base32(apr_pool_t * p, const char *src,
339 apr_ssize_t slen, int flags, apr_size_t * len)
340 __attribute__((nonnull(1)));
343 * Convert binary data to base32, and return the results from a pool.
344 * @param p Pool to allocate from.
345 * @param src The original buffer.
346 * @param slen The length of the original buffer.
347 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
348 * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_BASE32HEX,
349 * use RFC7515 base32hex Encoding.
350 * @param len If present, returns the number of characters written excluding
352 * @return A zero padded string allocated from the pool on success, or
353 * NULL if src was NULL.
355 APR_DECLARE(const char *)apr_pencode_base32_binary(apr_pool_t * p, const unsigned char *src,
356 apr_ssize_t slen, int flags, apr_size_t * len)
357 __attribute__((nonnull(1)));
360 * Convert base32 or base32hex with or without padding to text data.
361 * @param dest The destination string, can be NULL.
362 * @param src The original string.
363 * @param slen The length of the original string, or APR_ENCODE_STRING if
365 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
366 * APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
367 * @param len If present and src is NULL, returns the maximum possible length
368 * of the destination buffer, including a zero pad. If present and src is
369 * not NULL, returns the number of characters actually written.
370 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL, or APR_BADCH
371 * if a non base32 character is present.
373 APR_DECLARE(apr_status_t) apr_decode_base32(char *dest, const char *src,
374 apr_ssize_t slen, int flags, apr_size_t * len);
377 * Convert base32 or base32hex with or without padding to binary data.
378 * @param dest The destination buffer, can be NULL.
379 * @param src The original string.
380 * @param slen The length of the original string, or APR_ENCODE_STRING if
382 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
383 * APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
384 * @param len If present and src is NULL, returns the maximum possible length
385 * of the destination buffer, including a zero pad. If present and src is
386 * not NULL, returns the number of characters actually written.
387 * @return APR_SUCCESS, or APR_NOTFOUND if the src was NULL, or APR_BADCH
388 * if a non base32 character is present.
390 APR_DECLARE(apr_status_t) apr_decode_base32_binary(unsigned char *dest,
391 const char *src, apr_ssize_t slen, int flags, apr_size_t * len);
394 * Convert base32 or base32hex with or without padding to text data, and
395 * return the results from a pool.
396 * @param p Pool to allocate from.
397 * @param src The base32 string to decode.
398 * @param slen The length of the base32 string, or APR_ENCODE_STRING if
400 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
401 * APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
402 * @param len If present, returns the number of characters written, excluding
404 * @return A string allocated from the pool containing the result with a zero
405 * pad. If src was NULL, or an error occurred, NULL is returned.
407 APR_DECLARE(const char *)apr_pdecode_base32(apr_pool_t * p, const char *src,
408 apr_ssize_t slen, int flags, apr_size_t * len)
409 __attribute__((nonnull(1)));
412 * Convert base32 or base32hex with or without padding to binary data, and
413 * return the results from a pool.
414 * @param p Pool to allocate from.
415 * @param src The original string.
416 * @param slen The length of the original string, or APR_ENCODE_STRING if
418 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
419 * APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
420 * @param len If present, returns the number of characters written, excluding
422 * @return A buffer allocated from the pool containing the result with a zero
423 * pad. If src was NULL, or an error occurred, NULL is returned.
425 APR_DECLARE(const unsigned char *)apr_pdecode_base32_binary(apr_pool_t * p,
426 const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
427 __attribute__((nonnull(1)));
430 * Convert text data to base16 (hex).
431 * @param dest The destination string, can be NULL.
432 * @param src The original string.
433 * @param slen The length of the original string, or APR_ENCODE_STRING if
435 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
436 * APR_ENCODE_COLON, separate each token with a colon.
437 * @param len If present and src is NULL, returns the maximum possible length
438 * of the destination buffer, including a zero pad. If present and src is
439 * not NULL, returns the number of characters actually written.
440 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL.
442 APR_DECLARE(apr_status_t) apr_encode_base16(char *dest, const char *src,
443 apr_ssize_t slen, int flags, apr_size_t * len);
446 * Convert binary data to base16 (hex).
447 * @param dest The destination string, can be NULL.
448 * @param src The original buffer.
449 * @param slen The length of the original buffer.
450 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
451 * APR_ENCODE_COLON, separate each token with a colon.
452 * @param len If present and src is NULL, returns the maximum possible length
453 * of the destination buffer, including a zero pad. If present and src is
454 * not NULL, returns the number of characters actually written.
455 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL.
457 APR_DECLARE(apr_status_t) apr_encode_base16_binary(char *dest,
458 const unsigned char *src, apr_ssize_t slen, int flags,
462 * Convert text data to base16 (hex), and return the results from a
464 * @param p Pool to allocate from.
465 * @param src The original string.
466 * @param slen The length of the original string, or APR_ENCODE_STRING if
468 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
469 * APR_ENCODE_COLON, separate each token with a colon.
470 * @param len If present, returns the number of characters written, excluding
472 * @return A string allocated from the pool containing the result with a zero
473 * pad. If src was NULL, or an error occurred, NULL is returned.
475 APR_DECLARE(const char *)apr_pencode_base16(apr_pool_t * p, const char *src,
476 apr_ssize_t slen, int flags, apr_size_t * len)
477 __attribute__((nonnull(1)));
480 * Convert binary data to base16 (hex), and return the results from a
482 * @param p Pool to allocate from.
483 * @param src The original buffer.
484 * @param slen The length of the original buffer.
485 * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
486 * APR_ENCODE_COLON, separate each token with a colon.
487 * @param len If present, returns the number of characters written, excluding
489 * @return A string allocated from the pool containing the result with a zero
490 * pad. If src was NULL, or an error occurred, NULL is returned.
492 APR_DECLARE(const char *)apr_pencode_base16_binary(apr_pool_t * p,
493 const unsigned char *src, apr_ssize_t slen,
494 int flags, apr_size_t * len)__attribute__((nonnull(1)));
497 * Convert base16 (hex) to text data.
498 * @param dest The destination string, can be NULL.
499 * @param src The original string.
500 * @param slen The length of the original string, or APR_ENCODE_STRING if
502 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
503 * APR_ENCODE_COLON, allow tokens to be separated with a colon.
504 * @param len If present and src is NULL, returns the maximum possible length
505 * of the destination buffer, including a zero pad. If present and src is
506 * not NULL, returns the number of characters actually written.
507 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL, or APR_BADCH
508 * if a non hex character is present. A zero pad is appended to the buffer.
510 APR_DECLARE(apr_status_t) apr_decode_base16(char *dest, const char *src,
511 apr_ssize_t slen, int flags, apr_size_t * len);
514 * Convert base16 (hex) to binary data.
515 * @param dest The destination buffer, can be NULL.
516 * @param src The original string.
517 * @param slen The length of the original string, or APR_ENCODE_STRING if
519 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
520 * APR_ENCODE_COLON, allow tokens to be separated with a colon.
521 * @param len If present and src is NULL, returns the maximum possible length
522 * of the destination buffer, including a zero pad. If present and src is
523 * not NULL, returns the number of characters actually written.
524 * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL, or APR_BADCH
525 * if a non hex character is present. No zero pad is written to the buffer.
527 APR_DECLARE(apr_status_t) apr_decode_base16_binary(unsigned char *dest,
528 const char *src, apr_ssize_t slen, int flags, apr_size_t * len);
531 * Convert base16 (hex) and return the results from a pool.
532 * @param p Pool to allocate from.
533 * @param src The original string.
534 * @param slen The length of the original string, or APR_ENCODE_STRING if
536 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
537 * APR_ENCODE_COLON, allow tokens to be separated with a colon.
538 * @param len If present, returns the number of characters written, excluding
540 * @return A buffer allocated from the pool containing the result with a zero
541 * pad. If src was NULL, or an error occurred, NULL is returned.
543 APR_DECLARE(const char *)apr_pdecode_base16(apr_pool_t * p, const char *src,
544 apr_ssize_t slen, int flags, apr_size_t * len)
545 __attribute__((nonnull(1)));
548 * Convert base16 (hex) to binary data, and return the results from a pool.
549 * @param p Pool to allocate from.
550 * @param src The original string.
551 * @param slen The length of the original string, or APR_ENCODE_STRING if
553 * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
554 * APR_ENCODE_COLON, allow tokens to be separated with a colon.
555 * @param len If present, returns the number of characters written, excluding
557 * @return A buffer allocated from the pool containing the result with a zero
558 * pad. If src was NULL, or an error occurred, NULL is returned.
560 APR_DECLARE(const unsigned char *)apr_pdecode_base16_binary(apr_pool_t * p,
561 const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
562 __attribute__((nonnull(1)));
569 #endif /* !APR_ENCODE_H */