static s8t encode_v3_response(message_v3_t* message, u8t* output, u16t* output_len, const u8t* const input, u16t input_len, const u16t max_output_len) { s16t pos = max_output_len; ber_encode_pdu(output, &pos, input, input_len, &message->pdu, max_output_len); TRY(ber_encode_fixed_string(output, &pos, message->contextName.ptr, message->contextName.len)); TRY(ber_encode_fixed_string(output, &pos, message->contextEngineID.ptr, message->contextEngineID.len)); TRY(ber_encode_type_length(output, &pos, BER_TYPE_SEQUENCE, max_output_len - pos)); /* encode Security Model data */ switch (USM_SECURITY_MODEL) { case USM_SECURITY_MODEL: TRY(prepareOutgoingMsg_USM(message, output, max_output_len, &pos)); break; } /* msgGlobalData sequence */ s16t tmpPos = pos; TRY(ber_encode_integer(output, &pos, BER_TYPE_INTEGER, USM_SECURITY_MODEL)); /* flags */ DEC(&pos); output[pos] = message->msgFlags; TRY(ber_encode_type_length(output, &pos, BER_TYPE_OCTET_STRING, 1)); TRY(ber_encode_integer(output, &pos, BER_TYPE_INTEGER, MAX_BUF_SIZE)); TRY(ber_encode_integer(output, &pos, BER_TYPE_INTEGER, message->msgId)); TRY(ber_encode_type_length(output, &pos, BER_TYPE_SEQUENCE, tmpPos - pos)); TRY(ber_encode_integer(output, &pos, BER_TYPE_INTEGER, message->version)); /* sequence header*/ TRY(ber_encode_type_length(output, &pos, BER_TYPE_SEQUENCE, max_output_len - pos)); *output_len = max_output_len - pos; if (message->msgFlags & FLAG_AUTH) { authenticate(message, &output[pos], *output_len); } if (pos > 0) { memmove(output, output + pos, *output_len); } return 0; }
static s8t encode_USM_parameters(message_v3_t* message, u8t* output, u16t buf_len, s16t* pos) { if (message->msgFlags & FLAG_PRIV) { #if ENABLE_PRIVACY u8t iv[16]; /* IV */ convert_2_octets(iv, message->msgAuthoritativeEngineBoots); convert_2_octets(iv + 4, message->msgAuthoritativeEngineTime); /* privace parameters */ convert_2_octets(message->msgPrivacyParameters.ptr, getLPrivacyParameters()); convert_2_octets(message->msgPrivacyParameters.ptr, getHPrivacyParameters()); memcpy(iv + 8, message->msgPrivacyParameters.ptr, 8); aes_process(getPrivKul(), iv, output + *pos, output + *pos, buf_len - *pos, AES_ENCRYPT); TRY(ber_encode_type_length(output, pos, BER_TYPE_OCTET_STRING, buf_len - *pos)); #else return FAILURE; #endif } s16t tmpPos = *pos; TRY(ber_encode_fixed_string(output, pos, message->msgPrivacyParameters.ptr, message->msgPrivacyParameters.len)); TRY(ber_encode_fixed_string(output, pos, message->msgAuthenticationParameters.ptr, message->msgAuthenticationParameters.len)); message->msgAuthenticationParameters.ptr = &output[*pos + 2]; TRY(ber_encode_fixed_string(output, pos, message->msgUserName.ptr, message->msgUserName.len)); TRY(ber_encode_integer(output, pos, BER_TYPE_INTEGER, message->msgAuthoritativeEngineTime)); TRY(ber_encode_integer(output, pos, BER_TYPE_INTEGER, message->msgAuthoritativeEngineBoots)); TRY(ber_encode_fixed_string(output, pos, message->msgAuthoritativeEngineID.ptr, message->msgAuthoritativeEngineID.len)); TRY(ber_encode_type_length(output, pos, BER_TYPE_SEQUENCE, tmpPos - *pos)); TRY(ber_encode_type_length(output, pos, BER_TYPE_OCTET_STRING, tmpPos - *pos)); return 0; }
s8t processIncomingMsg_USM(u8t* const input, const u16t input_len, u16t* pos, message_v3_t* request) { /* If the value of the msgAuthoritativeEngineID field in the securityParameters is unknown, return usmStatsUnknownEngineIDs */ TRY(decode_USM_parameters(input, input_len, pos, request)); if (request->msgAuthoritativeEngineID.len != getEngineID()->len || memcmp(request->msgAuthoritativeEngineID.ptr, getEngineID()->ptr, getEngineID()->len)) { TRY(report(request, &usmStatsUnknownEngineIDs, &usmStatsUnknownEngineIDCounter)); #if PDEBUG printf("USM Modul: Error! Wrong Engine ID!\n"); #endif return ERR_USM; } /* check user name */ if (request->msgUserName.len != strlen((char*)getUserName()) || memcmp(request->msgUserName.ptr, getUserName(), request->msgUserName.len) != 0) { TRY(report(request, &usmStatsUnknownUserNames, &usmStatsUnknownUserNamesCounter)); #if PDEBUG printf("USM Modul: Error! Wrong Username\n"); #endif return ERR_USM; } /*sz*/ #if ENABLE_AUTH if (!(request->msgFlags & FLAG_AUTH)) { #if PDEBUG printf("USM Modul: Error! User needs Authentication\n"); #endif TRY(report(request, &usmStatsUnsupportedSecurityLevel, &usmStatsUnsupportedSecurityLevelCounter)); return ERR_USM; } #endif /*sz*/ if (request->msgFlags & FLAG_AUTH) { #if ENABLE_AUTH /* The timeliness check is only performed if authentication is applied to the message */ if (request->msgAuthenticationParameters.len != 12 || isBadHMAC(input, input_len, request) != ERR_NO_ERROR) { #ifndef DISABLE_HMAC TRY(report(request, &usmStatsWrongDigests, &usmStatsWrongDigestsCounter)); #if PDEBUG printf("USM Modul: Error! Authentication Failed!\n"); #endif return ERR_USM; #endif /* Disable HMAC */ } #else return FAILURE; #endif } #if ENABLE_AUTH /*sz*/ #if PDEBUG printf("Checking Engine Time getsysuptime()/100: %d\n",(getSysUpTime()/100)); printf("Request EngineTime:%d\n", request->msgAuthoritativeEngineTime); printf("RequestTime - getSysUpTime/100: %d \n", (request->msgAuthoritativeEngineTime - (getSysUpTime()/100))); printf("abs of RequestTime - getSysUpTime/100: %d \n",(abs(request->msgAuthoritativeEngineTime - (getSysUpTime()/100)))); printf("Checking if it is in the time window (1 if it is not!!!) %d\n", (abs(request->msgAuthoritativeEngineTime - (getSysUpTime()/100)) > TIME_WINDOW)); if (request->msgAuthoritativeEngineBoots == 0){ printf("USM Modul: request->msgAuthoritativeEngineBoots == 0\n"); } if (request->msgAuthoritativeEngineBoots != getMsgAuthoritativeEngineBoots()){ printf("USM Modul: request->msgAuthoritativeEngineBoots != getMsgAuthoritativeEngineBoots()\n"); } if (abs(request->msgAuthoritativeEngineTime - getSysUpTime()) < TIME_WINDOW){ printf("USM Modul: abs(request->msgAuthoritativeEngineTime - getSysUpTime()) < TIME_WINDOW\n"); } if (getMsgAuthoritativeEngineBoots()>=2147483647){ printf("USM Modul: getMsgAuthoritativeEngineBoots()>=2147483647\n"); } #endif #if DISABLE_MAET == 0 if (request->msgAuthoritativeEngineBoots != getMsgAuthoritativeEngineBoots() || abs(request->msgAuthoritativeEngineTime - (getSysUpTime()/100)) > TIME_WINDOW || getMsgAuthoritativeEngineBoots()>=2147483647){ #endif #if DISABLE_MAET == 1 if (request->msgAuthoritativeEngineBoots != getMsgAuthoritativeEngineBoots() || getMsgAuthoritativeEngineBoots()>=2147483647){ #endif /*sz*/ /* Changed not working abs(request->msgAuthoritativeEngineTime - getSysUpTime()) < TIME_WINDOW)*/ /* to line above. /* added line getMsgAuthoritativeEngineBoots()>=2147483647 in if above */ /* to stop the SNMP Agent when the maximum snmpEngineBoots is reached*/ /* and send an Not in Time Window Message back.*/ /*sz*/ TRY(report(request, &usmStatsNotInTimeWindows, &usmStatsNotInTimeWindowsCounter)); return ERR_USM; } /*sz*/ #endif /*#if ENABLE_AUTH*/ /*sz*/ #if ENABLE_PRIVACY if (!(request->msgFlags & FLAG_PRIV)) { #if PDEBUG printf("USM Modul: Error! User needs Privacy\n"); #endif TRY(report(request, &usmStatsUnsupportedSecurityLevel, &usmStatsUnsupportedSecurityLevelCounter)); return ERR_USM; } #endif /*sz*/ if (request->msgFlags & FLAG_PRIV) { #if ENABLE_PRIVACY if (request->msgPrivacyParameters.len != 8) { TRY(report(request, &usmStatsDecryptionErrors, &usmStatsDecryptionErrorsCounter)); return ERR_USM; } /* init IV */ u8t iv[16]; convert_2_octets(iv, request->msgAuthoritativeEngineBoots); convert_2_octets(iv + 4, request->msgAuthoritativeEngineTime); memcpy(iv + 8, request->msgPrivacyParameters.ptr, 8); /* decode the Scoped PDU */ aes_process(getPrivKul(), iv, input + *pos, input + *pos, input_len - *pos, AES_DECRYPT); #else return FAILURE; #endif } return 0; } static s8t encode_USM_parameters(message_v3_t* message, u8t* output, u16t buf_len, s16t* pos) { if (message->msgFlags & FLAG_PRIV) { #if ENABLE_PRIVACY u8t iv[16]; /* IV */ convert_2_octets(iv, message->msgAuthoritativeEngineBoots); convert_2_octets(iv + 4, message->msgAuthoritativeEngineTime); /* privace parameters */ convert_2_octets(message->msgPrivacyParameters.ptr, getLPrivacyParameters()); convert_2_octets(message->msgPrivacyParameters.ptr, getHPrivacyParameters()); memcpy(iv + 8, message->msgPrivacyParameters.ptr, 8); aes_process(getPrivKul(), iv, output + *pos, output + *pos, buf_len - *pos, AES_ENCRYPT); TRY(ber_encode_type_length(output, pos, BER_TYPE_OCTET_STRING, buf_len - *pos)); #else return FAILURE; #endif } s16t tmpPos = *pos; TRY(ber_encode_fixed_string(output, pos, message->msgPrivacyParameters.ptr, message->msgPrivacyParameters.len)); TRY(ber_encode_fixed_string(output, pos, message->msgAuthenticationParameters.ptr, message->msgAuthenticationParameters.len)); message->msgAuthenticationParameters.ptr = &output[*pos + 2]; TRY(ber_encode_fixed_string(output, pos, message->msgUserName.ptr, message->msgUserName.len)); TRY(ber_encode_integer(output, pos, BER_TYPE_INTEGER, message->msgAuthoritativeEngineTime)); TRY(ber_encode_integer(output, pos, BER_TYPE_INTEGER, message->msgAuthoritativeEngineBoots)); TRY(ber_encode_fixed_string(output, pos, message->msgAuthoritativeEngineID.ptr, message->msgAuthoritativeEngineID.len)); TRY(ber_encode_type_length(output, pos, BER_TYPE_SEQUENCE, tmpPos - *pos)); TRY(ber_encode_type_length(output, pos, BER_TYPE_OCTET_STRING, tmpPos - *pos)); return 0; } s8t prepareOutgoingMsg_USM(message_v3_t* message, u8t* output, u16t output_len, s16t* pos) { memcpy(&message->msgAuthoritativeEngineID, getEngineID(), sizeof(ptr_t)); message->msgAuthoritativeEngineBoots = getMsgAuthoritativeEngineBoots(); message->msgAuthoritativeEngineTime = getSysUpTime()/100; encode_USM_parameters(message, output, output_len, pos); return 0; }