Hello,
I apologize if my last question was too involved to test easily.
I've attached a new version of the test code that is much more direct in its use of a message digest.
The program opens /dev/zero and reads four bytes, one byte at a time, and after each byte retrieves the digest using BIO_gets().
As you can see from the output, the first digest is not equal to the following three.
Why is this? Am I misusing the BIO_gets() api? Is there an initial value injected into the BIO stream for digests that must be cleared before a first call to BIO_gets can be made?
Any help you can provide would be appreciated.
Thank you, Stephen.
$ gcc -o s_bio s_bio.c ./local/lib/libcrypto.a
$ ./s_bio read 1 byte(s): 00 hash: 93b885adfe0da089cdf634904fd59f71 hash: b0e641c998cc3eae6fa2f8726d98cddd read 1 byte(s): 00 hash: 013b1a00c5739a37fa9a5a89337ec241 hash: b0e641c998cc3eae6fa2f8726d98cddd read 1 byte(s): 00 hash: 013b1a00c5739a37fa9a5a89337ec241 hash: b0e641c998cc3eae6fa2f8726d98cddd read 1 byte(s): 00 hash: 013b1a00c5739a37fa9a5a89337ec241 hash: b0e641c998cc3eae6fa2f8726d98cddd
#include <openssl/evp.h>
#include <stdio.h>
int print_digest(BIO *b)
{
char digest[EVP_MAX_MD_SIZE];
int len;
int i;
memset(digest, 0, EVP_MAX_MD_SIZE);
len = BIO_gets(b, digest, EVP_MAX_MD_SIZE);
if ( len <= 0 )
{
fprintf(stderr, "error getting hash.\n");
return -1;
} else {
fprintf(stderr, "hash: ");
for (i=0; i < len; i++)
{
fprintf(stderr, "%02x", (unsigned char)digest[i]);
}
fprintf(stderr, "\n");
}
return 0;
}
int filter(char *input_file, int blocksize, int length)
{
BIO *bi = NULL;
BIO *digest=NULL;
int ret;
char *buf;
int l_read = 0;
int i;
buf = (char *)malloc(blocksize);
digest = BIO_new(BIO_f_md());
BIO_set_md(digest, EVP_md5());
/*BIO_set_md(digest, EVP_sha1());*/
/* INPUT */
bi = BIO_new_file(input_file, "r");
if ( bi == NULL)
{
fprintf(stderr, "bio new error\n");
return -1;
}
BIO_push(digest, bi);
bi = digest;
BIO_reset(digest);
while ( l_read < length )
{
ret = BIO_read(bi, buf, blocksize);
if ( ret > 0 )
{
fprintf(stderr, "read %d byte(s): ", ret);
for (i=0; i < ret; i++)
{
fprintf(stderr, "%02X", buf[i]);
}
fprintf(stderr, "\n");
/* Do stuff with input */
print_digest(digest);
print_digest(digest);
l_read += ret;
} else {
fprintf(stderr, "done reading: %d\n", ret);
break;
}
}
BIO_free_all(bi);
return 0;
}
int main(int argc, char **argv)
{
OpenSSL_add_all_algorithms();
if ( filter("/dev/zero", 1, 4) != 0 )
{
fprintf(stderr, "error:\n");
exit(1);
}
return 0;
}
