Replace base64 decoding.
This code has caused a long history of problems. This change rewrites it
completely with something that is, hopefully, much simplier and robust
and adds more testing.
Change-Id: Ibeef51f9386afd95d5b73316e451eb3a2d7ec4e0
Reviewed-on: https://boringssl-review.googlesource.com/8033
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/base64.h b/include/openssl/base64.h
index f28e7dd..4bf3888 100644
--- a/include/openssl/base64.h
+++ b/include/openssl/base64.h
@@ -87,15 +87,16 @@
/* Decoding */
-/* EVP_DecodedLength sets |*out_len| to the maximum number of bytes
- * that will be needed to call |EVP_DecodeBase64| on an input of
- * length |len|. */
+/* EVP_DecodedLength sets |*out_len| to the maximum number of bytes that will
+ * be needed to call |EVP_DecodeBase64| on an input of length |len|. It returns
+ * one on success or zero if |len| is not a valid length for a base64-encoded
+ * string. */
OPENSSL_EXPORT int EVP_DecodedLength(size_t *out_len, size_t len);
/* EVP_DecodeBase64 decodes |in_len| bytes from base64 and writes
* |*out_len| bytes to |out|. |max_out| is the size of the output
* buffer. If it is not enough for the maximum output size, the
- * operation fails. */
+ * operation fails. It returns one on success or zero on error. */
OPENSSL_EXPORT int EVP_DecodeBase64(uint8_t *out, size_t *out_len,
size_t max_out, const uint8_t *in,
size_t in_len);
@@ -105,9 +106,7 @@
*
* OpenSSL provides a streaming base64 implementation, however its behavior is
* very specific to PEM. It is also very lenient of invalid input. Use of any of
- * these functions is thus deprecated.
- *
- * TODO(davidben): Import upstream's rewrite that rejects the invalid input. */
+ * these functions is thus deprecated. */
/* EVP_EncodeInit initialises |*ctx|, which is typically stack
* allocated, for an encoding operation.
@@ -159,21 +158,25 @@
*
* WARNING: EVP_DecodeBlock's return value does not take padding into
* account. It also strips leading whitespace and trailing
- * whitespace. */
+ * whitespace and minuses. */
OPENSSL_EXPORT int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src,
size_t src_len);
struct evp_encode_ctx_st {
- unsigned num; /* number saved in a partial encode/decode */
- unsigned length; /* The length is either the output line length
- * (in input bytes) or the shortest input line
- * length that is ok. Once decoding begins,
- * the length is adjusted up each time a longer
- * line is decoded */
- uint8_t enc_data[80]; /* data to encode */
- unsigned line_num; /* number read on current line */
- int expect_nl;
+ /* data_used indicates the number of bytes of |data| that are valid. When
+ * encoding, |data| will be filled and encoded as a lump. When decoding, only
+ * the first four bytes of |data| will be used. */
+ unsigned data_used;
+ uint8_t data[48];
+
+ /* eof_seen indicates that the end of the base64 data has been seen when
+ * decoding. Only whitespace can follow. */
+ char eof_seen;
+
+ /* error_encountered indicates that invalid base64 data was found. This will
+ * cause all future calls to fail. */
+ char error_encountered;
};