📄 keytools.c
字号:
/* * keytools.c */#include <net-snmp/net-snmp-config.h>#include <stdio.h>#include <sys/types.h>#if HAVE_WINSOCK_H#include <winsock.h>#endif#ifdef HAVE_NETINET_IN_H#include <netinet/in.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#include <net-snmp/types.h>#include <net-snmp/output_api.h>#include <net-snmp/utilities.h>#include <net-snmp/library/snmp_api.h>#ifdef USE_OPENSSL# include <openssl/hmac.h>#else#ifdef USE_INTERNAL_MD5#include <net-snmp/library/md5.h>#endif#endif#include <net-snmp/library/scapi.h>#include <net-snmp/library/keytools.h>#include <net-snmp/library/transform_oids.h>/*******************************************************************-o-****** * generate_Ku * * Parameters: * *hashtype MIB OID for the transform type for hashing. * hashtype_len Length of OID value. * *P Pre-allocated bytes of passpharase. * pplen Length of passphrase. * *Ku Buffer to contain Ku. * *kulen Length of Ku buffer. * * Returns: * SNMPERR_SUCCESS Success. * SNMPERR_GENERR All errors. * * * Convert a passphrase into a master user key, Ku, according to the * algorithm given in RFC 2274 concerning the SNMPv3 User Security Model (USM) * as follows: * * Expand the passphrase to fill the passphrase buffer space, if necessary, * concatenation as many duplicates as possible of P to itself. If P is * larger than the buffer space, truncate it to fit. * * Then hash the result with the given hashtype transform. Return * the result as Ku. * * If successful, kulen contains the size of the hash written to Ku. * * NOTE Passphrases less than USM_LENGTH_P_MIN characters in length * cause an error to be returned. * (Punt this check to the cmdline apps? XXX) */intgenerate_Ku(const oid * hashtype, u_int hashtype_len, u_char * P, size_t pplen, u_char * Ku, size_t * kulen)#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL){ int rval = SNMPERR_SUCCESS, nbytes = USM_LENGTH_EXPANDED_PASSPHRASE; u_int i, pindex = 0; u_char buf[USM_LENGTH_KU_HASHBLOCK], *bufp;#ifdef USE_OPENSSL EVP_MD_CTX *ctx = malloc(sizeof(EVP_MD_CTX));#else MDstruct MD;#endif /* * Sanity check. */ if (!hashtype || !P || !Ku || !kulen || (*kulen <= 0) || (hashtype_len != USM_LENGTH_OID_TRANSFORM)) { QUITFUN(SNMPERR_GENERR, generate_Ku_quit); } if (pplen < USM_LENGTH_P_MIN) { snmp_log(LOG_ERR, "Error: passphrase chosen is below the length " "requirements of the USM (min=%d).\n",USM_LENGTH_P_MIN); snmp_set_detail("The supplied password length is too short."); QUITFUN(SNMPERR_GENERR, generate_Ku_quit); } /* * Setup for the transform type. */#ifdef USE_OPENSSL if (ISTRANSFORM(hashtype, HMACMD5Auth)) EVP_DigestInit(ctx, EVP_md5()); else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) EVP_DigestInit(ctx, EVP_sha1()); else { free(ctx); return (SNMPERR_GENERR); }#else MDbegin(&MD);#endif /* USE_OPENSSL */ while (nbytes > 0) { bufp = buf; for (i = 0; i < USM_LENGTH_KU_HASHBLOCK; i++) { *bufp++ = P[pindex++ % pplen]; }#ifdef USE_OPENSSL EVP_DigestUpdate(ctx, buf, USM_LENGTH_KU_HASHBLOCK);#else if (MDupdate(&MD, buf, USM_LENGTH_KU_HASHBLOCK * 8)) { rval = SNMPERR_USM_ENCRYPTIONERROR; goto md5_fin; }#endif /* USE_OPENSSL */ nbytes -= USM_LENGTH_KU_HASHBLOCK; }#ifdef USE_OPENSSL EVP_DigestFinal(ctx, (unsigned char *) Ku, (unsigned int *) kulen); /* * what about free() */#else if (MDupdate(&MD, buf, 0)) { rval = SNMPERR_USM_ENCRYPTIONERROR; goto md5_fin; } *kulen = sc_get_properlength(hashtype, hashtype_len); MDget(&MD, Ku, *kulen); md5_fin: memset(&MD, 0, sizeof(MD));#endif /* USE_OPENSSL */#ifdef SNMP_TESTING_CODE DEBUGMSGTL(("generate_Ku", "generating Ku (from %s): ", P)); for (i = 0; i < *kulen; i++) DEBUGMSG(("generate_Ku", "%02x", Ku[i])); DEBUGMSG(("generate_Ku", "\n"));#endif /* SNMP_TESTING_CODE */ generate_Ku_quit: memset(buf, 0, sizeof(buf));#ifdef USE_OPENSSL free(ctx);#endif return rval;} /* end generate_Ku() */#else_KEYTOOLS_NOT_AVAILABLE#endif /* internal or openssl *//*******************************************************************-o-****** * generate_kul * * Parameters: * *hashtype * hashtype_len * *engineID * engineID_len * *Ku Master key for a given user. * ku_len Length of Ku in bytes. * *Kul Localized key for a given user at engineID. * *kul_len Length of Kul buffer (IN); Length of Kul key (OUT). * * Returns: * SNMPERR_SUCCESS Success. * SNMPERR_GENERR All errors. * * * Ku MUST be the proper length (currently fixed) for the given hashtype. * * Upon successful return, Kul contains the localized form of Ku at * engineID, and the length of the key is stored in kul_len. * * The localized key method is defined in RFC2274, Sections 2.6 and A.2, and * originally documented in: * U. Blumenthal, N. C. Hien, B. Wijnen, * "Key Derivation for Network Management Applications", * IEEE Network Magazine, April/May issue, 1997. * * * ASSUMES SNMP_MAXBUF >= sizeof(Ku + engineID + Ku). * * NOTE Localized keys for privacy transforms are generated via * the authentication transform held by the same usmUser. * * XXX An engineID of any length is accepted, even if larger than * what is spec'ed for the textual convention. */intgenerate_kul(const oid * hashtype, u_int hashtype_len, u_char * engineID, size_t engineID_len, u_char * Ku, size_t ku_len, u_char * Kul, size_t * kul_len)#if defined(USE_OPENSSL) || defined(USE_INTERNAL_MD5){ int rval = SNMPERR_SUCCESS; u_int nbytes = 0; size_t properlength; u_char buf[SNMP_MAXBUF];#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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -