/*******************************************************************-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:\n\t%s\n\n", (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): %s\n", 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() */
/* * sc_get_properlength(oid *hashtype, u_int hashtype_len): * * Given a hashing type ("hashtype" and its length hashtype_len), return * the length of the hash result. * * Returns either the length or SNMPERR_GENERR for an unknown hashing type. */ int sc_get_properlength(const oid * hashtype, u_int hashtype_len) { DEBUGTRACE; /* * Determine transform type hash length. */ if (ISTRANSFORM(hashtype, HMACMD5Auth)) { return BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5); } else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) { return BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1); } return SNMPERR_GENERR; }
/*******************************************************************-o-****** * test_docrypt * * Returns: * Number of failures. */ int test_docrypt(void) { int rval = SNMPERR_SUCCESS, failcount = 0, bigstring_len = strlen(BIGSTRING), secret_len = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES), iv_len = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV); u_int buf_len = LOCAL_MAXBUF, cryptbuf_len = LOCAL_MAXBUF; char buf[LOCAL_MAXBUF], cryptbuf[LOCAL_MAXBUF], secret[LOCAL_MAXBUF], iv[LOCAL_MAXBUF]; OUTPUT("Test 1DES-CBC --"); memset(buf, 0, LOCAL_MAXBUF); memcpy(secret, BIGSECRET, secret_len); memcpy(iv, BKWDSECRET, iv_len); rval = sc_encrypt(usmDESPrivProtocol, USM_LENGTH_OID_TRANSFORM, secret, secret_len, iv, iv_len, BIGSTRING, bigstring_len, cryptbuf, &cryptbuf_len); FAILED(rval, "sc_encrypt()."); rval = sc_decrypt(usmDESPrivProtocol, USM_LENGTH_OID_TRANSFORM, secret, secret_len, iv, iv_len, cryptbuf, cryptbuf_len, buf, &buf_len); FAILED(rval, "sc_decrypt()."); if (buf_len != bigstring_len) { FAILED(SNMPERR_GENERR, "Decrypted buffer is the wrong length."); } if (memcmp(buf, BIGSTRING, bigstring_len)) { FAILED(SNMPERR_GENERR, "Decrypted buffer is not equal to original plaintext."); } SUCCESS("Test 1DES-CBC --"); return failcount; } /* end test_docrypt() */
int sc_get_proper_priv_length(const oid * privtype, u_int privtype_len) { int properlength = 0; #ifndef NETSNMP_DISABLE_DES if (ISTRANSFORM(privtype, DESPriv)) { properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES); } #endif #ifdef HAVE_AES if (ISTRANSFORM(privtype, AESPriv)) { properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_AES); } #endif return properlength; }
/*-----------------------------------------------------------------------------*/ void PopulateCOMSettings(HWND hDlg) { char szBuffer[MAXLEN_TEMPSTR]; WORD wCount, wPosition; // Fill baud combo box and make initial selection FillComboBox(GetDlgItem(hDlg, IDC_BPS_COMBO), szBaud, BaudTable, sizeof(BaudTable) / sizeof(BaudTable[0]), BAUDRATE(TTYInfo)); // Fill data bits combo box and make initial selection for (wCount = 5; wCount < 9; wCount++) { wsprintf(szBuffer, "%d", wCount); wPosition = LOWORD(SendDlgItemMessage(hDlg, IDC_DATABITS_COMBO, CB_ADDSTRING, 0, (LPARAM)(LPSTR)szBuffer)); if (wCount == BYTESIZE(TTYInfo)) { SendDlgItemMessage(hDlg, IDC_DATABITS_COMBO, CB_SETCURSEL, (WPARAM)wPosition, 0L); } } // Fill parity combo box and make initial selection FillComboBox(GetDlgItem(hDlg, IDC_PARITY_COMBO), szParity, ParityTable, sizeof(ParityTable) / sizeof(ParityTable[0]), PARITY(TTYInfo)); // Fill stop bits combo box and make initial selection FillComboBox(GetDlgItem(hDlg, IDC_STOPBITS_COMBO), szStopBits, StopBitsTable, sizeof(StopBitsTable) / sizeof(StopBitsTable[0]), STOPBITS(TTYInfo)); }
/*-----------------------------------------------------------------------------*/ void UpdateTTYInfo(HWND hDlg) { GetDlgItemText(hDlg, IDC_COMPORT_COMBO, gszPort, sizeof(gszPort)); BAUDRATE(TTYInfo) = GetdwTTYITem(hDlg, IDC_BPS_COMBO, szBaud, BaudTable, sizeof(BaudTable) / sizeof(BaudTable[0])); PARITY(TTYInfo) = GetbTTYITem(hDlg, IDC_PARITY_COMBO, szParity, ParityTable, sizeof(ParityTable) / sizeof(ParityTable[0])); STOPBITS(TTYInfo) = GetbTTYITem(hDlg, IDC_STOPBITS_COMBO, szStopBits, StopBitsTable, sizeof(StopBitsTable) / sizeof(StopBitsTable[0])); BYTESIZE(TTYInfo) = GetDlgItemInt(hDlg, IDC_DATABITS_COMBO, NULL, FALSE); }
/*-----------------------------------------------------------------------------*/ void InitTTYInfo() { // Initialize general TTY info COMDEV(TTYInfo) = NULL; CONNECTED(TTYInfo) = FALSE; PORT(TTYInfo) = '0'; // setting to 0 since we know nothing about // the current COM port configuration BAUDRATE(TTYInfo) = CBR_9600; BYTESIZE(TTYInfo) = 8; PARITY(TTYInfo) = NOPARITY; STOPBITS(TTYInfo) = ONESTOPBIT; InitFont(); ClearTTYContents(); }
// Connects to, sets up and configures (if virgin) port. void commConnect() { DCB dcb; HMENU hMenu; // Make sure we're not connected if (!CONNECTED(TTYInfo)) { // Menu hMenu = GetMenu(ghWndMain); // get the menu handle EnableMenuItem(hMenu, ID_FILE_CONNECT, MF_GRAYED | MF_DISABLED); // disable the connect menu EnableMenuItem(hMenu, ID_FILE_DISCONNECT, MF_ENABLED); // enable the disconnect menu EnableMenuItem(hMenu, ID_EDIT_SETTINGS, MF_GRAYED | MF_DISABLED); // disable the TTY menu COMDEV(TTYInfo) = CreateFile(gszPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); FillMemory(&dcb, sizeof(dcb), 0); dcb.BaudRate = BAUDRATE(TTYInfo); // set the baud rate dcb.ByteSize = BYTESIZE(TTYInfo); // set the data bits dcb.fParity = PARITY(TTYInfo); // set the parity dcb.StopBits = STOPBITS(TTYInfo); // set the stop bits SetCommState(COMDEV(TTYInfo), &dcb); // update the COM port configuration CONNECTED(TTYInfo) = TRUE; // we are now connected (hopefully) } // Start reading thread TTYInfo.hThread = CreateThread( NULL, // security attributes 0, // inital thread stack size, in bytes commReadThread, // address of thread function ghWndTerm, // argument for new thread 0, // creation flags &TTYInfo.hThread ); // address of returned thread ID TTYInfo.fConnected = TRUE; }
_SCAPI_NOT_CONFIGURED #endif /* USE_INTERNAL_MD5 */ /*******************************************************************-o-****** * sc_encrypt * * Parameters: * privtype Type of privacy cryptographic transform. * *key Key bits for crypting. * keylen Length of key (buffer) in bytes. * *iv IV bits for crypting. * ivlen Length of iv (buffer) in bytes. * *plaintext Plaintext to crypt. * ptlen Length of plaintext. * *ciphertext Ciphertext to crypt. * *ctlen Length of ciphertext. * * Returns: * SNMPERR_SUCCESS Success. * SNMPERR_SC_NOT_CONFIGURED Encryption is not supported. * SNMPERR_SC_GENERAL_FAILURE Any other error * * * Encrypt plaintext into ciphertext using key and iv. * * ctlen contains actual number of crypted bytes in ciphertext upon * successful return. */ int sc_encrypt( oid *privtype, size_t privtypelen, u_char *key, u_int keylen, u_char *iv, u_int ivlen, u_char *plaintext, u_int ptlen, u_char *ciphertext, size_t *ctlen) #if defined(USE_OPENSSL) { int rval = SNMPERR_SUCCESS; u_int transform, properlength, properlength_iv; u_char pad_block[32]; /* bigger than anything I need */ u_char my_iv[32]; /* ditto */ int pad, plast, pad_size; des_key_schedule key_sch; des_cblock key_struct; DEBUGTRACE; /* * Sanity check. */ #if !defined(SCAPI_AUTHPRIV) return SNMPERR_SC_NOT_CONFIGURED; #endif if ( !privtype || !key || !iv || !plaintext || !ciphertext || !ctlen || (keylen<=0) || (ivlen<=0) || (ptlen<=0) || (*ctlen<=0) || (privtypelen != USM_LENGTH_OID_TRANSFORM) ) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } else if ( ptlen >= *ctlen) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } #ifdef SNMP_TESTING_CODE { char buf[SNMP_MAXBUF]; sprint_hexstring(buf, iv, ivlen); DEBUGMSGTL(("scapi", "encrypt: IV: %s/ ", buf)); sprint_hexstring(buf, key, keylen); DEBUGMSG(("scapi","%s\n", buf)); sprint_hexstring(buf, plaintext, 16); DEBUGMSGTL(("scapi","encrypt: string: %s\n", buf)); } #endif /* SNMP_TESTING_CODE */ /* * Determine privacy transform. */ if ( ISTRANSFORM(privtype, DESPriv) ) { properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES); properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV); pad_size = properlength; } else { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } if ( (keylen<properlength) || (ivlen<properlength_iv) ) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } else if ( (keylen<properlength) || (ivlen<properlength_iv) ) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } /* now calculate the padding needed */ pad = pad_size - (ptlen % pad_size); if (ptlen + pad > *ctlen) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); /* not enough space */ } memset(pad_block, 0, sizeof(pad_block)); plast = (int) ptlen - (pad_size - pad); if (pad > 0) /* copy data into pad block if needed */ memcpy( pad_block, plaintext + plast, pad_size - pad); memset(&pad_block[pad_size-pad], pad, pad); /* filling in padblock */ memset(my_iv, 0, sizeof(my_iv)); if ( ISTRANSFORM(privtype, DESPriv) ) { memcpy(key_struct, key, sizeof(key_struct)); (void) des_key_sched(&key_struct, key_sch); memcpy(my_iv, iv, ivlen); /* encrypt the data */ des_ncbc_encrypt(plaintext, ciphertext, plast, key_sch, (des_cblock *) &my_iv, DES_ENCRYPT); /* then encrypt the pad block */ des_ncbc_encrypt(pad_block, ciphertext+plast, pad_size, key_sch, (des_cblock *)&my_iv, DES_ENCRYPT); *ctlen = plast + pad_size; } sc_encrypt_quit: /* clear memory just in case */ memset(my_iv, 0, sizeof(my_iv)); memset(pad_block, 0, sizeof(pad_block)); memset(key_struct, 0, sizeof(key_struct)); memset(key_sch, 0, sizeof(key_sch)); return rval; } /* end sc_encrypt() */
/*******************************************************************-o-****** * test_dokeyedhash * * Returns: * Number of failures. * * * Test keyed hashes with a variety of MAC length requests. * * * NOTE Both tests intentionally use the same secret * * FIX Get input or output from some other package which hashes... * XXX Could cut this in half with a little indirection... */ int test_dokeyedhash(void) { int rval = SNMPERR_SUCCESS, failcount = 0, bigstring_len = strlen(BIGSTRING), secret_len = strlen(BIGSECRET), properlength, mlcount = 0, /* MAC Length count. */ hblen; /* Hash Buffer length. */ u_int hashbuf_len[MLCOUNT_MAX] = { LOCAL_MAXBUF, BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1), BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5), BYTESIZE(SNMP_TRANS_AUTHLEN_HMAC96), 7, 0, }; u_char hashbuf[LOCAL_MAXBUF]; char *s; test_dokeyedhash_again: OUTPUT("Keyed hash test using MD5 --"); memset(hashbuf, 0, LOCAL_MAXBUF); hblen = hashbuf_len[mlcount]; properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5); rval = sc_generate_keyed_hash(usmHMACMD5AuthProtocol, USM_LENGTH_OID_TRANSFORM, BIGSECRET, secret_len, BIGSTRING, bigstring_len, hashbuf, &hblen); FAILED(rval, "sc_generate_keyed_hash()."); if (hashbuf_len[mlcount] > properlength) { if (hblen != properlength) { FAILED(SNMPERR_GENERR, "Wrong MD5 hash length returned. (1)"); } } else if (hblen != hashbuf_len[mlcount]) { FAILED(SNMPERR_GENERR, "Wrong MD5 hash length returned. (2)"); } rval = sc_check_keyed_hash(usmHMACMD5AuthProtocol, USM_LENGTH_OID_TRANSFORM, BIGSECRET, secret_len, BIGSTRING, bigstring_len, hashbuf, hblen); FAILED(rval, "sc_check_keyed_hash()."); binary_to_hex(hashbuf, hblen, &s); fprintf(stdout, "hash buffer (len=%d, request=%d): %s\n", hblen, hashbuf_len[mlcount], s); SNMP_FREE(s); SUCCESS("Keyed hash test using MD5."); OUTPUT("Keyed hash test using SHA1 --"); memset(hashbuf, 0, LOCAL_MAXBUF); hblen = hashbuf_len[mlcount]; properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1); rval = sc_generate_keyed_hash(usmHMACSHA1AuthProtocol, USM_LENGTH_OID_TRANSFORM, BIGSECRET, secret_len, BIGSTRING, bigstring_len, hashbuf, &hblen); FAILED(rval, "sc_generate_keyed_hash()."); if (hashbuf_len[mlcount] > properlength) { if (hblen != properlength) { FAILED(SNMPERR_GENERR, "Wrong SHA1 hash length returned. (1)"); } } else if (hblen != hashbuf_len[mlcount]) { FAILED(SNMPERR_GENERR, "Wrong SHA1 hash length returned. (2)"); } rval = sc_check_keyed_hash(usmHMACSHA1AuthProtocol, USM_LENGTH_OID_TRANSFORM, BIGSECRET, secret_len, BIGSTRING, bigstring_len, hashbuf, hblen); FAILED(rval, "sc_check_keyed_hash()."); binary_to_hex(hashbuf, hblen, &s); fprintf(stdout, "hash buffer (len=%d, request=%d): %s\n", hblen, hashbuf_len[mlcount], s); SNMP_FREE(s); SUCCESS("Keyed hash test using SHA1."); /* * Run the basic hash tests but vary the size MAC requests. */ if (hashbuf_len[++mlcount] != 0) { goto test_dokeyedhash_again; } return failcount; } /* end test_dokeyedhash() */
_SCAPI_NOT_CONFIGURED #endif /* NETSNMP_USE_INTERNAL_MD5 */ /*******************************************************************-o-****** * sc_encrypt * * Parameters: * privtype Type of privacy cryptographic transform. * *key Key bits for crypting. * keylen Length of key (buffer) in bytes. * *iv IV bits for crypting. * ivlen Length of iv (buffer) in bytes. * *plaintext Plaintext to crypt. * ptlen Length of plaintext. * *ciphertext Ciphertext to crypt. * *ctlen Length of ciphertext. * * Returns: * SNMPERR_SUCCESS Success. * SNMPERR_SC_NOT_CONFIGURED Encryption is not supported. * SNMPERR_SC_GENERAL_FAILURE Any other error * * * Encrypt plaintext into ciphertext using key and iv. * * ctlen contains actual number of crypted bytes in ciphertext upon * successful return. */ int sc_encrypt(const oid * privtype, size_t privtypelen, u_char * key, u_int keylen, u_char * iv, u_int ivlen, u_char * plaintext, u_int ptlen, u_char * ciphertext, size_t * ctlen) #if defined(NETSNMP_USE_OPENSSL) { int rval = SNMPERR_SUCCESS; u_int properlength = 0, properlength_iv = 0; u_char pad_block[128]; /* bigger than anything I need */ u_char my_iv[128]; /* ditto */ int pad, plast, pad_size = 0; int have_trans; #ifndef NETSNMP_DISABLE_DES #ifdef OLD_DES DES_key_schedule key_sch; #else DES_key_schedule key_sched_store; DES_key_schedule *key_sch = &key_sched_store; #endif DES_cblock key_struct; #endif #ifdef HAVE_AES AES_KEY aes_key; int new_ivlen = 0; #endif DEBUGTRACE; /* * Sanity check. */ #if !defined(NETSNMP_ENABLE_SCAPI_AUTHPRIV) snmp_log(LOG_ERR, "Encryption support not enabled.\n"); return SNMPERR_SC_NOT_CONFIGURED; #endif if (!privtype || !key || !iv || !plaintext || !ciphertext || !ctlen || (keylen <= 0) || (ivlen <= 0) || (ptlen <= 0) || (*ctlen <= 0) || (privtypelen != USM_LENGTH_OID_TRANSFORM)) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } else if (ptlen > *ctlen) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } #ifdef NETSNMP_ENABLE_TESTING_CODE { size_t buf_len = 128, out_len = 0; u_char *buf = (u_char *) malloc(buf_len); if (buf != NULL) { if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1, iv, ivlen)) { DEBUGMSGTL(("scapi", "encrypt: IV: %s/", buf)); } else { DEBUGMSGTL(("scapi", "encrypt: IV: %s [TRUNCATED]/", buf)); } out_len = 0; if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1, key, keylen)) { DEBUGMSG(("scapi", "%s\n", buf)); } else { DEBUGMSG(("scapi", "%s [TRUNCATED]\n", buf)); } out_len = 0; if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1, plaintext, 16)) { DEBUGMSGTL(("scapi", "encrypt: string: %s\n", buf)); } else { DEBUGMSGTL(("scapi", "encrypt: string: %s [TRUNCATED]\n", buf)); } free(buf); } else { DEBUGMSGTL(("scapi", "encrypt: malloc fail for debug output\n")); } } #endif /* NETSNMP_ENABLE_TESTING_CODE */ /* * Determine privacy transform. */ have_trans = 0; #ifndef NETSNMP_DISABLE_DES if (ISTRANSFORM(privtype, DESPriv)) { properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES); properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV); pad_size = properlength; have_trans = 1; } #endif #ifdef HAVE_AES if (ISTRANSFORM(privtype, AESPriv)) { properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_AES); properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_AES_IV); have_trans = 1; } #endif if (!have_trans) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } if ((keylen < properlength) || (ivlen < properlength_iv)) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); } memset(my_iv, 0, sizeof(my_iv)); #ifndef NETSNMP_DISABLE_DES if (ISTRANSFORM(privtype, DESPriv)) { /* * now calculate the padding needed */ pad = pad_size - (ptlen % pad_size); plast = (int) ptlen - (pad_size - pad); if (pad == pad_size) pad = 0; if (ptlen + pad > *ctlen) { QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); /* not enough space */ } if (pad > 0) { /* copy data into pad block if needed */ memcpy(pad_block, plaintext + plast, pad_size - pad); memset(&pad_block[pad_size - pad], pad, pad); /* filling in padblock */ } memcpy(key_struct, key, sizeof(key_struct)); (void) DES_key_sched(&key_struct, key_sch); memcpy(my_iv, iv, ivlen); /* * encrypt the data */ DES_ncbc_encrypt(plaintext, ciphertext, plast, key_sch, (DES_cblock *) my_iv, DES_ENCRYPT); if (pad > 0) { /* * then encrypt the pad block */ DES_ncbc_encrypt(pad_block, ciphertext + plast, pad_size, key_sch, (DES_cblock *) my_iv, DES_ENCRYPT); *ctlen = plast + pad_size; } else { *ctlen = plast; } } #endif #ifdef HAVE_AES if (ISTRANSFORM(privtype, AESPriv)) { (void) AES_set_encrypt_key(key, properlength*8, &aes_key); memcpy(my_iv, iv, ivlen); /* * encrypt the data */ AES_cfb128_encrypt(plaintext, ciphertext, ptlen, &aes_key, my_iv, &new_ivlen, AES_ENCRYPT); *ctlen = ptlen; } #endif sc_encrypt_quit: /* * clear memory just in case */ memset(my_iv, 0, sizeof(my_iv)); memset(pad_block, 0, sizeof(pad_block)); #ifndef NETSNMP_DISABLE_DES memset(key_struct, 0, sizeof(key_struct)); #ifdef OLD_DES memset(&key_sch, 0, sizeof(key_sch)); #else memset(&key_sched_store, 0, sizeof(key_sched_store)); #endif #endif #ifdef HAVE_AES memset(&aes_key,0,sizeof(aes_key)); #endif return rval; } /* end sc_encrypt() */
/*******************************************************************-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): %s\n", (isdefault_old) ? " (default)" : "", properlength, s); SNMP_FREE(s); binary_to_hex(newkey_buf, properlength, &s); fprintf(stdout, "newkey%s (len=%d): %s\n\n", (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: %s\n\n", ((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: %s\n\n", 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() */
/*******************************************************************-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:\n\t%s\n\n", (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): %s\n\n", (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, "\n\nMaster Ku using \"%s\":\n\t%s\n\n", 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): %s\n", ((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() */