static void MD5PassWord2Key(u_char *pwBytes, int pwLength, u_char *engineBytes, int engineLength, u_char *key) { MD5_CTX MD; u_char *cp, buffer[64]; int i, index = 0, count = 0; TnmMD5Init(&MD); while (count < 1048576) { cp = buffer; for(i = 0; i < 64; i++) { *cp++ = pwBytes[index++ % pwLength]; } TnmMD5Update(&MD, buffer, 64); count += 64; } TnmMD5Final(key, &MD); memcpy(buffer, key, 16); memcpy(buffer + 16, engineBytes, (size_t) engineLength); memcpy(buffer + 16 + engineLength, key, 16); TnmMD5Init(&MD); TnmMD5Update(&MD, buffer, 16 + engineLength + 16); TnmMD5Final(key, &MD); }
static void MD5AuthOutMsg(char *authKey, u_char *msg, int msgLen, u_char *msgAuthenticationParameters) { MD5_CTX MD; unsigned char extendedAuthKey[64]; unsigned char digest[16]; int i; memset(msgAuthenticationParameters, 0, 12); memcpy(extendedAuthKey, authKey, 16); for (i = 1; i < 64; i++) { extendedAuthKey[i] = extendedAuthKey[i] ^ 0x36; } TnmMD5Init(&MD); TnmMD5Update(&MD, extendedAuthKey, 64); TnmMD5Update(&MD, msg, msgLen); TnmMD5Final(digest, &MD); for (i = 0; i < 64; i++) { extendedAuthKey[i] = extendedAuthKey[i] ^ 0x5c; } TnmMD5Init(&MD); TnmMD5Update(&MD, extendedAuthKey, 64); TnmMD5Update(&MD, digest, 16); TnmMD5Final(digest, &MD); memcpy(msgAuthenticationParameters, digest, 12); }
void TnmSnmpMD5Digest(u_char *packet, int length, u_char *key, u_char *digest) { MD5_CTX MD; TnmMD5Init(&MD); /* initialize MD5 */ TnmMD5Update(&MD, (char *) packet, length); if (key) { TnmMD5Update(&MD, (char *) key, TNM_MD5_SIZE); } TnmMD5Final(digest, &MD); if (hexdump) { int i; if (key) { fprintf(stderr, "MD5 key: "); for (i = 0; i < TNM_MD5_SIZE; i++) { fprintf(stderr, "%02x ", key[i]); } fprintf(stdout, "\n"); } fprintf(stderr, "MD5 digest: "); for (i = 0; i < TNM_MD5_SIZE; i++) { fprintf(stderr, "%02x ", digest[i]); } fprintf(stderr, "\n"); } }
void TnmSnmpLocalizeKey(int algorithm, Tcl_Obj *authKey, Tcl_Obj *engineID, Tcl_Obj *localAuthKey) { unsigned char *engineBytes, *authKeyBytes; int engineLength, authKeyLength, localAuthKeyLength = 20; unsigned char localAuthKeyBytes[20]; /* must be big enough for MD5 and SHA */ authKeyBytes = (unsigned char *) Tcl_GetStringFromObj(authKey, &authKeyLength); engineBytes = (unsigned char *) Tcl_GetStringFromObj(engineID, &engineLength); /* * Localize a key as described in section 2.6 of RFC 2274. */ switch (algorithm) { case TNM_SNMP_AUTH_MD5: { MD5_CTX MD; TnmMD5Init(&MD); TnmMD5Update(&MD, authKeyBytes, authKeyLength); TnmMD5Update(&MD, engineBytes, engineLength); TnmMD5Update(&MD, authKeyBytes, authKeyLength); Tcl_SetObjLength(localAuthKey, 16); TnmMD5Final(localAuthKeyBytes, &MD); break; } case TNM_SNMP_AUTH_SHA: { SHA_CTX SH; TnmSHAInit(&SH); TnmSHAUpdate(&SH, authKeyBytes, authKeyLength); TnmSHAUpdate(&SH, engineBytes, engineLength); TnmSHAUpdate(&SH, authKeyBytes, authKeyLength); TnmSHAFinal(localAuthKeyBytes, &SH); break; } default: Tcl_Panic("unknown algorithm for key localization"); } Tcl_SetStringObj(localAuthKey, (char *) localAuthKeyBytes, localAuthKeyLength); }
static void MakeAuthKey(TnmSnmp *session) { MD5_CTX MD; u_char *cp, password_buf[64]; u_long password_index = 0; u_long count = 0, i; int found, valid = 0, passwordlen = strlen((char *) session->password); /* * We simply return if we do not have a password or if the * agentID is zero (which is an initialized agentID value. */ for (i = 0; i < USEC_MAX_AGENTID; i++) { if (session->agentID[i] != 0) { valid++; break; } } if (! valid || session->password == NULL) { return; } found = FindAuthKey(session); if (found != TCL_OK) { TnmMD5Init(&MD); /* initialize MD5 */ /* loop until we've done 1 Megabyte */ while (count < 1048576) { cp = password_buf; for(i = 0; i < 64; i++) { *cp++ = session->password[password_index++ % passwordlen]; /* * Take the next byte of the password, wrapping to the * beginning of the password as necessary. */ } TnmMD5Update(&MD, password_buf, 64); /* * 1048576 is divisible by 64, so the last MDupdate will be * aligned as well. */ count += 64; } TnmMD5Final(password_buf, &MD); memcpy(password_buf+TNM_MD5_SIZE, (char *) session->agentID, USEC_MAX_AGENTID); memcpy(password_buf+TNM_MD5_SIZE+USEC_MAX_AGENTID, password_buf, TNM_MD5_SIZE); TnmMD5Init(&MD); /* initialize MD5 */ TnmMD5Update(&MD, password_buf, TNM_MD5_SIZE+USEC_MAX_AGENTID+TNM_MD5_SIZE); TnmMD5Final(session->authKey, &MD); SaveAuthKey(session); } if (hexdump) { fprintf(stderr, "MD5 key: "); for (i = 0; i < TNM_MD5_SIZE; i++) { fprintf(stderr, "%02x ", session->authKey[i]); } fprintf(stderr, "\n"); } }