diff --git a/src/libutil/Makefile.am b/src/libutil/Makefile.am index 238025f826d5..1d2c01507727 100644 --- a/src/libutil/Makefile.am +++ b/src/libutil/Makefile.am @@ -15,8 +15,6 @@ noinst_LTLIBRARIES = \ libutil.la libutil_la_SOURCES = \ - base64.c \ - base64.h \ thread.h \ hash.c \ hash.h \ @@ -33,7 +31,6 @@ libutil_la_SOURCES = \ macros.h TESTS = \ - test_base64.t \ test_hash.t \ test_tomltk.t \ test_cf.t \ @@ -56,10 +53,6 @@ TEST_EXTENSIONS = .t T_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \ $(top_srcdir)/config/tap-driver.sh -test_base64_t_SOURCES = test/base64_test.c -test_base64_t_CPPFLAGS = $(test_cppflags) -test_base64_t_LDADD = $(test_ldadd) - test_hash_t_SOURCES = test/hash.c test_hash_t_CPPFLAGS = $(test_cppflags) test_hash_t_LDADD = $(test_ldadd) diff --git a/src/libutil/base64.c b/src/libutil/base64.c deleted file mode 100644 index 8bdcd3fe260e..000000000000 --- a/src/libutil/base64.c +++ /dev/null @@ -1,443 +0,0 @@ -/***************************************************************************** - * Written by Chris Dunlap . - * Copyright (C) 2007-2017 Lawrence Livermore National Security, LLC. - * Copyright (C) 2002-2007 The Regents of the University of California. - * UCRL-CODE-155910. - * - * This file is part of the MUNGE Uid 'N' Gid Emporium (MUNGE). - * For details, see . - * - * MUNGE is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) - * any later version. Additionally for the MUNGE library (libmunge), you - * can redistribute it and/or modify it under the terms of the GNU Lesser - * General Public License as published by the Free Software Foundation, - * either version 3 of the License, or (at your option) any later version. - * - * MUNGE is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * and GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * and GNU Lesser General Public License along with MUNGE. If not, see - * . - *****************************************************************************/ - - -#if HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include -#include -#include "base64.h" - - -/***************************************************************************** - * Notes - *****************************************************************************/ -/* - * For details on base64 encoding/decoding, refer to - * rfc2440 (OpenPGP Message Format) sections 6.3-6.5. - * - * Why am I not using OpenSSL's base64 encoding/decoding functions? - * Because they have the following fucked functionality: - * For base64-encoding, use of the context results in output that is broken - * into 64-character lines; however, EVP_EncodeBlock() output is not broken. - * For base64-decoding, use of the context returns the correct length of the - * resulting output; however, EVP_DecodeBlock() returns a length that may - * be up to two characters too long. - * Finally, data base64-encoded via a context has to be decoded via a context, - * and data base64-encoded w/o a context has to be decoded w/o a context. - * So fuck it, I wrote my own. :-P - */ - -/***************************************************************************** - * Constants - *****************************************************************************/ - -#define BASE64_MAGIC 0xDEADBEEF -#define BASE64_ERR 0xFF -#define BASE64_IGN 0xFE -#define BASE64_PAD 0xFD -#define BASE64_PAD_CHAR '=' - - -/***************************************************************************** - * Static Variables - *****************************************************************************/ - -static const unsigned char bin2asc[] = \ - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static const unsigned char asc2bin[256] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, - 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, - 0xff, 0xfd, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff -}; - - -/***************************************************************************** - * Extern Functions - *****************************************************************************/ - -int -base64_init (base64_ctx *x) -{ - assert (x != NULL); - - x->num = 0; - x->pad = 0; - assert (x->magic = BASE64_MAGIC); - assert (!(x->finalized = 0)); - return (0); -} - - -int -base64_encode_update (base64_ctx *x, void *vdst, int *dstlen, - const void *vsrc, int srclen) -{ - int n; - int num_read; - int num_write; - unsigned char *dst = (unsigned char *) vdst; - unsigned char *src = (unsigned char *) vsrc; - - assert (x != NULL); - assert (x->magic == BASE64_MAGIC); - assert (x->finalized != 1); - assert (dst != NULL); - assert (dstlen != NULL); - assert (src != NULL); - - num_write = 0; - - if (srclen <= 0) { - return (0); - } - /* Encode leftover data if context buffer can be filled. - */ - if ((x->num > 0) && (srclen >= (num_read = 3 - x->num))) { - memcpy (&x->buf[x->num], src, num_read); - src += num_read; - srclen -= num_read; - base64_encode_block (dst, &n, x->buf, 3); - x->num = 0; - dst += n; - num_write += n; - } - /* Encode maximum amount of data w/o requiring a pad. - */ - if (srclen >= 3) { - num_read = (srclen / 3) * 3; - base64_encode_block (dst, &n, src, num_read); - src += num_read; - srclen -= num_read; - num_write += n; - } - /* Save leftover data for the next update() or final(). - */ - if (srclen > 0) { - memcpy (&x->buf[x->num], src, srclen); - x->num += srclen; - } - *dstlen = num_write; - return (0); -} - - -int -base64_encode_final (base64_ctx *x, void *dst, int *dstlen) -{ - assert (x != NULL); - assert (x->magic == BASE64_MAGIC); - assert (x->finalized != 1); - assert (dst != NULL); - assert (dstlen != NULL); - - /* Encode leftover data from the previous update(). - */ - if (x->num > 0) { - base64_encode_block (dst, dstlen, x->buf, x->num); - x->num = 0; - } - else { - *dstlen = 0; - } - assert (x->finalized = 1); - return (0); -} - - -int -base64_decode_update (base64_ctx *x, void *dst, int *dstlen, - const void *src, int srclen) -{ -/* Context [x] should only be NULL when called via base64_decode_block(). - */ - int i = 0; - int err = 0; - int pad = 0; - unsigned char *pdst; - const unsigned char *psrc; - const unsigned char *psrc_last; - unsigned char c; - - assert ((x == NULL) || (x->magic == BASE64_MAGIC)); - assert ((x == NULL) || (x->finalized != 1)); - assert (dst != NULL); - assert (dstlen != NULL); - assert (src != NULL); - - pdst = dst; - psrc = src; - psrc_last = psrc + srclen; - - /* Restore context. - */ - if (x != NULL) { - i = x->num; - pad = x->pad; - *pdst = x->buf[0]; - } - while (psrc < psrc_last) { - c = asc2bin[*psrc++]; - if (c == BASE64_IGN) { - continue; - } - if ((c == BASE64_PAD) && (pad < 2)) { - pad++; - continue; - } - if ((c == BASE64_ERR) || (pad > 0)) { - err++; - break; - } - switch (i) { - case 0: - *pdst = (c << 2) & 0xfc; - break; - case 1: - *pdst++ |= (c >> 4) & 0x03; - *pdst = (c << 4) & 0xf0; - break; - case 2: - *pdst++ |= (c >> 2) & 0x0f; - *pdst = (c << 6) & 0xc0; - break; - case 3: - *pdst++ |= (c ) & 0x3f; - break; - } - i = (i + 1) % 4; - } - /* Save context. - */ - if (x != NULL) { - x->num = i; - x->pad = pad; - x->buf[0] = *pdst; - } - /* Check for the correct amount of padding. - */ - else if (!err) { - err = (((i + pad) % 4) != 0); - } - *pdst = '\0'; - *dstlen = pdst - (unsigned char *) dst; - return (err ? -1 : 0); -} - - -int -base64_decode_final (base64_ctx *x, void *dst, int *dstlen) -{ - int rc = 0; - - assert (x != NULL); - assert (x->magic == BASE64_MAGIC); - assert (x->finalized != 1); - - if (((x->num + x->pad) % 4) != 0) { - rc = -1; - } - *dstlen = 0; - assert (x->finalized = 1); - return (rc); -} - - -int -base64_cleanup (base64_ctx *x) -{ - assert (x != NULL); - assert (x->magic == BASE64_MAGIC); - - memset (x, 0, sizeof (*x)); - assert (x->magic = ~BASE64_MAGIC); - return (0); -} - - -int -base64_encode_block (void *dst, int *dstlen, const void *src, int srclen) -{ - unsigned char *pdst; - const unsigned char *psrc; - int n; - - pdst = dst; - psrc = src; - n = 0; - while (srclen >= 3) { - *pdst++ = bin2asc[ (psrc[0] >> 2) & 0x3f]; - *pdst++ = bin2asc[((psrc[0] << 4) & 0x30) | ((psrc[1] >> 4) & 0x0f)]; - *pdst++ = bin2asc[((psrc[1] << 2) & 0x3c) | ((psrc[2] >> 6) & 0x03)]; - *pdst++ = bin2asc[ (psrc[2] ) & 0x3f]; - psrc += 3; - srclen -= 3; - n += 4; - } - if (srclen == 2) { - *pdst++ = bin2asc[ (psrc[0] >> 2) & 0x3f]; - *pdst++ = bin2asc[((psrc[0] << 4) & 0x30) | ((psrc[1] >> 4) & 0x0f)]; - *pdst++ = bin2asc[ (psrc[1] << 2) & 0x3c]; - *pdst++ = '='; - n += 4; - } - else if (srclen == 1) { - *pdst++ = bin2asc[ (psrc[0] >> 2) & 0x3f]; - *pdst++ = bin2asc[ (psrc[0] << 4) & 0x30]; - *pdst++ = '='; - *pdst++ = '='; - n += 4; - } - *pdst = '\0'; - *dstlen = n; - return (0); -} - - -int -base64_decode_block (void *dst, int *dstlen, const void *src, int srclen) -{ - return (base64_decode_update (NULL, dst, dstlen, src, srclen)); -} - - -int -base64_encode_length (int srclen) -{ -/* When encoding, 3 bytes are encoded into 4 characters. - * Add 2 bytes to ensure a partial 3-byte chunk will be accounted for - * during integer division, then add 1 byte for the terminating NUL. - */ - return (((srclen + 2) / 3) * 4) + 1; -} - - -int -base64_decode_length (int srclen) -{ -/* When decoding, 4 characters are decoded into 3 bytes. - * Add 3 bytes to ensure a partial 4-byte chunk will be accounted for - * during integer division, then add 1 byte for the terminating NUL. - */ - return (((srclen + 3) / 4) * 3) + 1; -} - - -/***************************************************************************** - * Table Initialization Routines - *****************************************************************************/ - -#ifdef BASE64_INIT - - -#include -#include -#include - - -#define BASE64_DEF_COLS 12 - - -void base64_build_table (unsigned char *data, int len); -void base64_print_table (unsigned char *data, int len, char *name, int col); - - -int -main (int argc, char *argv[]) -{ - int col; - unsigned char a2b[256]; - - col = (argc > 1) ? atoi (argv[1]) : BASE64_DEF_COLS; - - base64_build_table (a2b, sizeof (a2b)); - base64_print_table (a2b, sizeof (a2b), "asc2bin", col); - exit (EXIT_SUCCESS); -} - - -void -base64_build_table (unsigned char *data, int len) -{ - int i; - - for (i = 0; i < len; i++) - data[i] = (isspace (i)) ? BASE64_IGN : BASE64_ERR; - for (i = strlen (bin2asc) - 1; i >= 0; i--) - data[bin2asc[i]] = i; - data[BASE64_PAD_CHAR] = BASE64_PAD; - return; -} - - -void -base64_print_table (unsigned char *data, int len, char *name, int col) -{ - int i; - int n; - - if (col < 1) { - col = BASE64_DEF_COLS; - } - printf ("static const unsigned char %s[%d] = {", name, len); - - for (i=0, n=len-1; ; i++) { - if ((i % col) == 0) - printf ("\n "); - printf ("0x%02x", data[i]); - if (i == n) - break; - printf (", "); - } - printf ("\n};\n"); - return; -} - - -#endif /* BASE64_INIT */ diff --git a/src/libutil/base64.h b/src/libutil/base64.h deleted file mode 100644 index 28b9ba63c8b9..000000000000 --- a/src/libutil/base64.h +++ /dev/null @@ -1,134 +0,0 @@ -/***************************************************************************** - * Written by Chris Dunlap . - * Copyright (C) 2007-2017 Lawrence Livermore National Security, LLC. - * Copyright (C) 2002-2007 The Regents of the University of California. - * UCRL-CODE-155910. - * - * This file is part of the MUNGE Uid 'N' Gid Emporium (MUNGE). - * For details, see . - * - * MUNGE is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) - * any later version. Additionally for the MUNGE library (libmunge), you - * can redistribute it and/or modify it under the terms of the GNU Lesser - * General Public License as published by the Free Software Foundation, - * either version 3 of the License, or (at your option) any later version. - * - * MUNGE is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * and GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * and GNU Lesser General Public License along with MUNGE. If not, see - * . - *****************************************************************************/ - - -#ifndef BASE64_H -#define BASE64_H - - -#if HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - - -/***************************************************************************** - * Data Types - *****************************************************************************/ - -typedef struct { - unsigned char buf[3]; - int num; - int pad; -#ifndef NDEBUG - int magic; - int finalized; -#endif /* !NDEBUG */ -} base64_ctx; - - -/***************************************************************************** - * Prototypes - *****************************************************************************/ - -int base64_init (base64_ctx *x); -/* - * Initializes the base64 context [x] for base64 encoding/decoding of data. - * Returns 0 on success, or -1 on error. - */ - -int base64_encode_update (base64_ctx *x, void *dst, int *dstlen, - const void *src, int srclen); -/* - * Updates the base64 context [x], encoding [srclen] bytes from [src] - * into [dst], and setting [dstlen] to the number of bytes written. - * This can be called multiple times to process successive blocks of data. - * Returns 0 on success, or -1 on error. - */ - -int base64_encode_final (base64_ctx *x, void *dst, int *dstlen); -/* - * Finalizes the base64 context [x], encoding the "final" data remaining - * in a partial block into [dst], and setting [dstlen] to the number of - * bytes written. - * After calling this function, no further updates should be made to [x] - * without re-initializing it first. - * Returns 0 on success, or -1 on error. - */ - -int base64_decode_update (base64_ctx *x, void *dst, int *dstlen, - const void *src, int srclen); -/* - * Updates the base64 context [x], decoding [srclen] bytes from [src] - * into [dst], and setting [dstlen] to the number of bytes written. - * This can be called multiple times to process successive blocks of data. - * Returns 0 on success, or -1 on error. - */ - -int base64_decode_final (base64_ctx *x, void *dst, int *dstlen); -/* - * Finalizes the base64 context [x], decoding the "final" data remaining - * in a partial block into [dst], and setting [dstlen] to the number of - * bytes written. - * After calling this function, no further updates should be made to [x] - * without re-initializing it first. - * Returns 0 on success, or -1 on error. - */ - -int base64_cleanup (base64_ctx *x); -/* - * Clears the base64 context [x]. - * Returns 0 on success, or -1 on error. - */ - -int base64_encode_block (void *dst, int *dstlen, const void *src, int srclen); -/* - * Base64-encodes [srclen] bytes from the contiguous [src] into [dst], - * and sets [dstlen] to the number of bytes written. - * Returns 0 on success, or -1 on error. - */ - -int base64_decode_block (void *dst, int *dstlen, const void *src, int srclen); -/* - * Base64-decodes [srclen] bytes from the contiguous [src] into [dst], - * and sets [dstlen] to the number of bytes written. - * Returns 0 on success, or -1 on error. - */ - -int base64_encode_length (int srclen); -/* - * Returns the size (in bytes) of the destination memory block required - * for base64 encoding a block of [srclen] bytes. - */ - -int base64_decode_length (int srclen); -/* - * Returns the size (in bytes) of the destination memory block required - * for base64 decoding a block of [srclen] bytes. - */ - - -#endif /* !BASE64_H */ diff --git a/src/libutil/test/base64_test.c b/src/libutil/test/base64_test.c deleted file mode 100644 index a9318d0b89a5..000000000000 --- a/src/libutil/test/base64_test.c +++ /dev/null @@ -1,175 +0,0 @@ -/***************************************************************************** - * Written by Chris Dunlap . - * Copyright (C) 2007-2017 Lawrence Livermore National Security, LLC. - * Copyright (C) 2002-2007 The Regents of the University of California. - * UCRL-CODE-155910. - * - * This file is part of the MUNGE Uid 'N' Gid Emporium (MUNGE). - * For details, see . - * - * MUNGE is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) - * any later version. Additionally for the MUNGE library (libmunge), you - * can redistribute it and/or modify it under the terms of the GNU Lesser - * General Public License as published by the Free Software Foundation, - * either version 3 of the License, or (at your option) any later version. - * - * MUNGE is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * and GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * and GNU Lesser General Public License along with MUNGE. If not, see - * . - *****************************************************************************/ - - -#include -#include -#include -#include "base64.h" - -#include "src/libtap/tap.h" - - -/* Test cases from rfc2440 (OpenPGP Message Format) - * section 6.5 (Examples of Radix-64). - */ - -int validate (const char *dst, const void *src, int srclen); -int encode_block (char *dst, int *dstlen, const void *src, int srclen); -int encode_context (char *dst, int *dstlen, const void *src, int srclen); -int decode_block (char *dst, int *dstlen, const void *src, int srclen); -int decode_context (char *dst, int *dstlen, const void *src, int srclen); - - -int -main (int argc, char *argv[]) -{ - const unsigned char src1[] = { 0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e }; - const unsigned char src2[] = { 0x14, 0xfb, 0x9c, 0x03, 0xd9 }; - const unsigned char src3[] = { 0x14, 0xfb, 0x9c, 0x03 }; - - const char dst1[] = "FPucA9l+"; - const char dst2[] = "FPucA9k="; - const char dst3[] = "FPucAw=="; - - plan (NO_PLAN); - - ok (validate (dst1, src1, sizeof (src1)) >= 0, - "base64 pattern 1"); - ok (validate (dst2, src2, sizeof (src2)) >= 0, - "base64 pattern 2"); - ok (validate (dst3, src3, sizeof (src3)) >= 0, - "base64 pattern 3"); - - done_testing (); -} - - -int -validate (const char *dst, const void *src, int srclen) -{ - int n; - char buf[9]; - - if (encode_block (buf, &n, src, srclen) < 0) - return (-1); - if (n != strlen (dst)) - return (-1); - if (strncmp (dst, buf, n)) - return (-1); - - if (decode_block (buf, &n, dst, strlen (dst)) < 0) - return (-1); - if (n != srclen) - return (-1); - if (strncmp (src, buf, n)) - return (-1); - - if (encode_context (buf, &n, src, srclen) < 0) - return (-1); - if (n != strlen (dst)) - return (-1); - if (strncmp (dst, buf, n)) - return (-1); - - if (decode_context (buf, &n, dst, strlen (dst)) < 0) - return (-1); - if (n != srclen) - return (-1); - if (strncmp (src, buf, n)) - return (-1); - - return (0); -} - - -int -encode_block (char *dst, int *dstlen, const void *src, int srclen) -{ - return (base64_encode_block (dst, dstlen, src, srclen)); -} - - -int -encode_context (char *dst, int *dstlen, const void *src, int srclen) -{ - base64_ctx x; - int i; - int n; - int m; - const unsigned char *p = src; - - if (base64_init (&x) < 0) - return (-1); - for (i = 0, n = 0; i < srclen; i++) { - if (base64_encode_update (&x, dst, &m, p + i, 1) < 0) - return (-1); - dst += m; - n += m; - } - if (base64_encode_final (&x, dst, &m) < 0) - return (-1); - if (base64_cleanup (&x) < 0) - return (-1); - n += m; - *dstlen = n; - return (0); -} - - -int -decode_block (char *dst, int *dstlen, const void *src, int srclen) -{ - return (base64_decode_block (dst, dstlen, src, srclen)); -} - - -int -decode_context (char *dst, int *dstlen, const void *src, int srclen) -{ - base64_ctx x; - int i; - int n; - int m; - const unsigned char *p = src; - - if (base64_init (&x) < 0) - return (-1); - for (i = 0, n = 0; i < srclen; i++) { - if (base64_decode_update (&x, dst, &m, p + i, 1) < 0) - return (-1); - dst += m; - n += m; - } - if (base64_decode_final (&x, dst, &m) < 0) - return (-1); - if (base64_cleanup (&x) < 0) - return (-1); - n += m; - *dstlen = n; - return (0); -}