keymanagetest.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:16k
- /*
- * keymanagetest.c
- *
- * Expected SUCCESSes: 2 + 2 + 3 for all tests.
- *
- * Returns:
- * Number of FAILUREs.
- *
- *
- * FIX Or how about passing a usmUser name and looking up the entry as
- * a means of getting key material? This means the userList is
- * available from an application...
- *
- * ASSUMES No key management functions return non-zero success codes.
- *
- * Test of generate_Ku(). SUCCESSes: 2
- * Test of generate_kul(). SUCCESSes: 2
- * Test of {encode,decode}_keychange(). SUCCESSes: 3
- */
- static char *rcsid = "$Id: keymanagetest.c,v 5.0 2002/04/20 07:30:22 hardaker Exp $"; /* */
- #include <net-snmp/net-snmp-config.h>
- #include <stdio.h>
- #ifdef HAVE_NETINET_IN_H
- #include <netinet/in.h>
- #endif
- #include "asn1.h"
- #include "snmp_api.h"
- #include "keytools.h"
- #include "tools.h"
- #include "scapi.h"
- #include "transform_oids.h"
- #include "callback.h"
- #include <stdlib.h>
- extern char *optarg;
- extern int optind, optopt, opterr;
- /*
- * Globals, &c...
- */
- char *local_progname;
- #define USAGE "Usage: %s [-h][-aklu][-E <engineID>][-N <newkey>][-O <oldkey>][-P <passphrase>]"
- #define OPTIONLIST "aqE:hklN:O:P:u"
- int doalltests = 0, dogenKu = 0, dogenkul = 0, dokeychange = 0;
- #define ALLOPTIONS (doalltests + dogenKu + dogenkul + dokeychange)
- #define LOCAL_MAXBUF (1024 * 8)
- #define NL "n"
- #define OUTPUTALWAYS(o) fprintf(stdout, "nn%snn", o);
- #define OUTPUT(o) if (!bequiet) { OUTPUTALWAYS(o); }
- #define SUCCESS(s)
- {
- if (!failcount && !bequiet)
- fprintf(stdout, "nSUCCESS: %sn", s);
- }
- #define FAILED(e, f)
- {
- if (e != SNMPERR_SUCCESS && !bequiet) {
- fprintf(stdout, "nFAILED: %sn", f);
- failcount += 1;
- }
- }
- /*
- * Test specific globals.
- */
- #define ENGINEID_DEFAULT "1.2.3.4wild"
- #define PASSPHRASE_DEFAULT "Clay's Conclusion: Creativity is great, "
- "but plagiarism is faster."
- #define OLDKEY_DEFAULT "This is a very old key."
- #define NEWKEY_DEFAULT "This key, on the other hand, is very new."
- char *engineID = NULL;
- char *passphrase = NULL;
- char *oldkey = NULL;
- char *newkey = NULL;
- int bequiet = 0;
- /*
- * Prototypes.
- */
- void usage(FILE * ofp);
- int test_genkul(void);
- int test_genKu(void);
- int test_keychange(void);
- int
- main(int argc, char **argv)
- {
- int rval = SNMPERR_SUCCESS, failcount = 0;
- char ch;
- local_progname = argv[0];
- optarg = NULL;
- /*
- * Parse.
- */
- while ((ch = getopt(argc, argv, OPTIONLIST)) != EOF) {
- switch (ch) {
- case 'a':
- doalltests = 1;
- break;
- case 'E':
- engineID = optarg;
- break;
- case 'k':
- dokeychange = 1;
- break;
- case 'l':
- dogenkul = 1;
- break;
- case 'N':
- newkey = optarg;
- break;
- case 'O':
- oldkey = optarg;
- break;
- case 'P':
- passphrase = optarg;
- break;
- case 'u':
- dogenKu = 1;
- break;
- case 'q':
- bequiet = 1;
- break;
- case 'h':
- rval = 0;
- default:
- usage(stdout);
- exit(rval);
- }
- argc -= 1;
- argv += 1;
- if (optarg) {
- argc -= 1;
- argv += 1;
- }
- optind = 1;
- optarg = NULL;
- } /* endwhile getopt */
- if ((argc > 1)) {
- usage(stdout);
- exit(1000);
- } else if (ALLOPTIONS != 1) {
- usage(stdout);
- exit(1000);
- }
- /*
- * Test stuff.
- */
- rval = sc_init();
- FAILED(rval, "sc_init().");
- if (dogenKu || doalltests) {
- failcount += test_genKu();
- }
- if (dogenkul || doalltests) {
- failcount += test_genkul();
- }
- if (dokeychange || doalltests) {
- failcount += test_keychange();
- }
- /*
- * Cleanup.
- */
- rval = sc_shutdown(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN,
- NULL, NULL);
- FAILED(rval, "sc_shutdown().");
- return failcount;
- } /* end main() */
- void
- usage(FILE * ofp)
- {
- fprintf(ofp,
- USAGE
- "" NL
- " -a All tests." NL
- " -E [0x]<engineID> snmpEngineID string."
- NL
- " -k Test {encode,decode}_keychange()."
- NL
- " -l generate_kul()."
- NL
- " -h Help."
- NL
- " -N [0x]<newkey> New key (for testing KeyChange TC)."
- NL
- " -O [0x]<oldkey> Old key (for testing KeyChange TC)."
- NL
- " -P <passphrase> Source string for usmUser master key."
- NL
- " -u generate_Ku()."
- NL
- " -q be quiet."
- NL "" NL, local_progname);
- } /* end usage() */
- #ifdef EXAMPLE
- /*******************************************************************-o-******
- * test_dosomething
- *
- * Test template.
- *
- * Returns:
- * Number of failures.
- */
- int
- test_dosomething(void)
- {
- int rval = SNMPERR_SUCCESS, failcount = 0;
- EM0(1, "UNIMPLEMENTED"); /* EM(1); /* */
- test_dosomething_quit:
- return failcount;
- } /* end test_dosomething() */
- #endif /* EXAMPLE */
- /*******************************************************************-o-******
- * test_genKu
- *
- * Returns:
- * Number of failures.
- *
- *
- * Test generation of usmUser master key from a passphrase.
- *
- * ASSUMES Passphrase is made of printable characters!
- */
- int
- test_genKu(void)
- {
- int rval = SNMPERR_SUCCESS,
- failcount = 0,
- properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5), kulen;
- char *hashname = "usmHMACMD5AuthProtocol.", *s;
- u_char Ku[LOCAL_MAXBUF];
- oid *hashtype = usmHMACMD5AuthProtocol;
- OUTPUT("Test of generate_Ku --");
- /*
- * Set passphrase.
- */
- if (!passphrase) {
- passphrase = PASSPHRASE_DEFAULT;
- }
- if (!bequiet)
- fprintf(stdout, "Passphrase%s:nt%snn",
- (passphrase == PASSPHRASE_DEFAULT) ? " (default)" : "",
- passphrase);
- test_genKu_again:
- memset(Ku, 0, LOCAL_MAXBUF);
- kulen = LOCAL_MAXBUF;
- rval = generate_Ku(hashtype, USM_LENGTH_OID_TRANSFORM,
- passphrase, strlen(passphrase), Ku, &kulen);
- FAILED(rval, "generate_Ku().");
- if (kulen != properlength) {
- FAILED(SNMPERR_GENERR, "Ku length is wrong for this hashtype.");
- }
- binary_to_hex(Ku, kulen, &s);
- if (!bequiet)
- fprintf(stdout, "Ku (len=%d): %sn", kulen, s);
- free_zero(s, kulen);
- SUCCESS(hashname);
- if (!bequiet)
- fprintf(stdout, "n");
- if (hashtype == usmHMACMD5AuthProtocol) {
- hashtype = usmHMACSHA1AuthProtocol;
- hashname = "usmHMACSHA1AuthProtocol.";
- properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
- goto test_genKu_again;
- }
- return failcount;
- } /* end test_genKu() */
- /*******************************************************************-o-******
- * test_genkul
- *
- * Returns:
- * Number of failures.
- *
- *
- * Test of generate_kul().
- *
- * A passphrase and engineID are hashed into a master key Ku using
- * both known hash transforms. Localized keys, also using both hash
- * transforms, are generated from each of these master keys.
- *
- * ASSUME generate_Ku is already tested.
- * ASSUME engineID is initially a NULL terminated string.
- */
- int
- test_genkul(void)
- {
- int rval = SNMPERR_SUCCESS,
- failcount = 0,
- properlength, kulen, kul_len, engineID_len, isdefault = FALSE;
- char *s = NULL,
- *testname = "Using HMACMD5 to create master key.",
- *hashname_Ku = "usmHMACMD5AuthProtocol", *hashname_kul;
- u_char Ku[LOCAL_MAXBUF], kul[LOCAL_MAXBUF];
- oid *hashtype_Ku = usmHMACMD5AuthProtocol, *hashtype_kul;
- OUTPUT("Test of generate_kul --");
- /*
- * Set passphrase and engineID.
- *
- * If engineID begins with 0x, assume it is written in (printable)
- * hex and convert it to binary data.
- */
- if (!passphrase) {
- passphrase = PASSPHRASE_DEFAULT;
- }
- if (!bequiet)
- fprintf(stdout, "Passphrase%s:nt%snn",
- (passphrase == PASSPHRASE_DEFAULT) ? " (default)" : "",
- passphrase);
- if (!engineID) {
- engineID = ENGINEID_DEFAULT;
- isdefault = TRUE;
- }
- engineID_len = strlen(engineID);
- if (tolower(*(engineID + 1)) == 'x') {
- engineID_len = hex_to_binary2(engineID + 2, engineID_len - 2, &s);
- if (engineID_len < 0) {
- FAILED((rval = SNMPERR_GENERR),
- "Could not resolve hex engineID.");
- }
- engineID = s;
- binary_to_hex(engineID, engineID_len, &s);
- }
- if (!bequiet)
- fprintf(stdout, "engineID%s (len=%d): %snn",
- (isdefault) ? " (default)" : "",
- engineID_len, (s) ? s : engineID);
- if (s) {
- SNMP_FREE(s);
- }
- /*
- * Create a master key using both hash transforms; create localized
- * keys using both hash transforms from each master key.
- */
- test_genkul_again_master:
- memset(Ku, 0, LOCAL_MAXBUF);
- kulen = LOCAL_MAXBUF;
- hashname_kul = "usmHMACMD5AuthProtocol";
- hashtype_kul = usmHMACMD5AuthProtocol;
- properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5);
- rval = generate_Ku(hashtype_Ku, USM_LENGTH_OID_TRANSFORM,
- passphrase, strlen(passphrase), Ku, &kulen);
- FAILED(rval, "generate_Ku().");
- binary_to_hex(Ku, kulen, &s);
- if (!bequiet)
- fprintf(stdout,
- "nnMaster Ku using "%s":nt%snn", hashname_Ku, s);
- free_zero(s, kulen);
- test_genkul_again_local:
- memset(kul, 0, LOCAL_MAXBUF);
- kul_len = LOCAL_MAXBUF;
- rval = generate_kul(hashtype_kul, USM_LENGTH_OID_TRANSFORM,
- engineID, engineID_len, Ku, kulen, kul, &kul_len);
- if ((hashtype_Ku == usmHMACMD5AuthProtocol)
- && (hashtype_kul == usmHMACSHA1AuthProtocol)) {
- if (rval == SNMPERR_SUCCESS) {
- FAILED(SNMPERR_GENERR,
- "generate_kul SHOULD fail when Ku length is "
- "less than hash transform length.");
- }
- } else {
- FAILED(rval, "generate_kul().");
- if (kul_len != properlength) {
- FAILED(SNMPERR_GENERR,
- "kul length is wrong for the given hashtype.");
- }
- binary_to_hex(kul, kul_len, &s);
- fprintf(stdout, "kul (%s) (len=%d): %sn",
- ((hashtype_Ku == usmHMACMD5AuthProtocol) ? "MD5" : "SHA"),
- kul_len, s);
- free_zero(s, kul_len);
- }
- /*
- * Create localized key using the other hash transform, but from
- * * the same master key.
- */
- if (hashtype_kul == usmHMACMD5AuthProtocol) {
- hashtype_kul = usmHMACSHA1AuthProtocol;
- hashname_kul = "usmHMACSHA1AuthProtocol";
- properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
- goto test_genkul_again_local;
- }
- SUCCESS(testname);
- /*
- * Re-create the master key using the other hash transform.
- */
- if (hashtype_Ku == usmHMACMD5AuthProtocol) {
- hashtype_Ku = usmHMACSHA1AuthProtocol;
- hashname_Ku = "usmHMACSHA1AuthProtocol";
- testname = "Using HMACSHA1 to create master key.";
- goto test_genkul_again_master;
- }
- return failcount;
- } /* end test_genkul() */
- /*******************************************************************-o-******
- * test_keychange
- *
- * Returns:
- * Number of failures.
- *
- *
- * Test of KeyChange TC implementation.
- *
- * ASSUME newkey and oldkey begin as NULL terminated strings.
- */
- int
- test_keychange(void)
- {
- int rval = SNMPERR_SUCCESS,
- failcount = 0,
- properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5),
- oldkey_len,
- newkey_len,
- keychange_len,
- temp_len, isdefault_new = FALSE, isdefault_old = FALSE;
- char *hashname = "usmHMACMD5AuthProtocol.", *s;
- u_char oldkey_buf[LOCAL_MAXBUF],
- newkey_buf[LOCAL_MAXBUF],
- temp_buf[LOCAL_MAXBUF], keychange_buf[LOCAL_MAXBUF];
- oid *hashtype = usmHMACMD5AuthProtocol;
- OUTPUT("Test of KeyChange TC --");
- /*
- * Set newkey and oldkey.
- */
- if (!newkey) { /* newkey */
- newkey = NEWKEY_DEFAULT;
- isdefault_new = TRUE;
- }
- newkey_len = strlen(newkey);
- if (tolower(*(newkey + 1)) == 'x') {
- newkey_len = hex_to_binary2(newkey + 2, newkey_len - 2, &s);
- if (newkey_len < 0) {
- FAILED((rval = SNMPERR_GENERR),
- "Could not resolve hex newkey.");
- }
- newkey = s;
- binary_to_hex(newkey, newkey_len, &s);
- }
- if (!oldkey) { /* oldkey */
- oldkey = OLDKEY_DEFAULT;
- isdefault_old = TRUE;
- }
- oldkey_len = strlen(oldkey);
- if (tolower(*(oldkey + 1)) == 'x') {
- oldkey_len = hex_to_binary2(oldkey + 2, oldkey_len - 2, &s);
- if (oldkey_len < 0) {
- FAILED((rval = SNMPERR_GENERR),
- "Could not resolve hex oldkey.");
- }
- oldkey = s;
- binary_to_hex(oldkey, oldkey_len, &s);
- }
- test_keychange_again:
- memset(oldkey_buf, 0, LOCAL_MAXBUF);
- memset(newkey_buf, 0, LOCAL_MAXBUF);
- memset(keychange_buf, 0, LOCAL_MAXBUF);
- memset(temp_buf, 0, LOCAL_MAXBUF);
- memcpy(oldkey_buf, oldkey, SNMP_MIN(oldkey_len, properlength));
- memcpy(newkey_buf, newkey, SNMP_MIN(newkey_len, properlength));
- keychange_len = LOCAL_MAXBUF;
- binary_to_hex(oldkey_buf, properlength, &s);
- fprintf(stdout, "noldkey%s (len=%d): %sn",
- (isdefault_old) ? " (default)" : "", properlength, s);
- SNMP_FREE(s);
- binary_to_hex(newkey_buf, properlength, &s);
- fprintf(stdout, "newkey%s (len=%d): %snn",
- (isdefault_new) ? " (default)" : "", properlength, s);
- SNMP_FREE(s);
- rval = encode_keychange(hashtype, USM_LENGTH_OID_TRANSFORM,
- oldkey_buf, properlength,
- newkey_buf, properlength,
- keychange_buf, &keychange_len);
- FAILED(rval, "encode_keychange().");
- if (keychange_len != (properlength * 2)) {
- FAILED(SNMPERR_GENERR,
- "KeyChange string (encoded) is not proper length "
- "for this hash transform.");
- }
- binary_to_hex(keychange_buf, keychange_len, &s);
- fprintf(stdout, "(%s) KeyChange string: %snn",
- ((hashtype == usmHMACMD5AuthProtocol) ? "MD5" : "SHA"), s);
- SNMP_FREE(s);
- temp_len = properlength;
- rval = decode_keychange(hashtype, USM_LENGTH_OID_TRANSFORM,
- oldkey_buf, properlength,
- keychange_buf, properlength * 2,
- temp_buf, &temp_len);
- FAILED(rval, "decode_keychange().");
- if (temp_len != properlength) {
- FAILED(SNMPERR_GENERR,
- "decoded newkey is not proper length for "
- "this hash transform.");
- }
- binary_to_hex(temp_buf, temp_len, &s);
- fprintf(stdout, "decoded newkey: %snn", s);
- SNMP_FREE(s);
- if (memcmp(newkey_buf, temp_buf, temp_len)) {
- FAILED(SNMPERR_GENERR, "newkey did not decode properly.");
- }
- SUCCESS(hashname);
- fprintf(stdout, "n");
- /*
- * Multiplex different test combinations.
- *
- * First clause is for Test #2, second clause is for (last) Test #3.
- */
- if (hashtype == usmHMACMD5AuthProtocol) {
- hashtype = usmHMACSHA1AuthProtocol;
- hashname = "usmHMACSHA1AuthProtocol (w/DES length kul's).";
- properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES)
- + BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
- goto test_keychange_again;
- } else if (properlength < BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1)) {
- hashtype = usmHMACSHA1AuthProtocol;
- hashname = "usmHMACSHA1AuthProtocol.";
- properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
- goto test_keychange_again;
- }
- return failcount;
- } /* end test_keychange() */