summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2002-10-30 21:48:01 +0100
committerNiels Möller <nisse@lysator.liu.se>2002-10-30 21:48:01 +0100
commit62e431b4da1d3789ebf1decd5c2a208e893a3813 (patch)
tree841ac3a16f64ffc99f97ea8481baac258ae63638
parente3e5eb760e03aeca6b863814de4f928e1e343551 (diff)
downloadnettle-62e431b4da1d3789ebf1decd5c2a208e893a3813.tar.gz
* base64-decode.c (base64_decode_single): Return -1 on error.
Also keep track of the number of padding characters ('=') seen. (base64_decode_update): New argument dst_length. Return -1 on error. (base64_decode_status): Renamed function... (base64_decode_final): ... to this. * base64.h (struct base64_decode_ctx): Deleted STATUS attribute. Added PADDING attribute. Rev: src/nettle/base64-decode.c:1.4 Rev: src/nettle/base64.h:1.11
-rw-r--r--base64-decode.c78
-rw-r--r--base64.h32
2 files changed, 57 insertions, 53 deletions
diff --git a/base64-decode.c b/base64-decode.c
index c332aa22..c1c0d2f0 100644
--- a/base64-decode.c
+++ b/base64-decode.c
@@ -57,30 +57,26 @@ decode_table[0x100] =
void
base64_decode_init(struct base64_decode_ctx *ctx)
{
- ctx->word = ctx->bits = 0;
- ctx->status = BASE64_DECODE_OK;
+ ctx->word = ctx->bits = ctx->padding = 0;
}
-unsigned
+int
base64_decode_single(struct base64_decode_ctx *ctx,
uint8_t *dst,
uint8_t src)
{
int data;
- if (ctx->status == BASE64_DECODE_ERROR)
- return 0;
-
data = decode_table[src];
switch(data)
{
default:
assert(data >= 0 && data < 0x40);
-
- if (ctx->status != BASE64_DECODE_OK)
- goto invalid;
-
+
+ if (ctx->padding)
+ return -1;
+
ctx->word = ctx->word << 6 | data;
ctx->bits += 6;
@@ -93,56 +89,60 @@ base64_decode_single(struct base64_decode_ctx *ctx,
else return 0;
case TABLE_INVALID:
- invalid:
- ctx->status = BASE64_DECODE_ERROR;
- /* Fall through */
-
+ return -1;
+
case TABLE_SPACE:
return 0;
case TABLE_END:
- if (!ctx->bits)
- goto invalid;
+ /* There can be at most two padding characters. */
+ if (!ctx->bits || ctx->padding > 2)
+ return -1;
+
if (ctx->word & ( (1<<ctx->bits) - 1))
/* We shouldn't have any leftover bits */
- goto invalid;
-
- ctx->status = BASE64_DECODE_END;
+ return -1;
+
+ ctx->padding++;
ctx->bits -= 2;
return 0;
}
}
-unsigned
+int
base64_decode_update(struct base64_decode_ctx *ctx,
+ unsigned *dst_length,
uint8_t *dst,
- unsigned length,
+ unsigned src_length,
const uint8_t *src)
{
unsigned done;
unsigned i;
-
- if (ctx->status == BASE64_DECODE_ERROR)
- return 0;
- for (i = 0, done = 0; i<length; i++)
- done += base64_decode_single(ctx, dst + done, src[i]);
-
- assert(done <= BASE64_DECODE_LENGTH(length));
+ assert(*dst_length >= BASE64_DECODE_LENGTH(src_length));
+
+ for (i = 0, done = 0; i<src_length; i++)
+ switch(base64_decode_single(ctx, dst + done, src[i]))
+ {
+ case -1:
+ return 0;
+ case 1:
+ done++;
+ /* Fall through */
+ case 0:
+ break;
+ default:
+ abort();
+ }
- return done;
+ assert(done <= BASE64_DECODE_LENGTH(src_length));
+
+ *dst_length = done;
+ return 1;
}
int
-base64_decode_status(struct base64_decode_ctx *ctx)
+base64_decode_final(struct base64_decode_ctx *ctx)
{
- switch (ctx->status)
- {
- case BASE64_DECODE_END:
- case BASE64_DECODE_OK:
- return ctx->bits == 0;
- case BASE64_DECODE_ERROR:
- return 0;
- }
- abort();
+ return ctx->bits == 0;
}
diff --git a/base64.h b/base64.h
index 3084bbff..9532e54f 100644
--- a/base64.h
+++ b/base64.h
@@ -95,36 +95,40 @@ base64_encode_group(uint8_t *dst, uint32_t group);
struct base64_decode_ctx
{
- enum
- {
- BASE64_DECODE_OK,
- BASE64_DECODE_ERROR,
- BASE64_DECODE_END
- } status;
unsigned word; /* Leftover bits */
unsigned bits; /* Number buffered bits */
+
+ /* Number of padding characters encountered */
+ unsigned padding;
};
void
base64_decode_init(struct base64_decode_ctx *ctx);
-/* Decodes a single byte. Returns amount of output (always 0 or 1).
- * FIXME: What to return on errors? */
-unsigned
+/* Decodes a single byte. Returns amount of output (0 or 1), or -1 on
+ * errors. */
+int
base64_decode_single(struct base64_decode_ctx *ctx,
uint8_t *dst,
uint8_t src);
-/* Returns the number of output characters. DST should point to an
- * area of size at least BASE64_DECODE_LENGTH(length). */
-unsigned
+/* Returns 1 on success, 0 on error. DST should point to an area of
+ * size at least BASE64_DECODE_LENGTH(length), and for sanity
+ * checking, *DST_LENGTH should be initialized to the size of that
+ * area before the call. *DST_LENGTH is updated to the amount of
+ * decoded output. */
+
+/* FIXME: Currently results in an assertion failure if *DST_LENGTH is
+ * too small. Return some error instead? */
+int
base64_decode_update(struct base64_decode_ctx *ctx,
+ unsigned *dst_length,
uint8_t *dst,
- unsigned length,
+ unsigned src_length,
const uint8_t *src);
/* Returns 1 on success. */
int
-base64_decode_status(struct base64_decode_ctx *ctx);
+base64_decode_final(struct base64_decode_ctx *ctx);
#endif /* NETTLE_BASE64_H_INCLUDED */