Blame tests/t-b64.c

Packit fc043f
/* t-b64.c - b64dec tests.
Packit fc043f
 * Copyright (C) 2017, 2018 g10 Code GmbH
Packit fc043f
 *
Packit fc043f
 * This file is part of Libgpg-error.
Packit fc043f
 *
Packit fc043f
 * This file is free software; you can redistribute it and/or modify
Packit fc043f
 * it under the terms of the GNU Lesser General Public License as
Packit fc043f
 * published by the Free Software Foundation; either version 2.1 of
Packit fc043f
 * the License, or (at your option) any later version.
Packit fc043f
 *
Packit fc043f
 * This file is distributed in the hope that it will be useful,
Packit fc043f
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit fc043f
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit fc043f
 * GNU Lesser General Public License for more details.
Packit fc043f
 *
Packit fc043f
 * You should have received a copy of the GNU Lesser General Public License
Packit fc043f
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
Packit fc043f
 * SPDX-License-Identifier: LGPL-2.1-or-later
Packit fc043f
 */
Packit fc043f
Packit fc043f
#if HAVE_CONFIG_H
Packit fc043f
#include <config.h>
Packit fc043f
#endif
Packit fc043f
Packit fc043f
#include <stdio.h>
Packit fc043f
#include <string.h>
Packit fc043f
#if HAVE_STDLIB_H
Packit fc043f
#include <stdlib.h>
Packit fc043f
#endif
Packit fc043f
Packit fc043f
#define PGM "t-b64"
Packit fc043f
#include "t-common.h"
Packit fc043f
Packit fc043f
static const char *test_string = "libgpg-error is free software; "
Packit fc043f
  "you can redistribute it and/or modify it under the terms of "
Packit fc043f
  "the GNU Lesser General Public License as published by the Free "
Packit fc043f
  "Software Foundation; either version 2.1 of the License, or "
Packit fc043f
  "(at your option) any later version.";
Packit fc043f
Packit fc043f
static const char *test_string_b64_0 = "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29"
Packit fc043f
  "mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgd"
Packit fc043f
  "W5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIEx"
Packit fc043f
  "pY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb"
Packit fc043f
  "247IGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXI"
Packit fc043f
  "gb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4=";
Packit fc043f
Packit fc043f
static const char *test_string_b64_1 =
Packit fc043f
  "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmli\n"
Packit fc043f
  "dXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBH\n"
Packit fc043f
  "TlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5\n"
Packit fc043f
  "IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIu\n"
Packit fc043f
  "MSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIg\n"
Packit fc043f
  "dmVyc2lvbi4=\n";
Packit fc043f
Packit fc043f
static const char *test_string_b64_2 =
Packit fc043f
  "-----BEGIN DATA-----\n"
Packit fc043f
  "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmli\n"
Packit fc043f
  "dXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBH\n"
Packit fc043f
  "TlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5\n"
Packit fc043f
  "IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIu\n"
Packit fc043f
  "MSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIg\n"
Packit fc043f
  "dmVyc2lvbi4=\n"
Packit fc043f
  "-----END DATA-----\n";
Packit fc043f
Packit fc043f
static const char *test_string_b64_3 =
Packit fc043f
  "-----BEGIN PGP ARMORED FILE-----\n"
Packit fc043f
  "\n"
Packit fc043f
  "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmli\n"
Packit fc043f
  "dXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBH\n"
Packit fc043f
  "TlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5\n"
Packit fc043f
  "IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIu\n"
Packit fc043f
  "MSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIg\n"
Packit fc043f
  "dmVyc2lvbi4=\n"
Packit fc043f
  "=4BMJ\n"
Packit fc043f
  "-----END PGP ARMORED FILE-----\n";
Packit fc043f
Packit fc043f
static const char *test_blob_1 = "\x01\x03\x04\xff";
Packit fc043f
static const char *test_blob_1_b64_0 = "AQME/w==";
Packit fc043f
static const char *test_blob_2 = "\x01\x03\x04\xff""A";
Packit fc043f
static const char *test_blob_2_b64_0 = "AQME/0E=";
Packit fc043f
static const char *test_blob_3 = "\x01\x03\x04\xff""AB";
Packit fc043f
static const char *test_blob_3_b64_0 = "AQME/0FC";
Packit fc043f
Packit fc043f
Packit fc043f
#define FAIL(a)  do { fail ("line %d: test %d failed\n", __LINE__, (a));  \
Packit fc043f
                    } while(0)
Packit fc043f
Packit fc043f
static gpg_error_t
Packit fc043f
test_b64enc_string (const char *string, const char *expected, const char *title)
Packit fc043f
{
Packit fc043f
  gpg_err_code_t err;
Packit fc043f
  estream_t fp;
Packit fc043f
  gpgrt_b64state_t state;
Packit fc043f
  char *result;
Packit fc043f
Packit fc043f
  fp = es_fopenmem (0, "rwb");
Packit fc043f
  if (!fp)
Packit fc043f
    die ("es_fopenmem failed: %s\n", gpg_strerror (gpg_error_from_syserror ()));
Packit fc043f
Packit fc043f
  state = gpgrt_b64enc_start (fp, title);
Packit fc043f
  if (!state)
Packit fc043f
    {
Packit fc043f
      err = gpg_err_code_from_syserror ();
Packit fc043f
      fail ("gpgrt_b64enc_start failed: %s\n", gpg_strerror (err));
Packit fc043f
      return err;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  err = gpgrt_b64enc_write (state, string, strlen (string));
Packit fc043f
  if (err)
Packit fc043f
    {
Packit fc043f
      fail ("gpgrt_b64enc_write failed: %s\n", gpg_strerror (err));
Packit fc043f
      return err;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  err = gpgrt_b64enc_finish (state);
Packit fc043f
  if (err)
Packit fc043f
    {
Packit fc043f
      fail ("gpgrt_b64enc_finish failed: %s\n", gpg_strerror (err));
Packit fc043f
      return err;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  es_fputc (0, fp);
Packit fc043f
  if (es_fclose_snatch (fp, (void**)&result, NULL))
Packit fc043f
    die ("es_fclose_snatch failed: %s\n",
Packit fc043f
         gpg_strerror (gpg_error_from_syserror ()));
Packit fc043f
Packit fc043f
  if (strcmp (result, expected))
Packit fc043f
    {
Packit fc043f
      if (verbose)
Packit fc043f
        {
Packit fc043f
          gpgrt_log_debug_string (result,   "result: ");
Packit fc043f
          gpgrt_log_debug_string (expected, "expect: ");
Packit fc043f
        }
Packit fc043f
      return GPG_ERR_FALSE;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  es_free (result);
Packit fc043f
  return 0;
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
static gpg_error_t
Packit fc043f
test_b64dec_string (const char *string, const char *expected, const char *title)
Packit fc043f
{
Packit fc043f
  gpg_error_t err;
Packit fc043f
  gpgrt_b64state_t state;
Packit fc043f
  char *buffer;
Packit fc043f
  size_t len;
Packit fc043f
Packit fc043f
  len = strlen (string);
Packit fc043f
  buffer = malloc (strlen (string) + 1);
Packit fc043f
  if (!buffer)
Packit fc043f
    {
Packit fc043f
      err = gpg_error_from_syserror ();
Packit fc043f
      return err;
Packit fc043f
    }
Packit fc043f
  strcpy (buffer, string);
Packit fc043f
Packit fc043f
  state = gpgrt_b64dec_start (title);
Packit fc043f
  if (!state)
Packit fc043f
    {
Packit fc043f
      err = gpg_err_code_from_syserror ();
Packit fc043f
      fail ("gpgrt_b64dec_start failed: %s\n", gpg_strerror (err));
Packit fc043f
      return err;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  err = gpgrt_b64dec_proc (state, buffer, len, &len;;
Packit fc043f
  if (err)
Packit fc043f
    {
Packit fc043f
      if (gpg_err_code (err) != GPG_ERR_EOF)
Packit fc043f
        {
Packit fc043f
          free (buffer);
Packit fc043f
          free (state);
Packit fc043f
          return err;
Packit fc043f
        }
Packit fc043f
    }
Packit fc043f
Packit fc043f
  err = gpgrt_b64dec_finish (state);
Packit fc043f
  if (err)
Packit fc043f
    {
Packit fc043f
      free (buffer);
Packit fc043f
      return err;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  if (len != strlen (expected) || strncmp (buffer, expected, len))
Packit fc043f
    {
Packit fc043f
      if (verbose)
Packit fc043f
        {
Packit fc043f
          gpgrt_log_debug_string (buffer,   "result(len=%zu): ", len);
Packit fc043f
          gpgrt_log_debug_string (expected, "expect(len=%zu): ",
Packit fc043f
                                  strlen (expected));
Packit fc043f
        }
Packit fc043f
      return GPG_ERR_FALSE;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  free (buffer);
Packit fc043f
  return 0;
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
static void
Packit fc043f
encoder_tests (void)
Packit fc043f
{
Packit fc043f
  gpg_err_code_t err;
Packit fc043f
Packit fc043f
  if (verbose)
Packit fc043f
    show ("running encoder tests\n");
Packit fc043f
Packit fc043f
  err = test_b64enc_string (test_string, test_string_b64_0, "");
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
  err = test_b64enc_string (test_string, test_string_b64_1, NULL);
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
  err = test_b64enc_string (test_string, test_string_b64_2, "DATA");
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
  err = test_b64enc_string (test_string, test_string_b64_3, "PGP ARMORED FILE");
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
Packit fc043f
  /* Note that the _test_ function dows not allow to provide a string
Packit fc043f
   * with an empdded Nul.  */
Packit fc043f
  err = test_b64enc_string (test_blob_1, test_blob_1_b64_0, "");
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
  err = test_b64enc_string (test_blob_2, test_blob_2_b64_0, "");
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
  err = test_b64enc_string (test_blob_3, test_blob_3_b64_0, "");
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
Packit fc043f
  err = test_b64enc_string ("@", "QA==", "");
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
  err = test_b64enc_string ("@", "QA==\n", NULL);
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
  err = test_b64enc_string ("@",
Packit fc043f
                            "-----BEGIN PGP SOMETHING-----\n"
Packit fc043f
                            "\n"
Packit fc043f
                            "QA==\n"
Packit fc043f
                            "=eMoB\n"
Packit fc043f
                            "-----END PGP SOMETHING-----\n",
Packit fc043f
                            "PGP SOMETHING");
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
Packit fc043f
  err = test_b64enc_string ("", "", "");
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
  err = test_b64enc_string ("", "", NULL);
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
  err = test_b64enc_string ("", "", "PGP SOMETHING");
Packit fc043f
  if (err)
Packit fc043f
    fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
static void
Packit fc043f
decoder_tests (void)
Packit fc043f
{
Packit fc043f
  gpg_err_code_t err;
Packit fc043f
Packit fc043f
  if (verbose)
Packit fc043f
    show ("running decoder tests\n");
Packit fc043f
Packit fc043f
  err = test_b64dec_string (test_string_b64_0, test_string, NULL);
Packit fc043f
  if (err)
Packit fc043f
    fail ("decoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
Packit fc043f
  err = test_b64dec_string (test_string_b64_1, test_string, NULL);
Packit fc043f
  if (err)
Packit fc043f
    fail ("decoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
Packit fc043f
  err = test_b64dec_string (test_string_b64_2, test_string, "");
Packit fc043f
  if (err)
Packit fc043f
    fail ("decoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
Packit fc043f
  err = test_b64dec_string (test_string_b64_2, test_string, NULL);
Packit fc043f
  if (err != GPG_ERR_BAD_DATA)
Packit fc043f
    fail ("decoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err));
Packit fc043f
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
static gpg_error_t
Packit fc043f
extra_tests (void)
Packit fc043f
{
Packit fc043f
  gpg_err_code_t err;
Packit fc043f
  gpgrt_b64state_t state;
Packit fc043f
Packit fc043f
  if (verbose)
Packit fc043f
    show ("running extra tests\n");
Packit fc043f
Packit fc043f
  /* Check that we detect mismacthed use of enc and dec functions.  */
Packit fc043f
  state = gpgrt_b64enc_start (es_stdout, NULL);
Packit fc043f
  if (!state)
Packit fc043f
    {
Packit fc043f
      err = gpg_err_code_from_syserror ();
Packit fc043f
      fail ("gpgrt_b64enc_start failed: %s\n", gpg_strerror (err));
Packit fc043f
      return err;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  err = gpgrt_b64dec_finish (state);
Packit fc043f
  if (err != GPG_ERR_CONFLICT)
Packit fc043f
    {
Packit fc043f
      fail ("gpgrt_b64dec_finish failed: %s\n", gpg_strerror (err));
Packit fc043f
      return err;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  state = gpgrt_b64dec_start (NULL);
Packit fc043f
  if (!state)
Packit fc043f
    {
Packit fc043f
      err = gpg_err_code_from_syserror ();
Packit fc043f
      fail ("gpgrt_b64dec_start failed: %s\n", gpg_strerror (err));
Packit fc043f
      return err;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  err = gpgrt_b64enc_finish (state);
Packit fc043f
  if (err != GPG_ERR_CONFLICT)
Packit fc043f
    {
Packit fc043f
      fail ("gpgrt_b64enc_finish failed: %s\n", gpg_strerror (err));
Packit fc043f
      return err;
Packit fc043f
    }
Packit fc043f
Packit fc043f
  return 0;
Packit fc043f
}
Packit fc043f
Packit fc043f
Packit fc043f
int
Packit fc043f
main (int argc, char **argv)
Packit fc043f
{
Packit fc043f
  int last_argc = -1;
Packit fc043f
Packit fc043f
  if (argc)
Packit fc043f
    {
Packit fc043f
      argc--; argv++;
Packit fc043f
    }
Packit fc043f
  while (argc && last_argc != argc )
Packit fc043f
    {
Packit fc043f
      last_argc = argc;
Packit fc043f
      if (!strcmp (*argv, "--help"))
Packit fc043f
        {
Packit fc043f
          puts (
Packit fc043f
"usage: ./" PGM " [options]\n"
Packit fc043f
"\n"
Packit fc043f
"Options:\n"
Packit fc043f
"  --verbose      Show what is going on\n"
Packit fc043f
"  --debug        Flyswatter\n"
Packit fc043f
);
Packit fc043f
          exit (0);
Packit fc043f
        }
Packit fc043f
      if (!strcmp (*argv, "--verbose"))
Packit fc043f
        {
Packit fc043f
          verbose = 1;
Packit fc043f
          argc--; argv++;
Packit fc043f
        }
Packit fc043f
      else if (!strcmp (*argv, "--debug"))
Packit fc043f
        {
Packit fc043f
          verbose = debug = 1;
Packit fc043f
          argc--; argv++;
Packit fc043f
        }
Packit fc043f
    }
Packit fc043f
Packit fc043f
  encoder_tests ();
Packit fc043f
  decoder_tests ();
Packit fc043f
  extra_tests ();
Packit fc043f
Packit fc043f
  return !!errorcount;
Packit fc043f
}