summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2014-05-03 16:54:48 +0000
committerjsing <>2014-05-03 16:54:48 +0000
commit514338c77dd677946d110257af15041ce31eb6d0 (patch)
tree48c09265d52171990bb9e1d8b24d43333c3427cb /src/lib
parent15fbf8f546dc0fe5cb255e4cdcd53ea50d1bd327 (diff)
downloadopenbsd-514338c77dd677946d110257af15041ce31eb6d0.tar.gz
openbsd-514338c77dd677946d110257af15041ce31eb6d0.tar.bz2
openbsd-514338c77dd677946d110257af15041ce31eb6d0.zip
Add checks for invalid base64 encoded data, specifically relating to the
handling of padding. This fixes a crash that can be triggered by feeding base64 data followed by 64 or more padding characters, which results in a negative output length. This issue was reported by David Ramos, although the same bug has been sitting in the OpenSSL RT since 2011: https://rt.openssl.org/Ticket/Display.html?id=2608 Worse still, BIO_read seems to be completely unable to detect that the base64 input was invalid/corrupt - in particular, enabling BIO_FLAGS_BASE64_NO_NL results in a stream of zero value bytes rather than no input (possibly a good replacement for /dev/null...), which could result in nasty consequences. Prior to this fix some zero value bytes were also injected without this flag being enabled. The recently added base64 regress triggers and documents these issues (and also ensures that this change retains functional behaviour).
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/evp/encode.c12
-rw-r--r--src/lib/libssl/src/crypto/evp/encode.c12
2 files changed, 24 insertions, 0 deletions
diff --git a/src/lib/libcrypto/evp/encode.c b/src/lib/libcrypto/evp/encode.c
index 9540a849c9..2268b8d2f2 100644
--- a/src/lib/libcrypto/evp/encode.c
+++ b/src/lib/libcrypto/evp/encode.c
@@ -259,6 +259,12 @@ EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
259 goto end; 259 goto end;
260 } 260 }
261 261
262 /* There should not be base64 data after padding. */
263 if (eof && tmp != '=' && tmp != '\r' && tmp != '\n') {
264 rv = -1;
265 goto end;
266 }
267
262 /* have we seen a '=' which is 'definitely' the last 268 /* have we seen a '=' which is 'definitely' the last
263 * input line. seof will point to the character that 269 * input line. seof will point to the character that
264 * holds it. and eof will hold how many characters to 270 * holds it. and eof will hold how many characters to
@@ -269,6 +275,12 @@ EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
269 eof++; 275 eof++;
270 } 276 }
271 277
278 /* There should be no more than two padding markers. */
279 if (eof > 2) {
280 rv = -1;
281 goto end;
282 }
283
272 if (v == B64_CR) { 284 if (v == B64_CR) {
273 ln = 0; 285 ln = 0;
274 if (exp_nl) 286 if (exp_nl)
diff --git a/src/lib/libssl/src/crypto/evp/encode.c b/src/lib/libssl/src/crypto/evp/encode.c
index 9540a849c9..2268b8d2f2 100644
--- a/src/lib/libssl/src/crypto/evp/encode.c
+++ b/src/lib/libssl/src/crypto/evp/encode.c
@@ -259,6 +259,12 @@ EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
259 goto end; 259 goto end;
260 } 260 }
261 261
262 /* There should not be base64 data after padding. */
263 if (eof && tmp != '=' && tmp != '\r' && tmp != '\n') {
264 rv = -1;
265 goto end;
266 }
267
262 /* have we seen a '=' which is 'definitely' the last 268 /* have we seen a '=' which is 'definitely' the last
263 * input line. seof will point to the character that 269 * input line. seof will point to the character that
264 * holds it. and eof will hold how many characters to 270 * holds it. and eof will hold how many characters to
@@ -269,6 +275,12 @@ EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
269 eof++; 275 eof++;
270 } 276 }
271 277
278 /* There should be no more than two padding markers. */
279 if (eof > 2) {
280 rv = -1;
281 goto end;
282 }
283
272 if (v == B64_CR) { 284 if (v == B64_CR) {
273 ln = 0; 285 ln = 0;
274 if (exp_nl) 286 if (exp_nl)