/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
 * applicable.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* This is derived from material copyright RSA Data Security, Inc.
 * Their notice is reproduced below in its entirety.
 *
 * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
 * rights reserved.
 *
 * RSA Data Security, Inc. makes no representations concerning either
 * the merchantability of this software or the suitability of this
 * software for any particular purpose. It is provided "as is"
 * without express or implied warranty of any kind.
 *
 * These notices must be retained in any copies of any part of this
 * documentation and/or software.
 */


#include "apr.h"
#include "apr_general.h"
#include "apr_file_io.h"
#include "apr_time.h"
#include "apr_md4.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*
 * This is a MD4 test program based on the code published in RFC 1320.
 * When run as ./testmd4 -x it should produce the following output:

MD4 test suite:
MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0
MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24
MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d
MD4 ("message digest") = d9130a8164549fe818874806e1c7014b
MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9
MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = 043f8582f241db351ce627e153e7f0e4
MD4 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536

*/

/* Length of test block, number of test blocks.
 */
#define TEST_BLOCK_LEN 1000
#define TEST_BLOCK_COUNT 1000

apr_pool_t *local_pool;
apr_file_t *in, *out, *err;

/* Prints a message digest in hexadecimal.
 */
static void MDPrint (unsigned char digest[APR_MD4_DIGESTSIZE])
{
    unsigned int i;

    for (i = 0; i < APR_MD4_DIGESTSIZE; i++)
        apr_file_printf(out, "%02x", digest[i]);
}

/* Digests a string and prints the result.
 */
static void MDString(char *string)
{
    apr_md4_ctx_t context;
    unsigned char digest[APR_MD4_DIGESTSIZE];
    unsigned int len = strlen(string);

    apr_md4_init(&context);
    apr_md4_update(&context, (unsigned char *)string, len);
    apr_md4_final(digest, &context);

    apr_file_printf (out, "MD4 (\"%s\") = ", string);
    MDPrint(digest);
    apr_file_printf (out, "\n");
}

/* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte
     blocks.
 */
static void MDTimeTrial(void)
{
    apr_md4_ctx_t context;
    apr_time_t endTime, startTime;
    apr_interval_time_t timeTaken;
    unsigned char block[TEST_BLOCK_LEN], digest[APR_MD4_DIGESTSIZE];
    unsigned int i;

    apr_file_printf(out, "MD4 time trial. Digesting %d %d-byte blocks ...", 
                     TEST_BLOCK_LEN, TEST_BLOCK_COUNT);

    /* Initialize block */
    for (i = 0; i < TEST_BLOCK_LEN; i++)
        block[i] = (unsigned char)(i & 0xff);

    /* Start timer */
    startTime = apr_time_now();

    /* Digest blocks */
    apr_md4_init(&context);
    for (i = 0; i < TEST_BLOCK_COUNT; i++)
        apr_md4_update(&context, block, TEST_BLOCK_LEN);

    apr_md4_final(digest, &context);

    /* Stop timer */
    endTime = apr_time_now();
    timeTaken = endTime - startTime;

    apr_file_printf(out, " done\n");
    apr_file_printf(out, "Digest = ");
    MDPrint(digest);

    apr_file_printf(out, "\nTime = %" APR_TIME_T_FMT " seconds\n", timeTaken);
    apr_file_printf(out, "Speed = % " APR_TIME_T_FMT " bytes/second\n",
                    TEST_BLOCK_LEN * TEST_BLOCK_COUNT/timeTaken);
}

/* Digests a reference suite of strings and prints the results.
 */
static void MDTestSuite(void)
{
    apr_file_printf(out, "MD4 test suite:\n");

    MDString("");
    MDString("a");
    MDString("abc");
    MDString("message digest");
    MDString("abcdefghijklmnopqrstuvwxyz");
    MDString("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
    MDString("12345678901234567890123456789012345678901234567890123456789012345678901234567890");
}

/* Digests a file and prints the result.
 */
static void MDFile(char *filename)
{
    apr_file_t *file;
    apr_md4_ctx_t context;
    apr_size_t len = 1024;
    unsigned char buffer[1024], digest[APR_MD4_DIGESTSIZE];

    if (apr_file_open(&file, filename, APR_READ, APR_OS_DEFAULT, local_pool) 
        != APR_SUCCESS)
        apr_file_printf(err, "%s can't be opened\n", filename);
    else {
        apr_md4_init(&context);
        while (apr_file_read(file, buffer, &len) != APR_SUCCESS)
        {
            apr_md4_update(&context, buffer, len);
            len = 1024;
        }
        apr_md4_final(digest, &context);

        apr_file_close(file);

        apr_file_printf(out, "MD4 (%s) = ", filename);
        MDPrint(digest);
        apr_file_printf(out, "\n");
    }
}

/* Digests the standard input and prints the result.
 */
static void MDFilter(void)
{
    apr_md4_ctx_t context;
    apr_size_t len = 16;
    unsigned char buffer[16], digest[16];

    apr_md4_init(&context);
    while (apr_file_read(in, buffer, &len) != APR_SUCCESS)
    {
        apr_md4_update(&context, buffer, len);
        len = 16;
    }
    apr_md4_update(&context, buffer, len);
    apr_md4_final(digest, &context);

    MDPrint(digest);
    apr_file_printf(out, "\n");
}


/* Main driver.

   Arguments (may be any combination):
     -sstring - digests string
     -t       - runs time trial
     -x       - runs test script
     filename - digests file
     (none)   - digests standard input
 */
int main (int argc, char **argv)
{
    int i;

    apr_initialize();
    atexit(apr_terminate);

    if (apr_pool_create(&local_pool, NULL) != APR_SUCCESS)
        exit(-1);

    apr_file_open_stdin(&in, local_pool); 
    apr_file_open_stdout(&out, local_pool); 
    apr_file_open_stderr(&err, local_pool); 

    if (argc > 1)
    {
        for (i = 1; i < argc; i++)
            if (argv[i][0] == '-' && argv[i][1] == 's')
                MDString(argv[i] + 2);
            else if (strcmp(argv[i], "-t") == 0)
                MDTimeTrial();
            else if (strcmp (argv[i], "-x") == 0)
                MDTestSuite();
            else
                MDFile(argv[i]);
    }
    else
        MDFilter();

    return 0;
}
