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;
}


Reply via email to