summaryrefslogtreecommitdiff
path: root/src/common/base64.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/base64.c')
-rw-r--r--src/common/base64.c94
1 files changed, 56 insertions, 38 deletions
diff --git a/src/common/base64.c b/src/common/base64.c
index a153a70..3deee97 100644
--- a/src/common/base64.c
+++ b/src/common/base64.c
@@ -14,7 +14,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <config.h>
#include "base64.h"
+#include "errcode.h"
#include <stdlib.h> // malloc
#include <stdint.h> // uint8_t
@@ -81,9 +83,9 @@ const uint8_t base64_dec[256] = {
};
int32_t base64_encode(const uint8_t *in,
- const uint32_t in_len,
- uint8_t *out,
- const uint32_t out_len)
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len)
{
uint8_t rest_len = in_len % 3;
const uint8_t *data = in;
@@ -92,9 +94,11 @@ int32_t base64_encode(const uint8_t *in,
uint8_t num;
// Checking inputs.
- if (in == NULL || out == NULL || in_len > MAX_BIN_DATA_LEN ||
- out_len < ((in_len + 2) / 3) * 4) {
- return -1;
+ if (in == NULL || out == NULL) {
+ return KNOT_EINVAL;
+ }
+ if (in_len > MAX_BIN_DATA_LEN || out_len < ((in_len + 2) / 3) * 4) {
+ return KNOT_ERANGE;
}
// Encoding loop takes 3 bytes and creates 4 characters.
@@ -121,7 +125,7 @@ int32_t base64_encode(const uint8_t *in,
// Processing of padding, if any.
switch (rest_len) {
// Input data has 2-byte last block => 1-char padding.
- case 2:
+ case 2:
// Computing 1. Base64 character.
num = *data >> 2;
*text++ = base64_enc[num];
@@ -138,9 +142,9 @@ int32_t base64_encode(const uint8_t *in,
// 1 padding character.
*text++ = base64_pad;
- break;
+ break;
// Input data has 1-byte last block => 2-char padding.
- case 1:
+ case 1:
// Computing 1. Base64 character.
num = *data >> 2;
*text++ = base64_enc[num];
@@ -153,38 +157,43 @@ int32_t base64_encode(const uint8_t *in,
*text++ = base64_pad;
*text++ = base64_pad;
- break;
+ break;
}
return (text - out);
}
int32_t base64_encode_alloc(const uint8_t *in,
- const uint32_t in_len,
- uint8_t **out)
+ const uint32_t in_len,
+ uint8_t **out)
{
- uint32_t out_len = ((in_len + 2) / 3) * 4;
-
- // Checking inputs.
+ // Check input (output is longer).
if (in_len > MAX_BIN_DATA_LEN) {
- return -1;
+ return KNOT_ERANGE;
}
- // Allocating output buffer.
- *out = malloc(out_len);
+ // Compute output buffer length.
+ uint32_t out_len = ((in_len + 2) / 3) * 4;
+ // Allocate output buffer.
+ *out = malloc(out_len);
if (*out == NULL) {
- return -1;
+ return KNOT_ENOMEM;
}
- // Encoding data.
- return base64_encode(in, in_len, *out, out_len);
+ // Encode data.
+ int32_t ret = base64_encode(in, in_len, *out, out_len);
+ if (ret < 0) {
+ free(*out);
+ }
+
+ return ret;
}
int32_t base64_decode(const uint8_t *in,
- const uint32_t in_len,
- uint8_t *out,
- const uint32_t out_len)
+ const uint32_t in_len,
+ uint8_t *out,
+ const uint32_t out_len)
{
const uint8_t *data = in;
const uint8_t *stop = in + in_len;
@@ -193,9 +202,14 @@ int32_t base64_decode(const uint8_t *in,
uint8_t c1, c2, c3, c4;
// Checking inputs.
- if (in == NULL || out == NULL || (in_len % 4) != 0 ||
- in_len > INT32_MAX || out_len < ((in_len + 3) / 4) * 3) {
- return -1;
+ if (in == NULL || out == NULL) {
+ return KNOT_EINVAL;
+ }
+ if (in_len > INT32_MAX || out_len < ((in_len + 3) / 4) * 3) {
+ return KNOT_ERANGE;
+ }
+ if ((in_len % 4) != 0) {
+ return KNOT_BASE64_ESIZE;
}
// Decoding loop takes 4 characters and creates 3 bytes.
@@ -211,7 +225,7 @@ int32_t base64_decode(const uint8_t *in,
if (c4 == PD) {
pad_len = 1;
} else {
- return -2;
+ return KNOT_BASE64_ECHAR;
}
}
@@ -220,13 +234,13 @@ int32_t base64_decode(const uint8_t *in,
if (c3 == PD) {
pad_len = 2;
} else {
- return -2;
+ return KNOT_BASE64_ECHAR;
}
}
// 1. and 2. chars must not be padding.
if (c2 >= PD || c1 >= PD) {
- return -2;
+ return KNOT_BASE64_ECHAR;
}
// Computing of output data based on padding length.
@@ -253,19 +267,23 @@ int32_t base64_decode(const uint8_t *in,
}
int32_t base64_decode_alloc(const uint8_t *in,
- const uint32_t in_len,
- uint8_t **out)
+ const uint32_t in_len,
+ uint8_t **out)
{
+ // Compute output buffer length.
uint32_t out_len = ((in_len + 3) / 4) * 3;
+ // Allocate output buffer.
*out = malloc(out_len);
-
- // Allocating output buffer.
if (*out == NULL) {
- return -1;
+ return KNOT_ENOMEM;
}
- // Decoding data.
- return base64_decode(in, in_len, *out, out_len);
-}
+ // Decode data.
+ int32_t ret = base64_decode(in, in_len, *out, out_len);
+ if (ret < 0) {
+ free(*out);
+ }
+ return ret;
+}