fix broken b64 decoding when reading encfs 1.x XML files

git-svn-id: http://encfs.googlecode.com/svn/trunk@120 db9cf616-1c43-0410-9cb8-a902689de0d6
This commit is contained in:
Valient Gough 2013-10-19 07:09:15 +00:00
parent 2b01a08938
commit 154ce001a1
3 changed files with 76 additions and 23 deletions

View File

@ -121,8 +121,10 @@ bool XmlValue::readB64(const char *path, byte *data, int length) const
<< ", got " << decodedSize;
return false;
}
changeBase2((byte *)s.data(), s.size(), 6, data, length, 8);
B64ToAsciiStandard(data, length);
if (!B64StandardDecode(data, (byte*) s.data(), s.size())) {
LOG(ERROR) << "B64 decode failure on " << s;
return false;
}
return true;
}

View File

@ -21,6 +21,7 @@
#include "base/base64.h"
#include <ctype.h>
#include <glog/logging.h>
namespace encfs {
@ -148,25 +149,6 @@ void B64ToAscii(byte *in, int length)
}
}
void B64ToAsciiStandard(byte *in, int length)
{
static const char LookupTable[] = "+/0123456789";
for(int offset=0; offset<length; ++offset)
{
int ch = in[offset];
if(ch > 11)
{
if(ch > 37)
ch += 'a' - 38;
else
ch += 'A' - 12;
} else
ch = LookupTable[ ch ];
in[offset] = ch;
}
}
static const byte Ascii2B64Table[] =
" 01 23456789:; ";
// 0123456789 123456789 123456789 123456789 123456789 123456789 1234
@ -229,4 +211,71 @@ void AsciiToB32(byte *out, const byte *in, int length)
}
}
#define WHITESPACE 64
#define EQUALS 65
#define INVALID 66
static const byte d[] = {
66,66,66,66,66,66,66,66,66,64,
66,66,66,66,66,66,66,66,66,66,
66,66,66,66,66,66,66,66,66,66,
66,66,66,66,66,66,66,66,66,66,
66,66,66,62,66,66,66,63,52,53,
54,55,56,57,58,59,60,61,66,66, // 50-59
66,65,66,66,66, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9,10,11,12,13,14,
15,16,17,18,19,20,21,22,23,24,
25,66,66,66,66,66,66,26,27,28,
29,30,31,32,33,34,35,36,37,38, // 100-109
39,40,41,42,43,44,45,46,47,48,
49,50,51
};
bool B64StandardDecode(byte *out, const byte *in, int inLen) {
const byte *end = in + inLen;
size_t buf = 1;
while (in < end) {
byte v = *in++;
if (v > 'z') {
LOG(ERROR) << "Invalid character: " << (unsigned int)v;
return false;
}
byte c = d[v];
switch (c) {
case WHITESPACE: continue; /* skip whitespace */
case INVALID:
LOG(ERROR) << "Invalid character: " << (unsigned int)v;
return false; /* invalid input, return error */
case EQUALS: /* pad character, end of data */
in = end;
continue;
default:
buf = buf << 6 | c;
/* If the buffer is full, split it into bytes */
if (buf & 0x1000000) {
*out++ = buf >> 16;
*out++ = buf >> 8;
*out++ = buf;
buf = 1;
}
}
}
if (buf & 0x40000) {
*out++ = buf >> 10;
*out++ = buf >> 2;
}
else if (buf & 0x1000) {
*out++ = buf >> 4;
}
return true;
}
} // namespace encfs

View File

@ -62,8 +62,6 @@ void changeBase2Inline(byte *buf, int srcLength,
// inplace translation from values [0,2^6] => base64 ASCII
void B64ToAscii(byte *buf, int length);
// Like B64ToAscii, but uses standard characters "+" and "/" in encoding.
void B64ToAsciiStandard(byte *buf, int length);
// inplace translation from values [0,2^5] => base32 ASCII
void B32ToAscii(byte *buf, int length);
@ -75,6 +73,10 @@ void AsciiToB64(byte *out, const byte *in, int length);
void AsciiToB32(byte *buf, int length);
void AsciiToB32(byte *out, const byte *in, int length);
// Decode B64 standard into the output array.
// The output size must be at least B64ToB256Bytes(inputLen).
bool B64StandardDecode(byte *out, const byte *in, int inputLen);
} // namespace encfs
#endif