keymanagetest.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:16k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  * keymanagetest.c
  3.  *
  4.  * Expected SUCCESSes:  2 + 2 + 3 for all tests.
  5.  *
  6.  * Returns:
  7.  *      Number of FAILUREs.
  8.  * 
  9.  *
  10.  * FIX  Or how about passing a usmUser name and looking up the entry as
  11.  *      a means of getting key material?  This means the userList is
  12.  *      available from an application...
  13.  *
  14.  * ASSUMES  No key management functions return non-zero success codes.
  15.  *
  16.  * Test of generate_Ku().                       SUCCESSes: 2
  17.  * Test of generate_kul().                      SUCCESSes: 2
  18.  * Test of {encode,decode}_keychange().         SUCCESSes: 3
  19.  */
  20. static char    *rcsid = "$Id: keymanagetest.c,v 5.0 2002/04/20 07:30:22 hardaker Exp $";        /* */
  21. #include <net-snmp/net-snmp-config.h>
  22. #include <stdio.h>
  23. #ifdef HAVE_NETINET_IN_H
  24. #include <netinet/in.h>
  25. #endif
  26. #include "asn1.h"
  27. #include "snmp_api.h"
  28. #include "keytools.h"
  29. #include "tools.h"
  30. #include "scapi.h"
  31. #include "transform_oids.h"
  32. #include "callback.h"
  33. #include <stdlib.h>
  34. extern char    *optarg;
  35. extern int      optind, optopt, opterr;
  36. /*
  37.  * Globals, &c...
  38.  */
  39. char           *local_progname;
  40. #define USAGE "Usage: %s [-h][-aklu][-E <engineID>][-N <newkey>][-O <oldkey>][-P <passphrase>]"
  41. #define OPTIONLIST "aqE:hklN:O:P:u"
  42. int             doalltests = 0, dogenKu = 0, dogenkul = 0, dokeychange = 0;
  43. #define ALLOPTIONS (doalltests + dogenKu + dogenkul + dokeychange)
  44. #define LOCAL_MAXBUF (1024 * 8)
  45. #define NL "n"
  46. #define OUTPUTALWAYS(o) fprintf(stdout, "nn%snn", o);
  47. #define OUTPUT(o) if (!bequiet) { OUTPUTALWAYS(o); }
  48. #define SUCCESS(s)
  49. {
  50. if (!failcount && !bequiet)
  51. fprintf(stdout, "nSUCCESS: %sn", s);
  52. }
  53. #define FAILED(e, f)
  54. {
  55. if (e != SNMPERR_SUCCESS && !bequiet) {
  56. fprintf(stdout, "nFAILED: %sn", f);
  57. failcount += 1;
  58. }
  59. }
  60. /*
  61.  * Test specific globals.
  62.  */
  63. #define ENGINEID_DEFAULT "1.2.3.4wild"
  64. #define PASSPHRASE_DEFAULT "Clay's Conclusion: Creativity is great, " 
  65. "but plagiarism is faster."
  66. #define OLDKEY_DEFAULT "This is a very old key."
  67. #define NEWKEY_DEFAULT "This key, on the other hand, is very new."
  68. char           *engineID = NULL;
  69. char           *passphrase = NULL;
  70. char           *oldkey = NULL;
  71. char           *newkey = NULL;
  72. int             bequiet = 0;
  73. /*
  74.  * Prototypes.
  75.  */
  76. void            usage(FILE * ofp);
  77. int             test_genkul(void);
  78. int             test_genKu(void);
  79. int             test_keychange(void);
  80. int
  81. main(int argc, char **argv)
  82. {
  83.     int             rval = SNMPERR_SUCCESS, failcount = 0;
  84.     char            ch;
  85.     local_progname = argv[0];
  86.     optarg = NULL;
  87.     /*
  88.      * Parse.
  89.      */
  90.     while ((ch = getopt(argc, argv, OPTIONLIST)) != EOF) {
  91.         switch (ch) {
  92.         case 'a':
  93.             doalltests = 1;
  94.             break;
  95.         case 'E':
  96.             engineID = optarg;
  97.             break;
  98.         case 'k':
  99.             dokeychange = 1;
  100.             break;
  101.         case 'l':
  102.             dogenkul = 1;
  103.             break;
  104.         case 'N':
  105.             newkey = optarg;
  106.             break;
  107.         case 'O':
  108.             oldkey = optarg;
  109.             break;
  110.         case 'P':
  111.             passphrase = optarg;
  112.             break;
  113.         case 'u':
  114.             dogenKu = 1;
  115.             break;
  116.         case 'q':
  117.             bequiet = 1;
  118.             break;
  119.         case 'h':
  120.             rval = 0;
  121.         default:
  122.             usage(stdout);
  123.             exit(rval);
  124.         }
  125.         argc -= 1;
  126.         argv += 1;
  127.         if (optarg) {
  128.             argc -= 1;
  129.             argv += 1;
  130.         }
  131.         optind = 1;
  132.         optarg = NULL;
  133.     }                           /* endwhile getopt */
  134.     if ((argc > 1)) {
  135.         usage(stdout);
  136.         exit(1000);
  137.     } else if (ALLOPTIONS != 1) {
  138.         usage(stdout);
  139.         exit(1000);
  140.     }
  141.     /*
  142.      * Test stuff.
  143.      */
  144.     rval = sc_init();
  145.     FAILED(rval, "sc_init().");
  146.     if (dogenKu || doalltests) {
  147.         failcount += test_genKu();
  148.     }
  149.     if (dogenkul || doalltests) {
  150.         failcount += test_genkul();
  151.     }
  152.     if (dokeychange || doalltests) {
  153.         failcount += test_keychange();
  154.     }
  155.     /*
  156.      * Cleanup.
  157.      */
  158.     rval = sc_shutdown(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN,
  159.                        NULL, NULL);
  160.     FAILED(rval, "sc_shutdown().");
  161.     return failcount;
  162. }                               /* end main() */
  163. void
  164. usage(FILE * ofp)
  165. {
  166.     fprintf(ofp,
  167.             USAGE
  168.             "" NL
  169.             "    -a All tests." NL
  170.             "    -E [0x]<engineID> snmpEngineID string."
  171.             NL
  172.             "    -k Test {encode,decode}_keychange()."
  173.             NL
  174.             "    -l generate_kul()."
  175.             NL
  176.             "    -h Help."
  177.             NL
  178.             "    -N [0x]<newkey> New key (for testing KeyChange TC)."
  179.             NL
  180.             "    -O [0x]<oldkey> Old key (for testing KeyChange TC)."
  181.             NL
  182.             "    -P <passphrase> Source string for usmUser master key."
  183.             NL
  184.             "    -u generate_Ku()."
  185.             NL
  186.             "    -q be quiet."
  187.             NL "" NL, local_progname);
  188. }                               /* end usage() */
  189. #ifdef EXAMPLE
  190. /*******************************************************************-o-******
  191.  * test_dosomething
  192.  *
  193.  * Test template.
  194.  *
  195.  * Returns:
  196.  * Number of failures.
  197.  */
  198. int
  199. test_dosomething(void)
  200. {
  201.     int             rval = SNMPERR_SUCCESS, failcount = 0;
  202.     EM0(1, "UNIMPLEMENTED");    /* EM(1); /* */
  203.   test_dosomething_quit:
  204.     return failcount;
  205. }                               /* end test_dosomething() */
  206. #endif                          /* EXAMPLE */
  207. /*******************************************************************-o-******
  208.  * test_genKu
  209.  *
  210.  * Returns:
  211.  * Number of failures.
  212.  *
  213.  *
  214.  * Test generation of usmUser master key from a passphrase.
  215.  *
  216.  * ASSUMES  Passphrase is made of printable characters!
  217.  */
  218. int
  219. test_genKu(void)
  220. {
  221.     int             rval = SNMPERR_SUCCESS,
  222.         failcount = 0,
  223.         properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5), kulen;
  224.     char           *hashname = "usmHMACMD5AuthProtocol.", *s;
  225.     u_char          Ku[LOCAL_MAXBUF];
  226.     oid            *hashtype = usmHMACMD5AuthProtocol;
  227.     OUTPUT("Test of generate_Ku --");
  228.     /*
  229.      * Set passphrase.
  230.      */
  231.     if (!passphrase) {
  232.         passphrase = PASSPHRASE_DEFAULT;
  233.     }
  234.     if (!bequiet)
  235.         fprintf(stdout, "Passphrase%s:nt%snn",
  236.                 (passphrase == PASSPHRASE_DEFAULT) ? " (default)" : "",
  237.                 passphrase);
  238.   test_genKu_again:
  239.     memset(Ku, 0, LOCAL_MAXBUF);
  240.     kulen = LOCAL_MAXBUF;
  241.     rval = generate_Ku(hashtype, USM_LENGTH_OID_TRANSFORM,
  242.                        passphrase, strlen(passphrase), Ku, &kulen);
  243.     FAILED(rval, "generate_Ku().");
  244.     if (kulen != properlength) {
  245.         FAILED(SNMPERR_GENERR, "Ku length is wrong for this hashtype.");
  246.     }
  247.     binary_to_hex(Ku, kulen, &s);
  248.     if (!bequiet)
  249.         fprintf(stdout, "Ku (len=%d):  %sn", kulen, s);
  250.     free_zero(s, kulen);
  251.     SUCCESS(hashname);
  252.     if (!bequiet)
  253.         fprintf(stdout, "n");
  254.     if (hashtype == usmHMACMD5AuthProtocol) {
  255.         hashtype = usmHMACSHA1AuthProtocol;
  256.         hashname = "usmHMACSHA1AuthProtocol.";
  257.         properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
  258.         goto test_genKu_again;
  259.     }
  260.     return failcount;
  261. }                               /* end test_genKu() */
  262. /*******************************************************************-o-******
  263.  * test_genkul
  264.  *
  265.  * Returns:
  266.  * Number of failures.
  267.  *
  268.  *
  269.  * Test of generate_kul().
  270.  *
  271.  * A passphrase and engineID are hashed into a master key Ku using
  272.  * both known hash transforms.  Localized keys, also using both hash
  273.  * transforms, are generated from each of these master keys.
  274.  *
  275.  * ASSUME  generate_Ku is already tested.
  276.  * ASSUME  engineID is initially a NULL terminated string.
  277.  */
  278. int
  279. test_genkul(void)
  280. {
  281.     int             rval = SNMPERR_SUCCESS,
  282.         failcount = 0,
  283.         properlength, kulen, kul_len, engineID_len, isdefault = FALSE;
  284.     char           *s = NULL,
  285.         *testname = "Using HMACMD5 to create master key.",
  286.         *hashname_Ku = "usmHMACMD5AuthProtocol", *hashname_kul;
  287.     u_char          Ku[LOCAL_MAXBUF], kul[LOCAL_MAXBUF];
  288.     oid            *hashtype_Ku = usmHMACMD5AuthProtocol, *hashtype_kul;
  289.     OUTPUT("Test of generate_kul --");
  290.     /*
  291.      * Set passphrase and engineID.
  292.      *
  293.      * If engineID begins with 0x, assume it is written in (printable)
  294.      * hex and convert it to binary data.
  295.      */
  296.     if (!passphrase) {
  297.         passphrase = PASSPHRASE_DEFAULT;
  298.     }
  299.     if (!bequiet)
  300.         fprintf(stdout, "Passphrase%s:nt%snn",
  301.                 (passphrase == PASSPHRASE_DEFAULT) ? " (default)" : "",
  302.                 passphrase);
  303.     if (!engineID) {
  304.         engineID = ENGINEID_DEFAULT;
  305.         isdefault = TRUE;
  306.     }
  307.     engineID_len = strlen(engineID);
  308.     if (tolower(*(engineID + 1)) == 'x') {
  309.         engineID_len = hex_to_binary2(engineID + 2, engineID_len - 2, &s);
  310.         if (engineID_len < 0) {
  311.             FAILED((rval = SNMPERR_GENERR),
  312.                    "Could not resolve hex engineID.");
  313.         }
  314.         engineID = s;
  315.         binary_to_hex(engineID, engineID_len, &s);
  316.     }
  317.     if (!bequiet)
  318.         fprintf(stdout, "engineID%s (len=%d):  %snn",
  319.                 (isdefault) ? " (default)" : "",
  320.                 engineID_len, (s) ? s : engineID);
  321.     if (s) {
  322.         SNMP_FREE(s);
  323.     }
  324.     /*
  325.      * Create a master key using both hash transforms; create localized
  326.      * keys using both hash transforms from each master key.
  327.      */
  328.   test_genkul_again_master:
  329.     memset(Ku, 0, LOCAL_MAXBUF);
  330.     kulen = LOCAL_MAXBUF;
  331.     hashname_kul = "usmHMACMD5AuthProtocol";
  332.     hashtype_kul = usmHMACMD5AuthProtocol;
  333.     properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5);
  334.     rval = generate_Ku(hashtype_Ku, USM_LENGTH_OID_TRANSFORM,
  335.                        passphrase, strlen(passphrase), Ku, &kulen);
  336.     FAILED(rval, "generate_Ku().");
  337.     binary_to_hex(Ku, kulen, &s);
  338.     if (!bequiet)
  339.         fprintf(stdout,
  340.                 "nnMaster Ku using "%s":nt%snn", hashname_Ku, s);
  341.     free_zero(s, kulen);
  342.   test_genkul_again_local:
  343.     memset(kul, 0, LOCAL_MAXBUF);
  344.     kul_len = LOCAL_MAXBUF;
  345.     rval = generate_kul(hashtype_kul, USM_LENGTH_OID_TRANSFORM,
  346.                         engineID, engineID_len, Ku, kulen, kul, &kul_len);
  347.     if ((hashtype_Ku == usmHMACMD5AuthProtocol)
  348.         && (hashtype_kul == usmHMACSHA1AuthProtocol)) {
  349.         if (rval == SNMPERR_SUCCESS) {
  350.             FAILED(SNMPERR_GENERR,
  351.                    "generate_kul SHOULD fail when Ku length is "
  352.                    "less than hash transform length.");
  353.         }
  354.     } else {
  355.         FAILED(rval, "generate_kul().");
  356.         if (kul_len != properlength) {
  357.             FAILED(SNMPERR_GENERR,
  358.                    "kul length is wrong for the given hashtype.");
  359.         }
  360.         binary_to_hex(kul, kul_len, &s);
  361.         fprintf(stdout, "kul (%s) (len=%d):  %sn",
  362.                 ((hashtype_Ku == usmHMACMD5AuthProtocol) ? "MD5" : "SHA"),
  363.                 kul_len, s);
  364.         free_zero(s, kul_len);
  365.     }
  366.     /*
  367.      * Create localized key using the other hash transform, but from
  368.      * * the same master key.
  369.      */
  370.     if (hashtype_kul == usmHMACMD5AuthProtocol) {
  371.         hashtype_kul = usmHMACSHA1AuthProtocol;
  372.         hashname_kul = "usmHMACSHA1AuthProtocol";
  373.         properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
  374.         goto test_genkul_again_local;
  375.     }
  376.     SUCCESS(testname);
  377.     /*
  378.      * Re-create the master key using the other hash transform.
  379.      */
  380.     if (hashtype_Ku == usmHMACMD5AuthProtocol) {
  381.         hashtype_Ku = usmHMACSHA1AuthProtocol;
  382.         hashname_Ku = "usmHMACSHA1AuthProtocol";
  383.         testname = "Using HMACSHA1 to create master key.";
  384.         goto test_genkul_again_master;
  385.     }
  386.     return failcount;
  387. }                               /* end test_genkul() */
  388. /*******************************************************************-o-******
  389.  * test_keychange
  390.  *
  391.  * Returns:
  392.  * Number of failures.
  393.  *
  394.  *
  395.  * Test of KeyChange TC implementation.
  396.  *
  397.  * ASSUME newkey and oldkey begin as NULL terminated strings.
  398.  */
  399. int
  400. test_keychange(void)
  401. {
  402.     int             rval = SNMPERR_SUCCESS,
  403.         failcount = 0,
  404.         properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5),
  405.         oldkey_len,
  406.         newkey_len,
  407.         keychange_len,
  408.         temp_len, isdefault_new = FALSE, isdefault_old = FALSE;
  409.     char           *hashname = "usmHMACMD5AuthProtocol.", *s;
  410.     u_char          oldkey_buf[LOCAL_MAXBUF],
  411.         newkey_buf[LOCAL_MAXBUF],
  412.         temp_buf[LOCAL_MAXBUF], keychange_buf[LOCAL_MAXBUF];
  413.     oid            *hashtype = usmHMACMD5AuthProtocol;
  414.     OUTPUT("Test of KeyChange TC --");
  415.     /*
  416.      * Set newkey and oldkey.
  417.      */
  418.     if (!newkey) {              /* newkey */
  419.         newkey = NEWKEY_DEFAULT;
  420.         isdefault_new = TRUE;
  421.     }
  422.     newkey_len = strlen(newkey);
  423.     if (tolower(*(newkey + 1)) == 'x') {
  424.         newkey_len = hex_to_binary2(newkey + 2, newkey_len - 2, &s);
  425.         if (newkey_len < 0) {
  426.             FAILED((rval = SNMPERR_GENERR),
  427.                    "Could not resolve hex newkey.");
  428.         }
  429.         newkey = s;
  430.         binary_to_hex(newkey, newkey_len, &s);
  431.     }
  432.     if (!oldkey) {              /* oldkey */
  433.         oldkey = OLDKEY_DEFAULT;
  434.         isdefault_old = TRUE;
  435.     }
  436.     oldkey_len = strlen(oldkey);
  437.     if (tolower(*(oldkey + 1)) == 'x') {
  438.         oldkey_len = hex_to_binary2(oldkey + 2, oldkey_len - 2, &s);
  439.         if (oldkey_len < 0) {
  440.             FAILED((rval = SNMPERR_GENERR),
  441.                    "Could not resolve hex oldkey.");
  442.         }
  443.         oldkey = s;
  444.         binary_to_hex(oldkey, oldkey_len, &s);
  445.     }
  446.   test_keychange_again:
  447.     memset(oldkey_buf, 0, LOCAL_MAXBUF);
  448.     memset(newkey_buf, 0, LOCAL_MAXBUF);
  449.     memset(keychange_buf, 0, LOCAL_MAXBUF);
  450.     memset(temp_buf, 0, LOCAL_MAXBUF);
  451.     memcpy(oldkey_buf, oldkey, SNMP_MIN(oldkey_len, properlength));
  452.     memcpy(newkey_buf, newkey, SNMP_MIN(newkey_len, properlength));
  453.     keychange_len = LOCAL_MAXBUF;
  454.     binary_to_hex(oldkey_buf, properlength, &s);
  455.     fprintf(stdout, "noldkey%s (len=%d):  %sn",
  456.             (isdefault_old) ? " (default)" : "", properlength, s);
  457.     SNMP_FREE(s);
  458.     binary_to_hex(newkey_buf, properlength, &s);
  459.     fprintf(stdout, "newkey%s (len=%d):  %snn",
  460.             (isdefault_new) ? " (default)" : "", properlength, s);
  461.     SNMP_FREE(s);
  462.     rval = encode_keychange(hashtype, USM_LENGTH_OID_TRANSFORM,
  463.                             oldkey_buf, properlength,
  464.                             newkey_buf, properlength,
  465.                             keychange_buf, &keychange_len);
  466.     FAILED(rval, "encode_keychange().");
  467.     if (keychange_len != (properlength * 2)) {
  468.         FAILED(SNMPERR_GENERR,
  469.                "KeyChange string (encoded) is not proper length "
  470.                "for this hash transform.");
  471.     }
  472.     binary_to_hex(keychange_buf, keychange_len, &s);
  473.     fprintf(stdout, "(%s) KeyChange string:  %snn",
  474.             ((hashtype == usmHMACMD5AuthProtocol) ? "MD5" : "SHA"), s);
  475.     SNMP_FREE(s);
  476.     temp_len = properlength;
  477.     rval = decode_keychange(hashtype, USM_LENGTH_OID_TRANSFORM,
  478.                             oldkey_buf, properlength,
  479.                             keychange_buf, properlength * 2,
  480.                             temp_buf, &temp_len);
  481.     FAILED(rval, "decode_keychange().");
  482.     if (temp_len != properlength) {
  483.         FAILED(SNMPERR_GENERR,
  484.                "decoded newkey is not proper length for "
  485.                "this hash transform.");
  486.     }
  487.     binary_to_hex(temp_buf, temp_len, &s);
  488.     fprintf(stdout, "decoded newkey:  %snn", s);
  489.     SNMP_FREE(s);
  490.     if (memcmp(newkey_buf, temp_buf, temp_len)) {
  491.         FAILED(SNMPERR_GENERR, "newkey did not decode properly.");
  492.     }
  493.     SUCCESS(hashname);
  494.     fprintf(stdout, "n");
  495.     /*
  496.      * Multiplex different test combinations.
  497.      *
  498.      * First clause is for Test #2, second clause is for (last) Test #3.
  499.      */
  500.     if (hashtype == usmHMACMD5AuthProtocol) {
  501.         hashtype = usmHMACSHA1AuthProtocol;
  502.         hashname = "usmHMACSHA1AuthProtocol (w/DES length kul's).";
  503.         properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES)
  504.             + BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
  505.         goto test_keychange_again;
  506.     } else if (properlength < BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1)) {
  507.         hashtype = usmHMACSHA1AuthProtocol;
  508.         hashname = "usmHMACSHA1AuthProtocol.";
  509.         properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
  510.         goto test_keychange_again;
  511.     }
  512.     return failcount;
  513. }                               /* end test_keychange() */