#include <curl/curl.h>
#include <libtransmission/transmission.h>
+#include <libtransmission/crypto-utils.h>
#include <libtransmission/error.h>
#include <libtransmission/file.h>
#include <libtransmission/log.h>
}
static void
-printPiecesImpl (const uint8_t * raw, size_t rawlen, int64_t j)
+printPiecesImpl (const uint8_t * raw, size_t rawlen, size_t j)
{
- int i, k, len;
+ size_t i, k, len;
char * str = tr_base64_decode (raw, rawlen, &len);
printf (" ");
for (i=k=0; k<len; ++k) {
tr_variant * torrent = tr_variantListChild (torrents, i);
if (tr_variantDictFindRaw (torrent, TR_KEY_pieces, &raw, &rawlen) &&
tr_variantDictFindInt (torrent, TR_KEY_pieceCount, &j)) {
- printPiecesImpl (raw, rawlen, j);
+ assert (j >= 0);
+ printPiecesImpl (raw, rawlen, (size_t) j);
if (i+1<n)
printf ("\n");
}
return 0;
}
+static int
+test_base64 (void)
+{
+ size_t len;
+ char * in, * out;
+ int i;
+
+ out = tr_base64_encode_str ("YOYO!", &len);
+ check_int_eq (8, len);
+ check_streq ("WU9ZTyE=", out);
+ in = tr_base64_decode_str (out, &len);
+ check_int_eq (5, len);
+ check_streq ("YOYO!", in);
+ tr_free (in);
+ tr_free (out);
+
+ out = tr_base64_encode ("", 0, &len);
+ check_int_eq (0, len);
+ check_streq ("", out);
+ out = tr_base64_decode ("", 0, &len);
+ check_int_eq (0, len);
+ check_streq ("", out);
+
+ out = tr_base64_encode (NULL, 0, &len);
+ check_int_eq (0, len);
+ check (out == NULL);
+ out = tr_base64_decode (NULL, 0, &len);
+ check_int_eq (0, len);
+ check (out == NULL);
+
+#define MAX_BUF_SIZE 1024
+
+ for (i = 1; i <= MAX_BUF_SIZE; ++i)
+ {
+ int j;
+ char buf[MAX_BUF_SIZE + 1];
+
+ for (j = 0; j < i; ++j)
+ buf[j] = tr_rand_int_weak (256);
+
+ out = tr_base64_encode (buf, j, &len);
+ check_int_eq ((j + 2) / 3 * 4, len);
+ in = tr_base64_decode (out, len, &len);
+ check_int_eq (j, len);
+ check (memcmp (in, buf, len) == 0);
+ tr_free (in);
+ tr_free (out);
+
+ for (j = 0; j < i; ++j)
+ buf[j] = 1 + tr_rand_int_weak (255);
+ buf[j] = '\0';
+
+ out = tr_base64_encode_str (buf, &len);
+ check_int_eq ((j + 2) / 3 * 4, len);
+ in = tr_base64_decode_str (out, &len);
+ check_int_eq (j, len);
+ check_streq (in, buf);
+ tr_free (in);
+ tr_free (out);
+ }
+
+#undef MAX_BUF_SIZE
+
+ return 0;
+}
+
int
main (void)
{
test_encrypt_decrypt,
test_sha1,
test_ssha1,
- test_random };
+ test_random,
+ test_base64 };
return runTests (tests, NUM_TESTS (tests));
}
#include <assert.h>
+#include <openssl/bio.h>
#include <openssl/bn.h>
+#include <openssl/buffer.h>
#include <openssl/dh.h>
#include <openssl/err.h>
#include <openssl/evp.h>
return check_result (RAND_bytes (buffer, (int) length));
}
+
+/***
+****
+***/
+
+void *
+tr_base64_encode_impl (const void * input,
+ size_t input_length,
+ size_t * output_length)
+{
+ char * ret = NULL;
+ int ret_length = 0;
+ BIO * bmem;
+ BIO * b64;
+
+ assert (input != NULL);
+ assert (input_length > 0);
+
+ bmem = BIO_new (BIO_s_mem ());
+ b64 = BIO_new (BIO_f_base64 ());
+
+ BIO_set_flags (b64, BIO_FLAGS_BASE64_NO_NL);
+ b64 = BIO_push (b64, bmem);
+
+ if (check_result_eq (BIO_write (b64, input, input_length), (int) input_length) &&
+ check_result (BIO_flush (b64)))
+ {
+ BUF_MEM * bptr;
+
+ BIO_get_mem_ptr (b64, &bptr);
+ ret = tr_strndup (bptr->data, bptr->length);
+ ret_length = bptr->length;
+ }
+
+ BIO_free_all (b64);
+
+ if (output_length != NULL)
+ *output_length = (size_t) ret_length;
+
+ return ret;
+}
+
+void *
+tr_base64_decode_impl (const void * input,
+ size_t input_length,
+ size_t * output_length)
+{
+ char * ret;
+ int ret_length;
+ int i;
+
+ assert (input != NULL);
+ assert (input_length > 0);
+
+ ret = tr_new (char, input_length + 1);
+
+ /* try two times, without and with BIO_FLAGS_BASE64_NO_NL flag */
+ for (i = 0; i < 2; ++i)
+ {
+ BIO * bmem = BIO_new_mem_buf ((void *) input, (int) input_length);
+ BIO * b64 = BIO_new (BIO_f_base64 ());
+
+ BIO_set_flags (b64, i == 1 ? BIO_FLAGS_BASE64_NO_NL : 0);
+ bmem = BIO_push (b64, bmem);
+
+ ret_length = BIO_read (bmem, ret, (int) input_length);
+ if (ret_length < 0 && i == 1)
+ log_error ();
+
+ BIO_free_all (bmem);
+
+ /* < 0 - fatal error, > 0 - success*/
+ if (ret_length != 0)
+ break;
+ }
+
+ if (ret_length < 0)
+ {
+ tr_free (ret);
+ return NULL;
+ }
+
+ ret[ret_length] = '\0';
+
+ if (output_length != NULL)
+ *output_length = (size_t) ret_length;
+
+ return ret;
+}
#include <assert.h>
#include <stdarg.h>
#include <stdlib.h> /* abs (), srand (), rand () */
-#include <string.h> /* memmove (), memset () */
+#include <string.h> /* memmove (), memset (), strlen () */
#include "transmission.h"
#include "crypto-utils.h"
return rand () % upper_bound;
}
+
+/***
+****
+***/
+
+void *
+tr_base64_encode (const void * input,
+ size_t input_length,
+ size_t * output_length)
+{
+ char * ret;
+
+ if (input != NULL)
+ {
+ if (input_length != 0)
+ {
+ if ((ret = tr_base64_encode_impl (input, input_length, output_length)) != NULL)
+ return ret;
+ }
+ else
+ ret = tr_strdup ("");
+ }
+ else
+ {
+ ret = NULL;
+ }
+
+ if (output_length != NULL)
+ *output_length = 0;
+
+ return ret;
+}
+
+void *
+tr_base64_encode_str (const char * input,
+ size_t * output_length)
+{
+ return tr_base64_encode (input, input == NULL ? 0 : strlen (input), output_length);
+}
+
+void *
+tr_base64_decode (const void * input,
+ size_t input_length,
+ size_t * output_length)
+{
+ char * ret;
+
+ if (input != NULL)
+ {
+ if (input_length != 0)
+ {
+ if ((ret = tr_base64_decode_impl (input, input_length, output_length)) != NULL)
+ return ret;
+ }
+ else
+ ret = tr_strdup ("");
+ }
+ else
+ {
+ ret = NULL;
+ }
+
+ if (output_length != NULL)
+ *output_length = 0;
+
+ return ret;
+}
+
+void *
+tr_base64_decode_str (const char * input,
+ size_t * output_length)
+{
+ return tr_base64_decode (input, input == NULL ? 0 : strlen (input), output_length);
+}
#include <inttypes.h>
#include <stddef.h>
-#include "utils.h" /* TR_GNUC_NULL_TERMINATED */
+#include "utils.h" /* TR_GNUC_MALLOC, TR_GNUC_NULL_TERMINATED */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
/**
*** @addtogroup utils Utilities
bool tr_rand_buffer (void * buffer,
size_t length);
+/**
+ * @brief Translate a block of bytes into base64.
+ * @return a newly-allocated null-terminated string that can be freed with tr_free ()
+ */
+void * tr_base64_encode (const void * input,
+ size_t input_length,
+ size_t * output_length) TR_GNUC_MALLOC;
+
+/**
+ * @brief Translate null-terminated string into base64.
+ * @return a newly-allocated null-terminated string that can be freed with tr_free ()
+ */
+void * tr_base64_encode_str (const char * input,
+ size_t * output_length) TR_GNUC_MALLOC;
+
+/**
+ * @brief Translate a block of bytes into base64 (internal, do not use).
+ * @return a newly-allocated null-terminated string that can be freed with tr_free ()
+ */
+void * tr_base64_encode_impl (const void * input,
+ size_t input_length,
+ size_t * output_length) TR_GNUC_MALLOC;
+
+/**
+ * @brief Translate a block of bytes from base64 into raw form.
+ * @return a newly-allocated null-terminated string that can be freed with tr_free ()
+ */
+void * tr_base64_decode (const void * input,
+ size_t input_length,
+ size_t * output_length) TR_GNUC_MALLOC;
+
+/**
+ * @brief Translate null-terminated string from base64 into raw form.
+ * @return a newly-allocated null-terminated string that can be freed with tr_free ()
+ */
+void * tr_base64_decode_str (const char * input,
+ size_t * output_length) TR_GNUC_MALLOC;
+
+/**
+ * @brief Translate null-terminated string from base64 into raw form (internal, do not use).
+ * @return a newly-allocated null-terminated string that can be freed with tr_free ()
+ */
+void * tr_base64_decode_impl (const void * input,
+ size_t input_length,
+ size_t * output_length) TR_GNUC_MALLOC;
+
/** @} */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* TR_CRYPTO_UTILS_H */
#include <unistd.h>
#include "transmission.h"
+#include "crypto-utils.h"
#include "error.h"
#include "file.h"
#include "platform.h" /* TR_PATH_DELIMETER */
libttest_zero_torrent_init (tr_session * session)
{
int err;
- int metainfo_len;
+ size_t metainfo_len;
char * metainfo;
const char * metainfo_base64;
tr_torrent * tor;
"OnByaXZhdGVpMGVlZQ==";
/* create the torrent ctor */
- metainfo = tr_base64_decode (metainfo_base64, -1, &metainfo_len);
+ metainfo = tr_base64_decode_str (metainfo_base64, &metainfo_len);
assert (metainfo != NULL);
assert (metainfo_len > 0);
assert (session != NULL);
#include <unistd.h> /* sync() */
#include "transmission.h"
+#include "crypto-utils.h"
#include "file.h"
#include "resume.h"
#include "torrent.h" /* tr_isTorrent() */
create_torrent_from_base64_metainfo (tr_ctor * ctor, const char * metainfo_base64)
{
int err;
- int metainfo_len;
+ size_t metainfo_len;
char * metainfo;
tr_torrent * tor;
/* create the torrent ctor */
- metainfo = tr_base64_decode (metainfo_base64, -1, &metainfo_len);
+ metainfo = tr_base64_decode_str (metainfo_base64, &metainfo_len);
assert (metainfo != NULL);
assert (metainfo_len > 0);
tr_ctorSetMetainfo (ctor, (uint8_t*)metainfo, metainfo_len);
auth = evhttp_find_header (req->input_headers, "Authorization");
if (auth && !evutil_ascii_strncasecmp (auth, "basic ", 6))
{
- int plen;
- char * p = tr_base64_decode (auth + 6, 0, &plen);
+ size_t plen;
+ char * p = tr_base64_decode_str (auth + 6, &plen);
if (p && plen && ((pass = strchr (p, ':'))))
{
user = p;
#include "transmission.h"
#include "completion.h"
+#include "crypto-utils.h"
#include "error.h"
#include "fdlimit.h"
#include "file.h"
if (fname == NULL)
{
- int len;
- char * metainfo = tr_base64_decode (metainfo_base64, -1, &len);
+ size_t len;
+ char * metainfo = tr_base64_decode_str (metainfo_base64, &len);
tr_ctorSetMetainfo (ctor, (uint8_t*)metainfo, len);
tr_free (metainfo);
}
#include "libtransmission-test.h"
-static int
-test_base64 (void)
-{
- int len;
- char *in, *out;
-
- /* base64 */
- out = tr_base64_encode ("YOYO!", -1, &len);
- check_streq ("WU9ZTyE=", out);
- check_int_eq (8, len);
- in = tr_base64_decode (out, -1, &len);
- check_streq ("YOYO!", in);
- check_int_eq (5, len);
- tr_free (in);
- tr_free (out);
- out = tr_base64_encode (NULL, 0, &len);
- check (out == NULL);
- check_int_eq (0, len);
-
- return 0;
-}
-
static int
test_strip_positional_args (void)
{
main (void)
{
const testFunc tests[] = { test_array,
- test_base64,
test_buildpath,
test_hex,
test_lowerbound,
return err;
}
-#include <string.h>
-#include <openssl/sha.h>
-#include <openssl/hmac.h>
-#include <openssl/evp.h>
-#include <openssl/bio.h>
-#include <openssl/buffer.h>
-
-char *
-tr_base64_encode (const void * input, int length, int * setme_len)
-{
- int retlen = 0;
- char * ret = NULL;
-
- if (input != NULL)
- {
- BIO * b64;
- BIO * bmem;
- BUF_MEM * bptr;
-
- if (length < 1)
- length = (int)strlen (input);
-
- bmem = BIO_new (BIO_s_mem ());
- b64 = BIO_new (BIO_f_base64 ());
- BIO_set_flags (b64, BIO_FLAGS_BASE64_NO_NL);
- b64 = BIO_push (b64, bmem);
- BIO_write (b64, input, length);
- (void) BIO_flush (b64);
- BIO_get_mem_ptr (b64, &bptr);
- ret = tr_strndup (bptr->data, bptr->length);
- retlen = bptr->length;
- BIO_free_all (b64);
- }
-
- if (setme_len)
- *setme_len = retlen;
-
- return ret;
-}
-
-char *
-tr_base64_decode (const void * input,
- int length,
- int * setme_len)
-{
- char * ret;
- BIO * b64;
- BIO * bmem;
- int retlen;
-
- if (length < 1)
- length = strlen (input);
-
- ret = tr_new0 (char, length);
- b64 = BIO_new (BIO_f_base64 ());
- bmem = BIO_new_mem_buf ((unsigned char*)input, length);
- bmem = BIO_push (b64, bmem);
- retlen = BIO_read (bmem, ret, length);
- if (!retlen)
- {
- /* try again, but with the BIO_FLAGS_BASE64_NO_NL flag */
- BIO_free_all (bmem);
- b64 = BIO_new (BIO_f_base64 ());
- BIO_set_flags (b64, BIO_FLAGS_BASE64_NO_NL);
- bmem = BIO_new_mem_buf ((unsigned char*)input, length);
- bmem = BIO_push (b64, bmem);
- retlen = BIO_read (bmem, ret, length);
- }
-
- if (setme_len)
- *setme_len = retlen;
-
- BIO_free_all (bmem);
- return ret;
-}
-
/***
****
***/
char * tr_strdup_vprintf (const char * fmt,
va_list args) TR_GNUC_MALLOC;
-/**
- * @brief Translate a block of bytes into base64
- * @return a newly-allocated string that can be freed with tr_free ()
- */
-char* tr_base64_encode (const void * input,
- int inlen,
- int * outlen) TR_GNUC_MALLOC;
-
-/**
- * @brief Translate a block of bytes from base64 into raw form
- * @return a newly-allocated string that can be freed with tr_free ()
- */
-char* tr_base64_decode (const void * input,
- int inlen,
- int * outlen) TR_GNUC_MALLOC;
-
/** @brief Portability wrapper for strlcpy () that uses the system implementation if available */
size_t tr_strlcpy (char * dst, const void * src, size_t siz);
#include <QDir>
#include <libtransmission/transmission.h>
-#include <libtransmission/utils.h> // tr_base64_encode()
+#include <libtransmission/crypto-utils.h> // tr_base64_encode()
#include "add-data.h"
#include "utils.h"
}
else
{
- int len;
- char * raw = tr_base64_decode (key.toUtf8().constData(), key.toUtf8().size(), &len);
+ size_t len;
+ void * raw = tr_base64_decode (key.toUtf8().constData(), key.toUtf8().size(), &len);
if (raw)
{
- metainfo.append (raw, len);
+ metainfo.append (static_cast<const char*> (raw), (int) len);
tr_free (raw);
type = METAINFO;
}
if (!metainfo.isEmpty ())
{
- int len = 0;
- char * b64 = tr_base64_encode (metainfo.constData(), metainfo.size(), &len);
- ret = QByteArray (b64, len);
+ size_t len;
+ void * b64 = tr_base64_encode (metainfo.constData(), metainfo.size(), &len);
+ ret = QByteArray (static_cast<const char*> (b64), (int) len);
tr_free (b64);
}