Commit 72888c4b authored by ale's avatar ale

Base64 decoder supports missing padding

This makes the C implementation compatible with the Go one, which
generates unpadded base64-encoded tokens.
parent a1981a2f
......@@ -27,6 +27,8 @@
#include <sys/types.h>
#include <inttypes.h>
#include <memory.h>
#include <stdlib.h>
#include "sso.h"
static const unsigned char base64_enc_map[64] = {
......@@ -117,15 +119,8 @@ int sso_base64_encode(unsigned char *dst, size_t *dlen,
return 0;
}
/**
* Decode a base64-formatted buffer.
*
* Supports both standard and "web-safe" encodings.
*
* The destination buffer is *not* zero-terminated.
*/
int sso_base64_decode(unsigned char *dst, size_t *dlen,
const unsigned char *src, size_t slen) {
static int sso_base64_decode_real(unsigned char *dst, size_t *dlen,
const unsigned char *src, size_t slen) {
size_t i, n;
uint32_t j, x;
unsigned char *p;
......@@ -199,3 +194,29 @@ int sso_base64_decode(unsigned char *dst, size_t *dlen,
return 0;
}
/**
* Decode a base64-formatted buffer.
*
* Supports both standard and "web-safe" encodings, and it can
* deal with missing padding.
*
* The destination buffer is *not* zero-terminated.
*/
int sso_base64_decode(unsigned char *dst, size_t *dlen,
const unsigned char *src, size_t slen) {
unsigned char *srcbuf;
int n, r;
n = 4 - (slen % 4);
if (n < 4) {
srcbuf = (unsigned char *)malloc(slen + n);
memcpy(srcbuf, src, slen);
memset(srcbuf + slen, '=', n);
r = sso_base64_decode_real(dst, dlen, srcbuf, slen + n);
free(srcbuf);
} else {
r = sso_base64_decode_real(dst, dlen, src, slen);
}
return r;
}
......@@ -61,6 +61,34 @@ TEST(Base64, DecodeStdOk) {
EXPECT_EQ(0, memcmp(alphabet, out, sz));
}
static const char *unpadded_src[] = {
"aA",
"aGU",
"aGVs",
"aGVsbA",
"aGVsbG8",
};
static const char *unpadded_res[] = {
"h",
"he",
"hel",
"hell",
"hello",
};
TEST(Base64, DecodeUnpaddedOk) {
for (int i = 0; i < 5; i++) {
char out[256] = {0};
size_t sz = sizeof(out);
EXPECT_EQ(0, sso_base64_decode((unsigned char *)out, &sz,
(unsigned char *)unpadded_src[i],
(size_t)strlen(unpadded_src[i])));
EXPECT_EQ(std::string(unpadded_res[i]), std::string(out, sz))
<< "Error decoding '" << unpadded_src[i] << "'";
}
}
class SSO : public testing::Test {
protected:
virtual void SetUp() { sso_generate_keys(public_key, secret_key); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment