提交 5562cfac 编写于 作者: D Dr. Stephen Henson

Base64 bio fixes. The base64 bio was seriously broken

when reading from a non blocking BIO.

It would incorrectly interpret retries as EOF, incorrectly
buffer initial data and have no buffering at all after initial
data (data would be sent one byte at a time to EVP_DecodeUpdate).
上级 c8252b71
...@@ -4,6 +4,11 @@ ...@@ -4,6 +4,11 @@
Changes between 0.9.7a and 0.9.8 [xx XXX xxxx] Changes between 0.9.7a and 0.9.8 [xx XXX xxxx]
*) Various fixes to base64 BIO and non blocking I/O. On write
flushes were not handled properly if the BIO retried. On read
data was not being buffered properly and had various logic bugs.
[Steve Henson]
*) Support for single pass processing for S/MIME signing. This now *) Support for single pass processing for S/MIME signing. This now
means that S/MIME signing can be done from a pipe, in addition means that S/MIME signing can be done from a pipe, in addition
cleartext signing (multipart/signed type) is effectively streaming cleartext signing (multipart/signed type) is effectively streaming
......
...@@ -184,7 +184,9 @@ static int b64_read(BIO *b, char *out, int outl) ...@@ -184,7 +184,9 @@ static int b64_read(BIO *b, char *out, int outl)
ret_code=0; ret_code=0;
while (outl > 0) while (outl > 0)
{ {
if (ctx->cont <= 0) break;
if (ctx->cont <= 0)
break;
i=BIO_read(b->next_bio,&(ctx->tmp[ctx->tmp_len]), i=BIO_read(b->next_bio,&(ctx->tmp[ctx->tmp_len]),
B64_BLOCK_SIZE-ctx->tmp_len); B64_BLOCK_SIZE-ctx->tmp_len);
...@@ -195,11 +197,21 @@ static int b64_read(BIO *b, char *out, int outl) ...@@ -195,11 +197,21 @@ static int b64_read(BIO *b, char *out, int outl)
/* Should be continue next time we are called? */ /* Should be continue next time we are called? */
if (!BIO_should_retry(b->next_bio)) if (!BIO_should_retry(b->next_bio))
{
ctx->cont=i; ctx->cont=i;
/* else we should continue when called again */ /* If buffer empty break */
break; if(ctx->tmp_len == 0)
break;
/* Fall through and process what we have */
else
i = 0;
}
/* else we retry and add more data to buffer */
else
break;
} }
i+=ctx->tmp_len; i+=ctx->tmp_len;
ctx->tmp_len = i;
/* We need to scan, a line at a time until we /* We need to scan, a line at a time until we
* have a valid line if we are starting. */ * have a valid line if we are starting. */
...@@ -255,8 +267,12 @@ static int b64_read(BIO *b, char *out, int outl) ...@@ -255,8 +267,12 @@ static int b64_read(BIO *b, char *out, int outl)
* reading until a new line. */ * reading until a new line. */
if (p == (unsigned char *)&(ctx->tmp[0])) if (p == (unsigned char *)&(ctx->tmp[0]))
{ {
ctx->tmp_nl=1; /* Check buffer full */
ctx->tmp_len=0; if (i == B64_BLOCK_SIZE)
{
ctx->tmp_nl=1;
ctx->tmp_len=0;
}
} }
else if (p != q) /* finished on a '\n' */ else if (p != q) /* finished on a '\n' */
{ {
...@@ -271,6 +287,11 @@ static int b64_read(BIO *b, char *out, int outl) ...@@ -271,6 +287,11 @@ static int b64_read(BIO *b, char *out, int outl)
else else
ctx->tmp_len=0; ctx->tmp_len=0;
} }
/* If buffer isn't full and we can retry then
* restart to read in more data.
*/
else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0))
continue;
if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)
{ {
...@@ -310,8 +331,8 @@ static int b64_read(BIO *b, char *out, int outl) ...@@ -310,8 +331,8 @@ static int b64_read(BIO *b, char *out, int outl)
i=EVP_DecodeUpdate(&(ctx->base64), i=EVP_DecodeUpdate(&(ctx->base64),
(unsigned char *)ctx->buf,&ctx->buf_len, (unsigned char *)ctx->buf,&ctx->buf_len,
(unsigned char *)ctx->tmp,i); (unsigned char *)ctx->tmp,i);
ctx->tmp_len = 0;
} }
ctx->cont=i;
ctx->buf_off=0; ctx->buf_off=0;
if (i < 0) if (i < 0)
{ {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册