Changeset 14359


Ignore:
Timestamp:
Dec 4, 2014, 7:58:34 PM (8 years ago)
Author:
mikedld
Message:

#4400, #5462: Move BASE64 helpers to crypto-utils

On a way to factoring out OpenSSL support to a standalone file to ease
addition of other crypto libraries support in the future, move helpers
providing BASE64 encoding and decoding to crypto-utils.{c,h}. OpenSSL-
related functionality is moved to crypto-utils-openssl.c.

Add new functions to be implemented by crypto backends:

  • tr_base64_encode_impl - encode from binary to BASE64,
  • tr_base64_decode_impl - decode from BASE64 to binary.

Change tr_base64_encode and tr_base64_decode functions to expect
non-negative input data length which is considered real and never adjusted.
To process null-terminated strings (which was achieved before by passing 0
or -1 as input data length), add new tr_base64_encode_str and
tr_base64_decode_str functions which do not accept input data length as
an argument but calculate it on their own.

Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/daemon/remote.c

    r14337 r14359  
    2121
    2222#include <libtransmission/transmission.h>
     23#include <libtransmission/crypto-utils.h>
    2324#include <libtransmission/error.h>
    2425#include <libtransmission/file.h>
     
    11921193
    11931194static void
    1194 printPiecesImpl (const uint8_t * raw, size_t rawlen, int64_t j)
    1195 {
    1196     int i, k, len;
     1195printPiecesImpl (const uint8_t * raw, size_t rawlen, size_t j)
     1196{
     1197    size_t i, k, len;
    11971198    char * str = tr_base64_decode (raw, rawlen, &len);
    11981199    printf ("  ");
     
    12261227            if (tr_variantDictFindRaw (torrent, TR_KEY_pieces, &raw, &rawlen) &&
    12271228                tr_variantDictFindInt (torrent, TR_KEY_pieceCount, &j)) {
    1228                 printPiecesImpl (raw, rawlen, j);
     1229                assert (j >= 0);
     1230                printPiecesImpl (raw, rawlen, (size_t) j);
    12291231                if (i+1<n)
    12301232                    printf ("\n");
  • trunk/libtransmission/crypto-test.c

    r14358 r14359  
    184184}
    185185
     186static int
     187test_base64 (void)
     188{
     189  size_t len;
     190  char * in, * out;
     191  int i;
     192
     193  out = tr_base64_encode_str ("YOYO!", &len);
     194  check_int_eq (8, len);
     195  check_streq ("WU9ZTyE=", out);
     196  in = tr_base64_decode_str (out, &len);
     197  check_int_eq (5, len);
     198  check_streq ("YOYO!", in);
     199  tr_free (in);
     200  tr_free (out);
     201
     202  out = tr_base64_encode ("", 0, &len);
     203  check_int_eq (0, len);
     204  check_streq ("", out);
     205  out = tr_base64_decode ("", 0, &len);
     206  check_int_eq (0, len);
     207  check_streq ("", out);
     208
     209  out = tr_base64_encode (NULL, 0, &len);
     210  check_int_eq (0, len);
     211  check (out == NULL);
     212  out = tr_base64_decode (NULL, 0, &len);
     213  check_int_eq (0, len);
     214  check (out == NULL);
     215
     216#define MAX_BUF_SIZE 1024
     217
     218  for (i = 1; i <= MAX_BUF_SIZE; ++i)
     219    {
     220      int j;
     221      char buf[MAX_BUF_SIZE + 1];
     222
     223      for (j = 0; j < i; ++j)
     224        buf[j] = tr_rand_int_weak (256);
     225
     226      out = tr_base64_encode (buf, j, &len);
     227      check_int_eq ((j + 2) / 3 * 4, len);
     228      in = tr_base64_decode (out, len, &len);
     229      check_int_eq (j, len);
     230      check (memcmp (in, buf, len) == 0);
     231      tr_free (in);
     232      tr_free (out);
     233
     234      for (j = 0; j < i; ++j)
     235        buf[j] = 1 + tr_rand_int_weak (255);
     236      buf[j] = '\0';
     237
     238      out = tr_base64_encode_str (buf, &len);
     239      check_int_eq ((j + 2) / 3 * 4, len);
     240      in = tr_base64_decode_str (out, &len);
     241      check_int_eq (j, len);
     242      check_streq (in, buf);
     243      tr_free (in);
     244      tr_free (out);
     245    }
     246
     247#undef MAX_BUF_SIZE
     248
     249  return 0;
     250}
     251
    186252int
    187253main (void)
     
    191257                             test_sha1,
    192258                             test_ssha1,
    193                              test_random };
     259                             test_random,
     260                             test_base64 };
    194261
    195262  return runTests (tests, NUM_TESTS (tests));
  • trunk/libtransmission/crypto-utils-openssl.c

    r14358 r14359  
    1010#include <assert.h>
    1111
     12#include <openssl/bio.h>
    1213#include <openssl/bn.h>
     14#include <openssl/buffer.h>
    1315#include <openssl/dh.h>
    1416#include <openssl/err.h>
     
    302304  return check_result (RAND_bytes (buffer, (int) length));
    303305}
     306
     307/***
     308****
     309***/
     310
     311void *
     312tr_base64_encode_impl (const void * input,
     313                       size_t       input_length,
     314                       size_t     * output_length)
     315{
     316  char * ret = NULL;
     317  int ret_length = 0;
     318  BIO * bmem;
     319  BIO * b64;
     320
     321  assert (input != NULL);
     322  assert (input_length > 0);
     323
     324  bmem = BIO_new (BIO_s_mem ());
     325  b64 = BIO_new (BIO_f_base64 ());
     326
     327  BIO_set_flags (b64, BIO_FLAGS_BASE64_NO_NL);
     328  b64 = BIO_push (b64, bmem);
     329
     330  if (check_result_eq (BIO_write (b64, input, input_length), (int) input_length) &&
     331      check_result (BIO_flush (b64)))
     332    {
     333      BUF_MEM * bptr;
     334
     335      BIO_get_mem_ptr (b64, &bptr);
     336      ret = tr_strndup (bptr->data, bptr->length);
     337      ret_length = bptr->length;
     338    }
     339
     340  BIO_free_all (b64);
     341
     342  if (output_length != NULL)
     343    *output_length = (size_t) ret_length;
     344
     345  return ret;
     346}
     347
     348void *
     349tr_base64_decode_impl (const void * input,
     350                       size_t       input_length,
     351                       size_t     * output_length)
     352{
     353  char * ret;
     354  int ret_length;
     355  int i;
     356
     357  assert (input != NULL);
     358  assert (input_length > 0);
     359
     360  ret = tr_new (char, input_length + 1);
     361
     362  /* try two times, without and with BIO_FLAGS_BASE64_NO_NL flag */
     363  for (i = 0; i < 2; ++i)
     364    {
     365      BIO * bmem = BIO_new_mem_buf ((void *) input, (int) input_length);
     366      BIO * b64 = BIO_new (BIO_f_base64 ());
     367
     368      BIO_set_flags (b64, i == 1 ? BIO_FLAGS_BASE64_NO_NL : 0);
     369      bmem = BIO_push (b64, bmem);
     370
     371      ret_length = BIO_read (bmem, ret, (int) input_length);
     372      if (ret_length < 0 && i == 1)
     373        log_error ();
     374
     375      BIO_free_all (bmem);
     376
     377      /* < 0 - fatal error, > 0 - success*/
     378      if (ret_length != 0)
     379        break;
     380    }
     381
     382  if (ret_length < 0)
     383    {
     384      tr_free (ret);
     385      return NULL;
     386    }
     387
     388  ret[ret_length] = '\0';
     389
     390  if (output_length != NULL)
     391    *output_length = (size_t) ret_length;
     392
     393  return ret;
     394}
  • trunk/libtransmission/crypto-utils.c

    r14358 r14359  
    1111#include <stdarg.h>
    1212#include <stdlib.h> /* abs (), srand (), rand () */
    13 #include <string.h> /* memmove (), memset () */
     13#include <string.h> /* memmove (), memset (), strlen () */
    1414
    1515#include "transmission.h"
     
    116116  return rand () % upper_bound;
    117117}
     118
     119/***
     120****
     121***/
     122
     123void *
     124tr_base64_encode (const void * input,
     125                  size_t       input_length,
     126                  size_t     * output_length)
     127{
     128  char * ret;
     129
     130  if (input != NULL)
     131    {
     132      if (input_length != 0)
     133        {
     134          if ((ret = tr_base64_encode_impl (input, input_length, output_length)) != NULL)
     135            return ret;
     136        }
     137      else
     138        ret = tr_strdup ("");
     139    }
     140  else
     141    {
     142      ret = NULL;
     143    }
     144
     145  if (output_length != NULL)
     146    *output_length = 0;
     147
     148  return ret;
     149}
     150
     151void *
     152tr_base64_encode_str (const char * input,
     153                      size_t     * output_length)
     154{
     155  return tr_base64_encode (input, input == NULL ? 0 : strlen (input), output_length);
     156}
     157
     158void *
     159tr_base64_decode (const void * input,
     160                  size_t       input_length,
     161                  size_t     * output_length)
     162{
     163  char * ret;
     164
     165  if (input != NULL)
     166    {
     167      if (input_length != 0)
     168        {
     169          if ((ret = tr_base64_decode_impl (input, input_length, output_length)) != NULL)
     170            return ret;
     171        }
     172      else
     173        ret = tr_strdup ("");
     174    }
     175  else
     176    {
     177      ret = NULL;
     178    }
     179
     180  if (output_length != NULL)
     181    *output_length = 0;
     182
     183  return ret;
     184}
     185
     186void *
     187tr_base64_decode_str (const char * input,
     188                      size_t     * output_length)
     189{
     190  return tr_base64_decode (input, input == NULL ? 0 : strlen (input), output_length);
     191}
  • trunk/libtransmission/crypto-utils.h

    r14358 r14359  
    1414#include <stddef.h>
    1515
    16 #include "utils.h" /* TR_GNUC_NULL_TERMINATED */
     16#include "utils.h" /* TR_GNUC_MALLOC, TR_GNUC_NULL_TERMINATED */
     17
     18#ifdef __cplusplus
     19extern "C" {
     20#endif
    1721
    1822/**
     
    151155                                        size_t           length);
    152156
     157/**
     158 * @brief Translate a block of bytes into base64.
     159 * @return a newly-allocated null-terminated string that can be freed with tr_free ()
     160 */
     161void           * tr_base64_encode      (const void     * input,
     162                                        size_t           input_length,
     163                                        size_t         * output_length) TR_GNUC_MALLOC;
     164
     165/**
     166 * @brief Translate null-terminated string into base64.
     167 * @return a newly-allocated null-terminated string that can be freed with tr_free ()
     168 */
     169void           * tr_base64_encode_str  (const char     * input,
     170                                        size_t         * output_length) TR_GNUC_MALLOC;
     171
     172/**
     173 * @brief Translate a block of bytes into base64 (internal, do not use).
     174 * @return a newly-allocated null-terminated string that can be freed with tr_free ()
     175 */
     176void           * tr_base64_encode_impl (const void     * input,
     177                                        size_t           input_length,
     178                                        size_t         * output_length) TR_GNUC_MALLOC;
     179
     180/**
     181 * @brief Translate a block of bytes from base64 into raw form.
     182 * @return a newly-allocated null-terminated string that can be freed with tr_free ()
     183 */
     184void           * tr_base64_decode      (const void     * input,
     185                                        size_t           input_length,
     186                                        size_t         * output_length) TR_GNUC_MALLOC;
     187
     188/**
     189 * @brief Translate null-terminated string from base64 into raw form.
     190 * @return a newly-allocated null-terminated string that can be freed with tr_free ()
     191 */
     192void           * tr_base64_decode_str  (const char     * input,
     193                                        size_t         * output_length) TR_GNUC_MALLOC;
     194
     195/**
     196 * @brief Translate null-terminated string from base64 into raw form (internal, do not use).
     197 * @return a newly-allocated null-terminated string that can be freed with tr_free ()
     198 */
     199void           * tr_base64_decode_impl (const void     * input,
     200                                        size_t           input_length,
     201                                        size_t         * output_length) TR_GNUC_MALLOC;
     202
    153203/** @} */
    154204
     205#ifdef __cplusplus
     206}
     207#endif
     208
    155209#endif /* TR_CRYPTO_UTILS_H */
  • trunk/libtransmission/libtransmission-test.c

    r14331 r14359  
    1515
    1616#include "transmission.h"
     17#include "crypto-utils.h"
    1718#include "error.h"
    1819#include "file.h"
     
    311312{
    312313  int err;
    313   int metainfo_len;
     314  size_t metainfo_len;
    314315  char * metainfo;
    315316  const char * metainfo_base64;
     
    343344
    344345  /* create the torrent ctor */
    345   metainfo = tr_base64_decode (metainfo_base64, -1, &metainfo_len);
     346  metainfo = tr_base64_decode_str (metainfo_base64, &metainfo_len);
    346347  assert (metainfo != NULL);
    347348  assert (metainfo_len > 0);
  • trunk/libtransmission/rename-test.c

    r14320 r14359  
    1616
    1717#include "transmission.h"
     18#include "crypto-utils.h"
    1819#include "file.h"
    1920#include "resume.h"
     
    102103{
    103104  int err;
    104   int metainfo_len;
     105  size_t metainfo_len;
    105106  char * metainfo;
    106107  tr_torrent * tor;
    107108
    108109  /* create the torrent ctor */
    109   metainfo = tr_base64_decode (metainfo_base64, -1, &metainfo_len);
     110  metainfo = tr_base64_decode_str (metainfo_base64, &metainfo_len);
    110111  assert (metainfo != NULL);
    111112  assert (metainfo_len > 0);
  • trunk/libtransmission/rpc-server.c

    r14354 r14359  
    612612      if (auth && !evutil_ascii_strncasecmp (auth, "basic ", 6))
    613613        {
    614           int plen;
    615           char * p = tr_base64_decode (auth + 6, 0, &plen);
     614          size_t plen;
     615          char * p = tr_base64_decode_str (auth + 6, &plen);
    616616          if (p && plen && ((pass = strchr (p, ':'))))
    617617            {
  • trunk/libtransmission/rpcimpl.c

    r14327 r14359  
    2020#include "transmission.h"
    2121#include "completion.h"
     22#include "crypto-utils.h"
    2223#include "error.h"
    2324#include "fdlimit.h"
     
    17971798          if (fname == NULL)
    17981799            {
    1799               int len;
    1800               char * metainfo = tr_base64_decode (metainfo_base64, -1, &len);
     1800              size_t len;
     1801              char * metainfo = tr_base64_decode_str (metainfo_base64, &len);
    18011802              tr_ctorSetMetainfo (ctor, (uint8_t*)metainfo, len);
    18021803              tr_free (metainfo);
  • trunk/libtransmission/utils-test.c

    r14354 r14359  
    3636
    3737#include "libtransmission-test.h"
    38 
    39 static int
    40 test_base64 (void)
    41 {
    42   int len;
    43   char *in, *out;
    44 
    45   /* base64 */
    46   out = tr_base64_encode ("YOYO!", -1, &len);
    47   check_streq ("WU9ZTyE=", out);
    48   check_int_eq (8, len);
    49   in = tr_base64_decode (out, -1, &len);
    50   check_streq ("YOYO!", in);
    51   check_int_eq (5, len);
    52   tr_free (in);
    53   tr_free (out);
    54   out = tr_base64_encode (NULL, 0, &len);
    55   check (out == NULL);
    56   check_int_eq (0, len);
    57 
    58   return 0;
    59 }
    6038
    6139static int
     
    519497{
    520498  const testFunc tests[] = { test_array,
    521                              test_base64,
    522499                             test_buildpath,
    523500                             test_hex,
  • trunk/libtransmission/utils.c

    r14348 r14359  
    811811  tr_free (tmp);
    812812  return err;
    813 }
    814 
    815 #include <string.h>
    816 #include <openssl/sha.h>
    817 #include <openssl/hmac.h>
    818 #include <openssl/evp.h>
    819 #include <openssl/bio.h>
    820 #include <openssl/buffer.h>
    821 
    822 char *
    823 tr_base64_encode (const void * input, int length, int * setme_len)
    824 {
    825   int retlen = 0;
    826   char * ret = NULL;
    827 
    828   if (input != NULL)
    829     {
    830       BIO * b64;
    831       BIO * bmem;
    832       BUF_MEM * bptr;
    833 
    834       if (length < 1)
    835         length = (int)strlen (input);
    836 
    837       bmem = BIO_new (BIO_s_mem ());
    838       b64 = BIO_new (BIO_f_base64 ());
    839       BIO_set_flags (b64, BIO_FLAGS_BASE64_NO_NL);
    840       b64 = BIO_push (b64, bmem);
    841       BIO_write (b64, input, length);
    842       (void) BIO_flush (b64);
    843       BIO_get_mem_ptr (b64, &bptr);
    844       ret = tr_strndup (bptr->data, bptr->length);
    845       retlen = bptr->length;
    846       BIO_free_all (b64);
    847     }
    848 
    849   if (setme_len)
    850     *setme_len = retlen;
    851 
    852   return ret;
    853 }
    854 
    855 char *
    856 tr_base64_decode (const void * input,
    857                   int          length,
    858                   int *        setme_len)
    859 {
    860   char * ret;
    861   BIO * b64;
    862   BIO * bmem;
    863   int retlen;
    864 
    865   if (length < 1)
    866     length = strlen (input);
    867 
    868   ret = tr_new0 (char, length);
    869   b64 = BIO_new (BIO_f_base64 ());
    870   bmem = BIO_new_mem_buf ((unsigned char*)input, length);
    871   bmem = BIO_push (b64, bmem);
    872   retlen = BIO_read (bmem, ret, length);
    873   if (!retlen)
    874     {
    875       /* try again, but with the BIO_FLAGS_BASE64_NO_NL flag */
    876       BIO_free_all (bmem);
    877       b64 = BIO_new (BIO_f_base64 ());
    878       BIO_set_flags (b64, BIO_FLAGS_BASE64_NO_NL);
    879       bmem = BIO_new_mem_buf ((unsigned char*)input, length);
    880       bmem = BIO_push (b64, bmem);
    881       retlen = BIO_read (bmem, ret, length);
    882     }
    883 
    884   if (setme_len)
    885     *setme_len = retlen;
    886 
    887   BIO_free_all (bmem);
    888   return ret;
    889813}
    890814
  • trunk/libtransmission/utils.h

    r14348 r14359  
    288288                          va_list      args) TR_GNUC_MALLOC;
    289289
    290 /**
    291  * @brief Translate a block of bytes into base64
    292  * @return a newly-allocated string that can be freed with tr_free ()
    293  */
    294 char* tr_base64_encode (const void * input,
    295                         int          inlen,
    296                         int        * outlen) TR_GNUC_MALLOC;
    297 
    298 /**
    299  * @brief Translate a block of bytes from base64 into raw form
    300  * @return a newly-allocated string that can be freed with tr_free ()
    301  */
    302 char* tr_base64_decode (const void * input,
    303                         int          inlen,
    304                         int        * outlen) TR_GNUC_MALLOC;
    305 
    306290/** @brief Portability wrapper for strlcpy () that uses the system implementation if available */
    307291size_t tr_strlcpy (char * dst, const void * src, size_t siz);
  • trunk/qt/add-data.cc

    r14225 r14359  
    1212
    1313#include <libtransmission/transmission.h>
    14 #include <libtransmission/utils.h> // tr_base64_encode()
     14#include <libtransmission/crypto-utils.h> // tr_base64_encode()
    1515
    1616#include "add-data.h"
     
    4747  else
    4848    {
    49       int len;
    50       char * raw = tr_base64_decode (key.toUtf8().constData(), key.toUtf8().size(), &len);
     49      size_t len;
     50      void * raw = tr_base64_decode (key.toUtf8().constData(), key.toUtf8().size(), &len);
    5151      if (raw)
    5252        {
    53           metainfo.append (raw, len);
     53          metainfo.append (static_cast<const char*> (raw), (int) len);
    5454          tr_free (raw);
    5555          type = METAINFO;
     
    7171  if (!metainfo.isEmpty ())
    7272    {
    73       int len = 0;
    74       char * b64 = tr_base64_encode (metainfo.constData(), metainfo.size(), &len);
    75       ret = QByteArray (b64, len);
     73      size_t len;
     74      void * b64 = tr_base64_encode (metainfo.constData(), metainfo.size(), &len);
     75      ret = QByteArray (static_cast<const char*> (b64), (int) len);
    7676      tr_free (b64);
    7777    }
Note: See TracChangeset for help on using the changeset viewer.