summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-string.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2004-05-17 22:19:04 +0000
committerKristian Høgsberg <krh@redhat.com>2004-05-17 22:19:04 +0000
commitd86fc4071ccb8590d922e3456c5c80c0f7bb9d6f (patch)
tree7ed880494686d9290ad1f9ded6230459e2e7269a /dbus/dbus-string.c
parent91605d6899e8f21a6adf7f2fc87cfe07d399875f (diff)
2004-05-17 Kristian Høgsberg <krh@redhat.com>
Remove base64 encoding, replace with hex encoding. Original patch from trow@ximian.com, added error handling. * dbus/dbus-string.c (_dbus_string_base64_encode) (_dbus_string_base64_decode): Remove. (_dbus_string_hex_decode): Add end_return argument so we can distinguish between OOM and invalid hex encoding. (_dbus_string_test): Remove base64 tests and add test case for invalid hex. * dbus/dbus-keyring.c, dbus/dbus-auth-script.c, dbus/dbus-auth.c: Replace base64 with hex. * test/data/auth/invalid-hex-encoding.auth-script: New test case for invalid hex encoded data in auth protocol.
Diffstat (limited to 'dbus/dbus-string.c')
-rw-r--r--dbus/dbus-string.c478
1 files changed, 26 insertions, 452 deletions
diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c
index 6a83398d..8820273d 100644
--- a/dbus/dbus-string.c
+++ b/dbus/dbus-string.c
@@ -2125,400 +2125,6 @@ _dbus_string_ends_with_c_str (const DBusString *a,
return TRUE;
}
-static const signed char base64_table[] = {
- /* 0 */ 'A',
- /* 1 */ 'B',
- /* 2 */ 'C',
- /* 3 */ 'D',
- /* 4 */ 'E',
- /* 5 */ 'F',
- /* 6 */ 'G',
- /* 7 */ 'H',
- /* 8 */ 'I',
- /* 9 */ 'J',
- /* 10 */ 'K',
- /* 11 */ 'L',
- /* 12 */ 'M',
- /* 13 */ 'N',
- /* 14 */ 'O',
- /* 15 */ 'P',
- /* 16 */ 'Q',
- /* 17 */ 'R',
- /* 18 */ 'S',
- /* 19 */ 'T',
- /* 20 */ 'U',
- /* 21 */ 'V',
- /* 22 */ 'W',
- /* 23 */ 'X',
- /* 24 */ 'Y',
- /* 25 */ 'Z',
- /* 26 */ 'a',
- /* 27 */ 'b',
- /* 28 */ 'c',
- /* 29 */ 'd',
- /* 30 */ 'e',
- /* 31 */ 'f',
- /* 32 */ 'g',
- /* 33 */ 'h',
- /* 34 */ 'i',
- /* 35 */ 'j',
- /* 36 */ 'k',
- /* 37 */ 'l',
- /* 38 */ 'm',
- /* 39 */ 'n',
- /* 40 */ 'o',
- /* 41 */ 'p',
- /* 42 */ 'q',
- /* 43 */ 'r',
- /* 44 */ 's',
- /* 45 */ 't',
- /* 46 */ 'u',
- /* 47 */ 'v',
- /* 48 */ 'w',
- /* 49 */ 'x',
- /* 50 */ 'y',
- /* 51 */ 'z',
- /* 52 */ '0',
- /* 53 */ '1',
- /* 54 */ '2',
- /* 55 */ '3',
- /* 56 */ '4',
- /* 57 */ '5',
- /* 58 */ '6',
- /* 59 */ '7',
- /* 60 */ '8',
- /* 61 */ '9',
- /* 62 */ '+',
- /* 63 */ '/'
-};
-
-/** The minimum char that's a valid char in Base64-encoded text */
-#define UNBASE64_MIN_CHAR (43)
-/** The maximum char that's a valid char in Base64-encoded text */
-#define UNBASE64_MAX_CHAR (122)
-/** Must subtract this from a char's integer value before offsetting
- * into unbase64_table
- */
-#define UNBASE64_TABLE_OFFSET UNBASE64_MIN_CHAR
-static const signed char unbase64_table[] = {
- /* 43 + */ 62,
- /* 44 , */ -1,
- /* 45 - */ -1,
- /* 46 . */ -1,
- /* 47 / */ 63,
- /* 48 0 */ 52,
- /* 49 1 */ 53,
- /* 50 2 */ 54,
- /* 51 3 */ 55,
- /* 52 4 */ 56,
- /* 53 5 */ 57,
- /* 54 6 */ 58,
- /* 55 7 */ 59,
- /* 56 8 */ 60,
- /* 57 9 */ 61,
- /* 58 : */ -1,
- /* 59 ; */ -1,
- /* 60 < */ -1,
- /* 61 = */ -1,
- /* 62 > */ -1,
- /* 63 ? */ -1,
- /* 64 @ */ -1,
- /* 65 A */ 0,
- /* 66 B */ 1,
- /* 67 C */ 2,
- /* 68 D */ 3,
- /* 69 E */ 4,
- /* 70 F */ 5,
- /* 71 G */ 6,
- /* 72 H */ 7,
- /* 73 I */ 8,
- /* 74 J */ 9,
- /* 75 K */ 10,
- /* 76 L */ 11,
- /* 77 M */ 12,
- /* 78 N */ 13,
- /* 79 O */ 14,
- /* 80 P */ 15,
- /* 81 Q */ 16,
- /* 82 R */ 17,
- /* 83 S */ 18,
- /* 84 T */ 19,
- /* 85 U */ 20,
- /* 86 V */ 21,
- /* 87 W */ 22,
- /* 88 X */ 23,
- /* 89 Y */ 24,
- /* 90 Z */ 25,
- /* 91 [ */ -1,
- /* 92 \ */ -1,
- /* 93 ] */ -1,
- /* 94 ^ */ -1,
- /* 95 _ */ -1,
- /* 96 ` */ -1,
- /* 97 a */ 26,
- /* 98 b */ 27,
- /* 99 c */ 28,
- /* 100 d */ 29,
- /* 101 e */ 30,
- /* 102 f */ 31,
- /* 103 g */ 32,
- /* 104 h */ 33,
- /* 105 i */ 34,
- /* 106 j */ 35,
- /* 107 k */ 36,
- /* 108 l */ 37,
- /* 109 m */ 38,
- /* 110 n */ 39,
- /* 111 o */ 40,
- /* 112 p */ 41,
- /* 113 q */ 42,
- /* 114 r */ 43,
- /* 115 s */ 44,
- /* 116 t */ 45,
- /* 117 u */ 46,
- /* 118 v */ 47,
- /* 119 w */ 48,
- /* 120 x */ 49,
- /* 121 y */ 50,
- /* 122 z */ 51
-};
-
-/**
- * Encodes a string using Base64, as documented in RFC 2045.
- *
- * @param source the string to encode
- * @param start byte index to start encoding
- * @param dest string where encoded data should be placed
- * @param insert_at where to place encoded data
- * @returns #TRUE if encoding was successful, #FALSE if no memory etc.
- */
-dbus_bool_t
-_dbus_string_base64_encode (const DBusString *source,
- int start,
- DBusString *dest,
- int insert_at)
-{
- int source_len;
- unsigned int dest_len; /* unsigned for overflow checks below */
- const unsigned char *s;
- unsigned char *d;
- const unsigned char *triplet_end;
- const unsigned char *final_end;
- DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
- _dbus_assert (source != dest);
-
- /* For each 24 bits (3 bytes) of input, we have 4 bytes of
- * output.
- */
- source_len = real_source->len - start;
- dest_len = (source_len / 3) * 4;
- if (source_len % 3 != 0)
- dest_len += 4;
-
- if (dest_len > (unsigned int) real_dest->max_length)
- return FALSE;
-
- if (source_len == 0)
- return TRUE;
-
- if (!open_gap (dest_len, real_dest, insert_at))
- return FALSE;
-
- d = real_dest->str + insert_at;
- s = real_source->str + start;
- final_end = real_source->str + (start + source_len);
- triplet_end = final_end - (source_len % 3);
- _dbus_assert (triplet_end <= final_end);
- _dbus_assert ((final_end - triplet_end) < 3);
-
-#define ENCODE_64(v) (base64_table[ (unsigned char) (v) ])
-#define SIX_BITS_MASK (0x3f)
- _dbus_assert (SIX_BITS_MASK < _DBUS_N_ELEMENTS (base64_table));
-
- while (s != triplet_end)
- {
- unsigned int triplet;
-
- triplet = s[2] | (s[1] << 8) | (s[0] << 16);
-
- /* Encode each 6 bits. */
-
- *d++ = ENCODE_64 (triplet >> 18);
- *d++ = ENCODE_64 ((triplet >> 12) & SIX_BITS_MASK);
- *d++ = ENCODE_64 ((triplet >> 6) & SIX_BITS_MASK);
- *d++ = ENCODE_64 (triplet & SIX_BITS_MASK);
-
- s += 3;
- }
-
- switch (final_end - triplet_end)
- {
- case 2:
- {
- unsigned int doublet;
-
- doublet = s[1] | (s[0] << 8);
-
- *d++ = ENCODE_64 (doublet >> 12);
- *d++ = ENCODE_64 ((doublet >> 6) & SIX_BITS_MASK);
- *d++ = ENCODE_64 (doublet & SIX_BITS_MASK);
- *d++ = '=';
- }
- break;
- case 1:
- {
- unsigned int singlet;
-
- singlet = s[0];
-
- *d++ = ENCODE_64 ((singlet >> 6) & SIX_BITS_MASK);
- *d++ = ENCODE_64 (singlet & SIX_BITS_MASK);
- *d++ = '=';
- *d++ = '=';
- }
- break;
- case 0:
- break;
- }
-
- _dbus_assert (d == (real_dest->str + (insert_at + dest_len)));
-
- return TRUE;
-}
-
-/**
- * Decodes a string from Base64, as documented in RFC 2045.
- *
- * @todo sort out the AUDIT comment in here. The case it mentions
- * ("====" or "x===") is not allowed in correct base64, so need to
- * decide what to do with that kind of input. Probably ignore it
- * since we ignore any other junk seen.
- *
- * @param source the string to decode
- * @param start byte index to start decode
- * @param dest string where decoded data should be placed
- * @param insert_at where to place decoded data
- * @returns #TRUE if decoding was successful, #FALSE if no memory etc.
- */
-dbus_bool_t
-_dbus_string_base64_decode (const DBusString *source,
- int start,
- DBusString *dest,
- int insert_at)
-{
- int source_len;
- const char *s;
- const char *end;
- DBusString result;
- unsigned int triplet = 0;
- int sextet_count;
- int pad_count;
- DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);
- _dbus_assert (source != dest);
-
- source_len = real_source->len - start;
- s = real_source->str + start;
- end = real_source->str + source_len;
-
- if (source_len == 0)
- return TRUE;
-
- if (!_dbus_string_init (&result))
- return FALSE;
-
- pad_count = 0;
- sextet_count = 0;
- while (s != end)
- {
- /* The idea is to just skip anything that isn't
- * a base64 char - it's allowed to have whitespace,
- * newlines, etc. in here. We also ignore trailing
- * base64 chars, though that's suspicious.
- */
-
- if (*s >= UNBASE64_MIN_CHAR &&
- *s <= UNBASE64_MAX_CHAR)
- {
- if (*s == '=')
- {
- /* '=' is padding, doesn't represent additional data
- * but does increment our count.
- */
- pad_count += 1;
- sextet_count += 1;
- }
- else
- {
- int val;
-
- val = unbase64_table[(*s) - UNBASE64_TABLE_OFFSET];
-
- if (val >= 0)
- {
- triplet <<= 6;
- triplet |= (unsigned int) val;
- sextet_count += 1;
- }
- }
-
- if (sextet_count == 4)
- {
- /* no pad = 3 bytes, 1 pad = 2 bytes, 2 pad = 1 byte */
-
-
- /* AUDIT: Comment doesn't mention 4 pad => 0,
- * 3 pad => 1 byte, though the code should
- * work fine if those are the required outputs.
- *
- * I assume that the spec requires dropping
- * the top two bits of, say, ///= which is > 2
- * bytes worth of bits. (Or otherwise, you couldn't
- * actually represent 2 byte sequences.
- */
-
- if (pad_count < 1)
- {
- if (!_dbus_string_append_byte (&result,
- triplet >> 16))
- goto failed;
- }
-
- if (pad_count < 2)
- {
- if (!_dbus_string_append_byte (&result,
- (triplet >> 8) & 0xff))
- goto failed;
- }
-
- if (!_dbus_string_append_byte (&result,
- triplet & 0xff))
- goto failed;
-
- sextet_count = 0;
- pad_count = 0;
- triplet = 0;
- }
- }
-
- ++s;
- }
-
- if (!_dbus_string_move (&result, 0, dest, insert_at))
- {
- _dbus_string_free (&result);
- return FALSE;
- }
-
- _dbus_string_free (&result);
-
- return TRUE;
-
- failed:
- _dbus_string_free (&result);
-
- return FALSE;
-}
-
/**
* Encodes a string in hex, the way MD5 and SHA-1 are usually
* encoded. (Each byte is two hex digits.)
@@ -2583,13 +2189,15 @@ _dbus_string_hex_encode (const DBusString *source,
*
* @param source the string to decode
* @param start byte index to start decode
+ * @param end_return return location of the end of the hex data, or #NULL
* @param dest string where decoded data should be placed
* @param insert_at where to place decoded data
- * @returns #TRUE if decoding was successful, #FALSE if no memory etc.
+ * @returns #TRUE if decoding was successful, #FALSE if no memory.
*/
dbus_bool_t
_dbus_string_hex_decode (const DBusString *source,
int start,
+ int *end_return,
DBusString *dest,
int insert_at)
{
@@ -2672,17 +2280,14 @@ _dbus_string_hex_decode (const DBusString *source,
val = 15;
break;
default:
- val = 0;
- _dbus_verbose ("invalid character '%c' in hex encoded text\n",
- *p);
- goto out;
+ goto done;
}
if (high_bits)
{
if (!_dbus_string_append_byte (&result,
val << 4))
- goto out;
+ goto out;
}
else
{
@@ -2703,9 +2308,13 @@ _dbus_string_hex_decode (const DBusString *source,
++p;
}
+ done:
if (!_dbus_string_move (&result, 0, dest, insert_at))
goto out;
+ if (end_return)
+ *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source);
+
retval = TRUE;
out:
@@ -3228,60 +2837,13 @@ test_max_len (DBusString *str,
}
static void
-test_base64_roundtrip (const unsigned char *data,
- int len)
-{
- DBusString orig;
- DBusString encoded;
- DBusString decoded;
-
- if (len < 0)
- len = strlen (data);
-
- if (!_dbus_string_init (&orig))
- _dbus_assert_not_reached ("could not init string");
-
- if (!_dbus_string_init (&encoded))
- _dbus_assert_not_reached ("could not init string");
-
- if (!_dbus_string_init (&decoded))
- _dbus_assert_not_reached ("could not init string");
-
- if (!_dbus_string_append_len (&orig, data, len))
- _dbus_assert_not_reached ("couldn't append orig data");
-
- if (!_dbus_string_base64_encode (&orig, 0, &encoded, 0))
- _dbus_assert_not_reached ("could not encode");
-
- if (!_dbus_string_base64_decode (&encoded, 0, &decoded, 0))
- _dbus_assert_not_reached ("could not decode");
-
- if (!_dbus_string_equal (&orig, &decoded))
- {
- const char *s;
-
- printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n",
- _dbus_string_get_length (&orig),
- _dbus_string_get_length (&encoded),
- _dbus_string_get_length (&decoded));
- printf ("Original: %s\n", data);
- s = _dbus_string_get_const_data (&decoded);
- printf ("Decoded: %s\n", s);
- _dbus_assert_not_reached ("original string not the same as string decoded from base64");
- }
-
- _dbus_string_free (&orig);
- _dbus_string_free (&encoded);
- _dbus_string_free (&decoded);
-}
-
-static void
test_hex_roundtrip (const unsigned char *data,
int len)
{
DBusString orig;
DBusString encoded;
DBusString decoded;
+ int end;
if (len < 0)
len = strlen (data);
@@ -3301,9 +2863,11 @@ test_hex_roundtrip (const unsigned char *data,
if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))
_dbus_assert_not_reached ("could not encode");
- if (!_dbus_string_hex_decode (&encoded, 0, &decoded, 0))
+ if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))
_dbus_assert_not_reached ("could not decode");
+ _dbus_assert (_dbus_string_get_length (&encoded) == end);
+
if (!_dbus_string_equal (&orig, &decoded))
{
const char *s;
@@ -3315,7 +2879,7 @@ test_hex_roundtrip (const unsigned char *data,
printf ("Original: %s\n", data);
s = _dbus_string_get_const_data (&decoded);
printf ("Decoded: %s\n", s);
- _dbus_assert_not_reached ("original string not the same as string decoded from base64");
+ _dbus_assert_not_reached ("original string not the same as string decoded from hex");
}
_dbus_string_free (&orig);
@@ -3867,8 +3431,18 @@ _dbus_string_test (void)
_dbus_string_free (&str);
- /* Base 64 and Hex encoding */
- test_roundtrips (test_base64_roundtrip);
+ /* Hex encoding */
+ _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string");
+ if (!_dbus_string_init (&other))
+ _dbus_assert_not_reached ("could not init string");
+
+ if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0))
+ _dbus_assert_not_reached ("deccoded bogus hex string with no error");
+
+ _dbus_assert (end == 8);
+
+ _dbus_string_free (&other);
+
test_roundtrips (test_hex_roundtrip);
/* Path validation */