1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
/* 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;
}
|