keytools.c

来自「eCos操作系统源码」· C语言 代码 · 共 650 行 · 第 1/2 页

C
650
字号
#if defined(USE_OPENSSL) || defined(USE_INTERNAL_MD5){	int		 rval    = SNMPERR_SUCCESS;	u_int		 nbytes  = 0;        size_t           properlength;	u_char		 buf[SNMP_MAXBUF];	void		*context = NULL;#ifdef SNMP_TESTING_CODE        int		 i;#endif	/*	 * Sanity check.	 */	if ( !hashtype || !engineID || !Ku || !Kul || !kul_len		|| (engineID_len<=0) || (ku_len<=0) || (*kul_len<=0)		|| (hashtype_len != USM_LENGTH_OID_TRANSFORM) )	{		QUITFUN(SNMPERR_GENERR, generate_kul_quit);	}        properlength = sc_get_properlength(hashtype, hashtype_len);        if (properlength == SNMPERR_GENERR)          QUITFUN(SNMPERR_GENERR, generate_kul_quit);       	if (((int)*kul_len < properlength) || ((int)ku_len < properlength) ) {		QUITFUN(SNMPERR_GENERR, generate_kul_quit);	}	/*	 * Concatenate Ku and engineID properly, then hash the result.	 * Store it in Kul.	 */	nbytes = 0;	memcpy(buf,	   Ku,		properlength); nbytes += properlength;	memcpy(buf+nbytes, engineID,	engineID_len); nbytes += engineID_len;	memcpy(buf+nbytes, Ku,		properlength); nbytes += properlength;	rval = sc_hash(hashtype, hashtype_len, buf, nbytes, Kul, kul_len);#ifdef SNMP_TESTING_CODE        DEBUGMSGTL(("generate_kul", "generating Kul (from Ku): "));        for(i=0; i < *kul_len; i++)          DEBUGMSG(("generate_kul", "%02x",Kul[i]));        DEBUGMSG(("generate_kul", "keytools\n"));#endif /* SNMP_TESTING_CODE */	QUITFUN(rval, generate_kul_quit);		generate_kul_quit:	SNMP_FREE(context);	return rval;}  /* end generate_kul() */#else_KEYTOOLS_NOT_AVAILABLE#endif						/* internal or openssl *//*******************************************************************-o-****** * encode_keychange * * Parameters: *	*hashtype	MIB OID for the hash transform type. *	 hashtype_len	Length of the MIB OID hash transform type. *	*oldkey		Old key that is used to encodes the new key. *	 oldkey_len	Length of oldkey in bytes. *	*newkey		New key that is encoded using the old key. *	 newkey_len	Length of new key in bytes. *	*kcstring	Buffer to contain the KeyChange TC string. *	*kcstring_len	Length of kcstring buffer. *       * Returns: *	SNMPERR_SUCCESS			Success. *	SNMPERR_GENERR			All errors. * * * Uses oldkey and acquired random bytes to encode newkey into kcstring * according to the rules of the KeyChange TC described in RFC 2274, Section 5. * * Upon successful return, *kcstring_len contains the length of the * encoded string. * * ASSUMES	Old and new key are always equal to each other, although *		this may be less than the transform type hash output * 		output length (eg, using KeyChange for a DESPriv key when *		the user also uses SHA1Auth).  This also implies that the *		hash placed in the second 1/2 of the key change string *		will be truncated before the XOR'ing when the hash output is  *		larger than that 1/2 of the key change string. * *		*kcstring_len will be returned as exactly twice that same *		length though the input buffer may be larger. * * XXX FIX:     Does not handle varibable length keys. * XXX FIX:     Does not handle keys larger than the hash algorithm used. */intencode_keychange(	oid	*hashtype,	u_int  hashtype_len,			u_char	*oldkey,	size_t  oldkey_len,			u_char	*newkey,	size_t  newkey_len,			u_char	*kcstring,	size_t *kcstring_len)#if defined(USE_OPENSSL) || defined(USE_INTERNAL_MD5){	int		 rval    = SNMPERR_SUCCESS;	size_t		 properlength;        size_t            nbytes  = 0;        u_char          *tmpbuf = NULL;	void		*context = NULL;	/*	 * Sanity check.	 */	if ( !hashtype || !oldkey || !newkey || !kcstring || !kcstring_len		|| (oldkey_len<=0) || (newkey_len<=0) || (*kcstring_len<=0)		|| (hashtype_len != USM_LENGTH_OID_TRANSFORM) )	{		QUITFUN(SNMPERR_GENERR, encode_keychange_quit);	}	/*	 * Setup for the transform type.	 */        properlength = sc_get_properlength(hashtype, hashtype_len);        if (properlength == SNMPERR_GENERR)          QUITFUN(SNMPERR_GENERR, encode_keychange_quit);	if ( (oldkey_len != newkey_len) || (*kcstring_len < (2*oldkey_len)) )	{		QUITFUN(SNMPERR_GENERR, encode_keychange_quit);	}	properlength = SNMP_MIN((int)oldkey_len, properlength);	/*	 * Use the old key and some random bytes to encode the new key	 * in the KeyChange TC format:	 *	. Get random bytes (store in first half of kcstring),	 *	. Hash (oldkey | random_bytes) (into second half of kcstring),	 *	. XOR hash and newkey (into second half of kcstring).	 *	 * Getting the wrong number of random bytes is considered an error.	 */	nbytes = properlength;#if defined(SNMP_TESTING_CODE) && defined(RANDOMZEROS)		memset(kcstring, 0, nbytes);		DEBUGMSG(("encode_keychange",                          "** Using all zero bits for \"random\" delta of )"                          "the keychange string! **\n"));#else /* !SNMP_TESTING_CODE */		rval = sc_random(kcstring, &nbytes);		QUITFUN(rval, encode_keychange_quit);		if ((int)nbytes != properlength) {			QUITFUN(SNMPERR_GENERR, encode_keychange_quit);		}#endif /* !SNMP_TESTING_CODE */        tmpbuf = (u_char *)malloc(properlength*2);        if (tmpbuf) {            memcpy(tmpbuf, oldkey, properlength);            memcpy(tmpbuf+properlength, kcstring, properlength);                *kcstring_len -= properlength;            rval = sc_hash(hashtype, hashtype_len, tmpbuf, properlength*2,                           kcstring+properlength, kcstring_len);                        QUITFUN(rval, encode_keychange_quit);                *kcstring_len = (properlength*2);                kcstring += properlength;            nbytes    = 0;            while ((int)(nbytes++) < properlength) {                u_char kcs = *kcstring;            	*kcstring++ = kcs ^ *newkey++;            }        }encode_keychange_quit:	if (rval != SNMPERR_SUCCESS) memset(kcstring, 0, *kcstring_len);        SNMP_FREE(tmpbuf);	SNMP_FREE(context);	return rval;}  /* end encode_keychange() */#else_KEYTOOLS_NOT_AVAILABLE#endif						/* internal or openssl *//*******************************************************************-o-****** * decode_keychange * * Parameters: *	*hashtype	MIB OID of the hash transform to use. *	 hashtype_len	Length of the hash transform MIB OID. *	*oldkey		Old key that is used to encode the new key. *	 oldkey_len	Length of oldkey in bytes. *	*kcstring	Encoded KeyString buffer containing the new key. *	 kcstring_len	Length of kcstring in bytes. *	*newkey		Buffer to hold the extracted new key. *	*newkey_len	Length of newkey in bytes. *       * Returns: *	SNMPERR_SUCCESS			Success. *	SNMPERR_GENERR			All errors. * * * Decodes a string of bits encoded according to the KeyChange TC described * in RFC 2274, Section 5.  The new key is extracted from *kcstring with * the aid of the old key. * * Upon successful return, *newkey_len contains the length of the new key. * * * ASSUMES	Old key is exactly 1/2 the length of the KeyChange buffer, *		although this length may be less than the hash transform *		output.  Thus the new key length will be equal to the old *		key length. *//* XXX:  if the newkey is not long enough, it should be freed and remalloced */intdecode_keychange(	oid	*hashtype,	u_int  hashtype_len,			u_char	*oldkey,	size_t  oldkey_len,			u_char	*kcstring,	size_t  kcstring_len,			u_char	*newkey,	size_t *newkey_len)#if defined(USE_OPENSSL) || defined(USE_INTERNAL_MD5){	int		 rval    = SNMPERR_SUCCESS;	size_t		 properlength = 0;	u_int		 nbytes  = 0;	u_char		*bufp,			 tmp_buf[SNMP_MAXBUF];        size_t           tmp_buf_len = SNMP_MAXBUF;	void		*context = NULL;        u_char          *tmpbuf = NULL;	/*	 * Sanity check.	 */	if ( !hashtype || !oldkey || !kcstring || !newkey || !newkey_len		|| (oldkey_len<=0) || (kcstring_len<=0) || (*newkey_len<=0)		|| (hashtype_len != USM_LENGTH_OID_TRANSFORM) )	{		QUITFUN(SNMPERR_GENERR, decode_keychange_quit);	}	/*	 * Setup for the transform type.	 */        properlength = sc_get_properlength(hashtype, hashtype_len);        if (properlength == SNMPERR_GENERR)          QUITFUN(SNMPERR_GENERR, decode_keychange_quit);	if ( ((oldkey_len*2) != kcstring_len) || (*newkey_len < oldkey_len) )	{		QUITFUN(SNMPERR_GENERR, decode_keychange_quit);	}	properlength = oldkey_len;        *newkey_len = properlength;	/*	 * Use the old key and the given KeyChange TC string to recover	 * the new key:	 *	. Hash (oldkey | random_bytes) (into newkey),	 *	. XOR hash and encoded (second) half of kcstring (into newkey).	 */        tmpbuf = (u_char *)malloc(properlength*2);        if (tmpbuf) {            memcpy(tmpbuf, oldkey, properlength);            memcpy(tmpbuf+properlength, kcstring, properlength);                rval = sc_hash(hashtype, hashtype_len, tmpbuf, properlength*2,                           tmp_buf, &tmp_buf_len);            QUITFUN(rval, decode_keychange_quit);                memcpy(newkey, tmp_buf, properlength);            bufp   = kcstring+properlength;            nbytes = 0;            while ((int)(nbytes++) < properlength) {                    u_char nk = *newkey;                    *newkey++ = nk ^ *bufp++;            }        }decode_keychange_quit:	if (rval != SNMPERR_SUCCESS) {		memset(newkey, 0, properlength);	}	memset(tmp_buf, 0, SNMP_MAXBUF);	SNMP_FREE(context);        if (tmpbuf != NULL) SNMP_FREE(tmpbuf);	return rval;}  /* end decode_keychange() */#else_KEYTOOLS_NOT_AVAILABLE#endif						/* internal or openssl */#endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */

⌨️ 快捷键说明

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