⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snmpusm.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
         * 	unknown engines, processing continues w/ boots/time == (0,0).
	 */
	if (get_enginetime (theEngineID, theEngineIDLength, 
			    &boots_uint, &time_uint, FALSE) == -1)
	{
		DEBUGMSGTL(("usm","%s\n", "Failed to find engine data."));
	}

	boots_long = boots_uint;
	time_long  = time_uint;
	

	/* 
	 * Set up the Offsets.
	 */
	if (usm_calc_offsets (globalDataLen, theSecLevel, theEngineIDLength,
		theNameLength, scopedPduLen, boots_long, time_long,
		&theTotalLength, &authParamsOffset,
		&privParamsOffset, &dataOffset, &datalen,
		&msgAuthParmLen, &msgPrivParmLen,
		&otstlen, &seq_len, &msgSecParmLen) == -1)
	{
		DEBUGMSGTL(("usm","Failed calculating offsets.\n"));
		usm_free_usmStateReference (secStateRef);
		return SNMPERR_USM_GENERICERROR;
	}

	/*
		So, we have the offsets for the three parts that need to be
		determined, and an overall length.  Now we need to make
		sure all of this would fit in the outgoing buffer, and
		whether or not we need to make a new buffer, etc.
	*/


	/* 
	 * Set wholeMsg as a pointer to globalData.  Sanity check for
	 * the proper size.
	 * 
	 * Mark workspace in the message with bytes of all 1's to make it
	 * easier to find mistakes in raw message dumps.
	 */
	ptr = *wholeMsg = globalData;
	if (theTotalLength > *wholeMsgLen)
	{
		DEBUGMSGTL(("usm","Message won't fit in buffer.\n"));
		usm_free_usmStateReference (secStateRef);
		return SNMPERR_USM_GENERICERROR;
	}

	ptr_len = *wholeMsgLen = theTotalLength;

#ifdef SNMP_TESTING_CODE
	memset (&ptr[globalDataLen], 0xFF, theTotalLength-globalDataLen);
#endif /* SNMP_TESTING_CODE */


	/* 
	 * Do the encryption.
	 */
	if (theSecLevel == SNMP_SEC_LEVEL_AUTHPRIV)
	{
		size_t	encrypted_length = theTotalLength - dataOffset;
		size_t	salt_length	 = BYTESIZE(USM_MAX_SALT_LENGTH);
                u_char	salt[BYTESIZE(USM_MAX_SALT_LENGTH)];

		/* XXX  Hardwired to seek into a 1DES private key!
		 */
		if ( usm_set_salt(	salt,		&salt_length,
					thePrivKey+8,	thePrivKeyLength-8,
                        		&ptr[privParamsOffset])
						== -1 )
		{
			DEBUGMSGTL(("usm","Can't set DES-CBC salt.\n"));
			usm_free_usmStateReference (secStateRef);
			return SNMPERR_USM_GENERICERROR;
		}

		if ( sc_encrypt(
			 thePrivProtocol,	 thePrivProtocolLength,
			 thePrivKey,		 thePrivKeyLength,
                         salt,			 salt_length,
			 scopedPdu,		 scopedPduLen,
			&ptr[dataOffset],	&encrypted_length)
							!= SNMP_ERR_NOERROR )
		{
			DEBUGMSGTL(("usm","DES-CBC error.\n"));
			usm_free_usmStateReference (secStateRef);
			return SNMPERR_USM_ENCRYPTIONERROR;
		}


#ifdef SNMP_TESTING_CODE
		if ( debug_is_token_registered("usm/dump") == SNMPERR_SUCCESS) {
			dump_chunk("usm/dump", "This data was encrypted:",
					scopedPdu, scopedPduLen);
			dump_chunk("usm/dump", "salt + Encrypted form:",
					salt, salt_length);
			dump_chunk("usm/dump", NULL,
					&ptr[dataOffset], encrypted_length);
			dump_chunk("usm/dump", "*wholeMsg:",
					*wholeMsg, theTotalLength);
		}
#endif


		ptr 	= *wholeMsg;
		ptr_len = *wholeMsgLen = theTotalLength;


		/* 
		 * XXX  Sanity check for salt length should be moved up
		 *	under usm_calc_offsets() or tossed.
		 */
		if ( (encrypted_length != (theTotalLength - dataOffset))
				|| (salt_length != msgPrivParmLen) )
		{
			DEBUGMSGTL(("usm","DES-CBC length error.\n"));
			usm_free_usmStateReference (secStateRef);
			return SNMPERR_USM_ENCRYPTIONERROR;
		}

		DEBUGMSGTL(("usm","Encryption successful.\n"));
	}

	/* 
	 * No encryption for you!
	 */
	else
	{
		memcpy( &ptr[dataOffset], scopedPdu, scopedPduLen );
	}



	/* 
	 * Start filling in the other fields (in prep for authentication).
	 * 
	 * offSet is an octet string header, which is different from all
	 * the other headers.
	 */
	remaining = ptr_len - globalDataLen;

	offSet =  ptr_len - remaining;
	asn_build_header (&ptr[offSet], &remaining, 
		(u_char)(ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR), otstlen);

	offSet = ptr_len - remaining;
	asn_build_sequence (&ptr[offSet], &remaining, 
		(u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), seq_len);
	
	offSet = ptr_len - remaining;
	asn_build_string (&ptr[offSet], &remaining,
		(u_char)(ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR),
		theEngineID, theEngineIDLength);
	
	offSet = ptr_len - remaining;
	asn_build_int (&ptr[offSet], &remaining,
		(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
		&boots_long, sizeof(long));
	
	offSet = ptr_len - remaining;
	asn_build_int (&ptr[offSet], &remaining,
		(u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER),
		&time_long, sizeof(long));
	
	offSet = ptr_len - remaining;
	asn_build_string (&ptr[offSet], &remaining,
		(u_char)(ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR),
		(u_char *)theName, theNameLength);


	/*
		Note: if there is no authentication being done,
		msgAuthParmLen is 0, and there is no effect (other than
		inserting a zero-length header) of the following
		statements.
	*/

	offSet = ptr_len - remaining;
	asn_build_header(
			&ptr[offSet],
			&remaining,
			(u_char)(ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR),
			msgAuthParmLen);

	if (theSecLevel == SNMP_SEC_LEVEL_AUTHNOPRIV
		|| theSecLevel == SNMP_SEC_LEVEL_AUTHPRIV)
	{
		offSet = ptr_len - remaining;
		memset (&ptr[offSet],0,msgAuthParmLen);
	}

	remaining -= msgAuthParmLen;


	/*
		Note: if there is no encryption being done, msgPrivParmLen
		is 0, and there is no effect (other than inserting a
		zero-length header) of the following statements.
	*/

	offSet = ptr_len - remaining;
	asn_build_header(
		&ptr[offSet],
		&remaining,
		(u_char)(ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR),
		msgPrivParmLen);

	remaining -= msgPrivParmLen;	/* Skipping the IV already there. */


	/* 
	 * For privacy, need to add the octet string header for it.
	 */
	if (theSecLevel==SNMP_SEC_LEVEL_AUTHPRIV)
	{
		offSet = ptr_len - remaining;
		asn_build_header(
			&ptr[offSet],
			&remaining,
			(u_char)(ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR),
			theTotalLength - dataOffset );
	}


	/* 
	 * Adjust overall length and store it as the first SEQ length
	 * of the SNMPv3Message.
	 *
	 * FIX	4 is a magic number!
	 */
	remaining = theTotalLength;
	asn_build_sequence (ptr, &remaining, 
		(u_char)(ASN_SEQUENCE | ASN_CONSTRUCTOR), theTotalLength-4);


	/* 
	 * Now, time to consider / do authentication.
	 */
	if (theSecLevel == SNMP_SEC_LEVEL_AUTHNOPRIV
		|| theSecLevel == SNMP_SEC_LEVEL_AUTHPRIV)
	{
		size_t	temp_sig_len	= msgAuthParmLen;
		u_char *temp_sig	= (u_char *) malloc (temp_sig_len);

		if (temp_sig == NULL)
		{
			DEBUGMSGTL(("usm","Out of memory.\n"));
			usm_free_usmStateReference (secStateRef);
			return SNMPERR_USM_GENERICERROR;
		}

		if ( sc_generate_keyed_hash (
			theAuthProtocol,	 theAuthProtocolLength,
			theAuthKey,		 theAuthKeyLength,
			ptr,			 ptr_len,
			temp_sig,		&temp_sig_len)
							!= SNMP_ERR_NOERROR )
		{
			/* FIX temp_sig_len defined?!
			 */
			SNMP_ZERO(temp_sig, temp_sig_len);
			SNMP_FREE(temp_sig);
			DEBUGMSGTL(("usm","Signing failed.\n"));
			usm_free_usmStateReference (secStateRef);
			return SNMPERR_USM_AUTHENTICATIONFAILURE;
		}

		if (temp_sig_len != msgAuthParmLen)
		{
			SNMP_ZERO(temp_sig, temp_sig_len);
			SNMP_FREE(temp_sig);
			DEBUGMSGTL(("usm","Signing lengths failed.\n"));
			usm_free_usmStateReference (secStateRef);
			return SNMPERR_USM_AUTHENTICATIONFAILURE;
		}

		memcpy (&ptr[authParamsOffset], temp_sig, msgAuthParmLen);

		SNMP_ZERO(temp_sig, temp_sig_len);
		SNMP_FREE(temp_sig);

	}  /* endif -- create keyed hash */


	usm_free_usmStateReference (secStateRef);

	DEBUGMSGTL(("usm","USM processing completed.\n"));
	
	return SNMPERR_SUCCESS;

}  /* end usm_generate_out_msg() */




/*******************************************************************-o-******
 * usm_parse_security_parameters
 *
 * Parameters:
 *	(See list below...)
 *      
 * Returns:
 *	0	On success,
 *	-1	Otherwise.
 *
 *	tab stop 4
 *
 *	Extracts values from the security header and data portions of the
 *	incoming buffer.
 */
int
usm_parse_security_parameters (
	u_char  *secParams,
	size_t   remaining,
	u_char  *secEngineID,
	size_t  *secEngineIDLen,
	u_int   *boots_uint,
	u_int   *time_uint,
	char    *secName,
	size_t  *secNameLen,
	u_char  *signature,
	size_t  *signature_length,
	u_char  *salt,
	size_t  *salt_length,
	u_char **data_ptr)
{
	u_char  *parse_ptr = secParams;
	u_char  *value_ptr;
	u_char  *next_ptr;
	u_char   type_value;

	size_t   octet_string_length = remaining;
	size_t   sequence_length;
	size_t   remaining_bytes;

	long     boots_long;
	long     time_long;

	u_int    origNameLen;


	/* 
	 * Eat the first octet header.
	 */
	if ((value_ptr = asn_parse_sequence (parse_ptr, &octet_string_length,
		&type_value,
		(ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR),
		"usm first octet")) == NULL)
	{
		/* RETURN parse error */ return -1;
	}


	/* 
	 * Eat the sequence header.
	 */
	parse_ptr 	= value_ptr;
	sequence_length = octet_string_length;

	if ((value_ptr = asn_parse_sequence (parse_ptr, &sequence_length,
		&type_value,
		(ASN_SEQUENCE | ASN_CONSTRUCTOR),
		"usm sequence")) == NULL)
	{
		/* RETURN parse error */ return -1;
	}


	/*
	 * Retrieve the engineID.
	 */
	parse_ptr 	= value_ptr;
	remaining_bytes = sequence_length;

        DEBUGDUMPHEADER("dump_recv", "Parsing msgAuthoritativeEngineID\n");
	if ( (next_ptr
		= asn_parse_string (parse_ptr, &remaining_bytes, &type_value,
			secEngineID, secEngineIDLen)) == NULL )
	{
		DEBUGINDENTLESS();
                /* RETURN parse error */ return -1;
	}
        DEBUGINDENTLESS();

	if (type_value != (u_char) (ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR))
	{
		/* RETURN parse error */ return -1;
	}


	/* 
	 * Retrieve the engine boots, notice switch in the way next_ptr and
	 * remaining_bytes are used (to accomodate the asn code).
	 */
        DEBUGDUMPHEADER("dump_recv", "Parsing msgAuthoritativeEngineBoots\n");
	if ((next_ptr = asn_parse_int (next_ptr, &remaining_bytes, &type_value,
		&boots_long, sizeof(long))) == NULL)
	{
		DEBUGINDENTLESS();
                /* RETURN parse error */ return -1;
	}
        DEBUGINDENTLESS();

	if (type_value != (u_char) (ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_INTEGER))
	{
		DEBUGINDENTLESS();
                /* RETURN parse error */ return -1;
	}

	*boots_uint = (u_int) boots_long;


	/* 
	 * Retrieve the time value.
	 */
        DEBUGDUMPHEADER("dump_recv", "Parsing msgAuthoritativeEngineTime\n");
	if ((next_ptr = asn_parse_int (next_ptr, &remaining_bytes, &type_value,
		&time_long, sizeof(long))) == NULL)
	{
		/* RETURN parse error */ return -1;
	}

	if (type_value != (u_char) (ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_INTEGER))
	{
		  DEBUGINDENTLESS();
                  /* RETURN parse error */ return -1;
	}

	*time_uint = (u_int) time_long;


	/* 
	 * Retrieve the secName.
	 */
	origNameLen = *secNameLen;

        DEBUGDUMPHEADER("dump_recv", "Parsing msgUserName\n");
	if ( (next_ptr
		= asn_parse_string (next_ptr, &remaining_bytes, &type_value,
			(u_char *)secName, secNameLen)) == NULL )
	{
                DEBUGINDENTLESS();
		/* RETURN parse error */ return -1;
	}
        DEBUGINDENTLESS();

	/* FIX -- doesn't this also indicate a buffer overrun?
	 */
	if ((int)origNameLen < *secNameLen + 1)
	{
		/* RETURN parse error, but it's really a parameter error */
		return -1;
	}

	secName[*secNameLen] = '\0';

	if (type_value != (u_char) (ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR))
	{
		/* RETURN parse error */ return -1;
	}


	/* 
	 * Retrieve the signature and blank it if there.
	 */
        DEBUGDUMPHEADER("dump_recv", "Parsing msgAuthenticationParameters\n");
	if ( (next_ptr
		= asn_parse_string (next_ptr, &remaining_bytes, &type_value,
			signature, signature_length)) == NULL )
	{
                DEBUGINDENTLESS();
		/* RETURN parse error */ return -1;
	}
        DEBUGINDENTLESS();

	if (type_value != (u_char) (ASN_UNIVERSAL|ASN_PRIMITIVE|ASN_OCTET_STR))
	{
		/* RETURN parse error */ return -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -