4 * Expected SUCCESSes: 2 + 10 + 1 for all tests.
10 * ASSUMES No key management functions return non-zero success codes.
12 * XXX Split into individual modules?
13 * XXX Error/fringe conditions should be tested.
16 * Test of sc_random. SUCCESSes: 2.
17 * REQUIRES a human to spot check for obvious non-randomness...
19 * Test of sc_generate_keyed_hash and sc_check_keyed_hash. SUCCESSes: 10.
21 * Test of sc_encrypt and sc_decrypt. SUCCESSes: 1.
24 static char *rcsid = "$Id: scapitest.c,v 1.1.1.1 2005/04/29 01:45:23 echo Exp $"; /* */
27 #include <net-snmp/net-snmp-config.h>
30 #ifdef HAVE_NETINET_IN_H
31 #include <netinet/in.h>
39 #include "transform_oids.h"
45 extern int optind, optopt, opterr;
56 #define USAGE "Usage: %s [-h][-acHr]"
57 #define OPTIONLIST "achHr"
59 int doalltests = 0, docrypt = 0, dokeyedhash = 0, dorandom = 0;
61 #define ALLOPTIONS (doalltests + docrypt + dokeyedhash + dorandom)
65 #define LOCAL_MAXBUF (1024 * 8)
68 #define OUTPUT(o) fprintf(stdout, "\n\n%s\n\n", o);
73 fprintf(stdout, "\nSUCCESS: %s\n", s); \
76 #define FAILED(e, f) \
78 if (e != SNMPERR_SUCCESS) { \
79 fprintf(stdout, "\nFAILED: %s\n", f); \
86 " A port may be a pleasant retreat for any mind grown weary of" \
87 "the struggle for existence. The vast expanse of sky, the" \
88 "mobile architecture of the clouds, the chameleon coloration" \
89 "of the sea, the beacons flashing on the shore, together make" \
90 "a prism which is marvellously calculated to entertain but not" \
91 "fatigue the eye. The lofty ships with their complex webs of" \
92 "rigging, swayed to and fro by the swell in harmonious dance," \
93 "all help to maintain a taste for rhythm and beauty in the" \
94 "mind. And above all there is a mysterious, aristrocratic kind" \
95 "of pleasure to be had, for those who have lost all curiosity" \
96 "or ambition, as they strech on the belvedere or lean over the" \
97 "mole to watch the arrivals and departures of other men, those" \
98 "who still have sufficient strength of purpose in them, the" \
99 "urge to travel or enrich themselves." \
101 " From _The_Poems_in_Prose_, \"The Port\" (XLI)."
103 #define BIGSECRET "Shhhh... Don't tell *anyone* about this. Not a soul."
104 #define BKWDSECRET ".luos a toN .siht tuoba *enoyna* llet t'noD ...hhhhS"
106 #define MLCOUNT_MAX 6 /* MAC Length Count Maximum. */
113 void usage(FILE * ofp);
115 int test_docrypt(void);
116 int test_dokeyedhash(void);
117 int test_dorandom(void);
123 main(int argc, char **argv)
125 int rval = SNMPERR_SUCCESS, failcount = 0;
128 local_progname = argv[0];
133 while ((ch = getopt(argc, argv, OPTIONLIST)) != EOF) {
157 } /* endwhile getopt */
163 } else if (ALLOPTIONS != 1) {
173 FAILED(rval, "sc_init().");
176 if (docrypt || doalltests) {
177 failcount += test_docrypt();
179 if (dokeyedhash || doalltests) {
180 failcount += test_dokeyedhash();
182 if (dorandom || doalltests) {
183 failcount += test_dorandom();
190 rval = sc_shutdown(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN,
192 FAILED(rval, "sc_shutdown().");
209 " -c Test of sc_encrypt()/sc_decrypt()."
213 " -H Test sc_{generate,check}_keyed_hash()."
215 " -r Test sc_random()."
216 NL "" NL, local_progname);
224 /*******************************************************************-o-******
230 * Number of failures.
233 test_dosomething(void)
235 int rval = SNMPERR_SUCCESS, failcount = 0;
237 EM0(1, "UNIMPLEMENTED"); /* EM(1); /* */
239 test_dosomething_quit:
242 } /* end test_dosomething() */
249 /*******************************************************************-o-******
252 * One large request, one set of short requests.
255 * Number of failures.
257 * XXX probably should split up into individual options.
262 int rval = SNMPERR_SUCCESS,
264 origrequest = (1024 * 2),
265 origrequest_short = 19, nbytes = origrequest, shortcount = 7, i;
266 char buf[LOCAL_MAXBUF];
268 OUTPUT("Random test -- large request:");
270 rval = sc_random(buf, &nbytes);
271 FAILED(rval, "sc_random().");
273 if (nbytes != origrequest) {
274 FAILED(SNMPERR_GENERR,
275 "sc_random() returned different than requested.");
278 dump_chunk("scapitest", NULL, buf, nbytes);
280 SUCCESS("Random test -- large request.");
283 OUTPUT("Random test -- short requests:");
284 origrequest_short = 16;
286 for (i = 0; i < shortcount; i++) {
287 nbytes = origrequest_short;
288 rval = sc_random(buf, &nbytes);
289 FAILED(rval, "sc_random().");
291 if (nbytes != origrequest_short) {
292 FAILED(SNMPERR_GENERR,
293 "sc_random() returned different " "than requested.");
296 dump_chunk("scapitest", NULL, buf, nbytes);
299 SUCCESS("Random test -- short requests.");
304 } /* end test_dorandom() */
308 /*******************************************************************-o-******
312 * Number of failures.
315 * Test keyed hashes with a variety of MAC length requests.
318 * NOTE Both tests intentionally use the same secret
320 * FIX Get input or output from some other package which hashes...
321 * XXX Could cut this in half with a little indirection...
324 test_dokeyedhash(void)
326 int rval = SNMPERR_SUCCESS, failcount = 0, bigstring_len = strlen(BIGSTRING), secret_len = strlen(BIGSECRET), properlength, mlcount = 0, /* MAC Length count. */
327 hblen; /* Hash Buffer length. */
329 u_int hashbuf_len[MLCOUNT_MAX] = {
331 BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1),
332 BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5),
333 BYTESIZE(SNMP_TRANS_AUTHLEN_HMAC96),
338 u_char hashbuf[LOCAL_MAXBUF];
341 test_dokeyedhash_again:
343 OUTPUT("Keyed hash test using MD5 --");
345 memset(hashbuf, 0, LOCAL_MAXBUF);
346 hblen = hashbuf_len[mlcount];
347 properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5);
350 sc_generate_keyed_hash(usmHMACMD5AuthProtocol,
351 USM_LENGTH_OID_TRANSFORM, BIGSECRET,
352 secret_len, BIGSTRING, bigstring_len,
354 FAILED(rval, "sc_generate_keyed_hash().");
356 if (hashbuf_len[mlcount] > properlength) {
357 if (hblen != properlength) {
358 FAILED(SNMPERR_GENERR, "Wrong MD5 hash length returned. (1)");
361 } else if (hblen != hashbuf_len[mlcount]) {
362 FAILED(SNMPERR_GENERR, "Wrong MD5 hash length returned. (2)");
366 sc_check_keyed_hash(usmHMACMD5AuthProtocol,
367 USM_LENGTH_OID_TRANSFORM, BIGSECRET,
368 secret_len, BIGSTRING, bigstring_len, hashbuf,
370 FAILED(rval, "sc_check_keyed_hash().");
372 binary_to_hex(hashbuf, hblen, &s);
373 fprintf(stdout, "hash buffer (len=%d, request=%d): %s\n",
374 hblen, hashbuf_len[mlcount], s);
377 SUCCESS("Keyed hash test using MD5.");
381 OUTPUT("Keyed hash test using SHA1 --");
383 memset(hashbuf, 0, LOCAL_MAXBUF);
384 hblen = hashbuf_len[mlcount];
385 properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
388 sc_generate_keyed_hash(usmHMACSHA1AuthProtocol,
389 USM_LENGTH_OID_TRANSFORM, BIGSECRET,
390 secret_len, BIGSTRING, bigstring_len,
392 FAILED(rval, "sc_generate_keyed_hash().");
394 if (hashbuf_len[mlcount] > properlength) {
395 if (hblen != properlength) {
396 FAILED(SNMPERR_GENERR,
397 "Wrong SHA1 hash length returned. (1)");
400 } else if (hblen != hashbuf_len[mlcount]) {
401 FAILED(SNMPERR_GENERR, "Wrong SHA1 hash length returned. (2)");
405 sc_check_keyed_hash(usmHMACSHA1AuthProtocol,
406 USM_LENGTH_OID_TRANSFORM, BIGSECRET,
407 secret_len, BIGSTRING, bigstring_len, hashbuf,
409 FAILED(rval, "sc_check_keyed_hash().");
411 binary_to_hex(hashbuf, hblen, &s);
412 fprintf(stdout, "hash buffer (len=%d, request=%d): %s\n",
413 hblen, hashbuf_len[mlcount], s);
416 SUCCESS("Keyed hash test using SHA1.");
421 * Run the basic hash tests but vary the size MAC requests.
423 if (hashbuf_len[++mlcount] != 0) {
424 goto test_dokeyedhash_again;
430 } /* end test_dokeyedhash() */
436 /*******************************************************************-o-******
440 * Number of failures.
445 int rval = SNMPERR_SUCCESS,
447 bigstring_len = strlen(BIGSTRING),
448 secret_len = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES),
449 iv_len = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
451 u_int buf_len = LOCAL_MAXBUF, cryptbuf_len = LOCAL_MAXBUF;
453 char buf[LOCAL_MAXBUF],
454 cryptbuf[LOCAL_MAXBUF], secret[LOCAL_MAXBUF], iv[LOCAL_MAXBUF];
456 OUTPUT("Test 1DES-CBC --");
459 memset(buf, 0, LOCAL_MAXBUF);
461 memcpy(secret, BIGSECRET, secret_len);
462 memcpy(iv, BKWDSECRET, iv_len);
465 rval = sc_encrypt(usmDESPrivProtocol, USM_LENGTH_OID_TRANSFORM,
468 BIGSTRING, bigstring_len, cryptbuf, &cryptbuf_len);
469 FAILED(rval, "sc_encrypt().");
471 rval = sc_decrypt(usmDESPrivProtocol, USM_LENGTH_OID_TRANSFORM,
473 iv, iv_len, cryptbuf, cryptbuf_len, buf, &buf_len);
474 FAILED(rval, "sc_decrypt().");
476 if (buf_len != bigstring_len) {
477 FAILED(SNMPERR_GENERR, "Decrypted buffer is the wrong length.");
479 if (memcmp(buf, BIGSTRING, bigstring_len)) {
480 FAILED(SNMPERR_GENERR,
481 "Decrypted buffer is not equal to original plaintext.");
485 SUCCESS("Test 1DES-CBC --");
489 } /* end test_docrypt() */