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

📄 scapi.c

📁 snmp up 2
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * scapi.c * */#include <net-snmp/net-snmp-config.h>#include <sys/types.h>#if HAVE_WINSOCK_H#include <winsock.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if TIME_WITH_SYS_TIME# ifdef WIN32#  include <sys/timeb.h># else#  include <sys/time.h># endif# include <time.h>#else# if HAVE_SYS_TIME_H#  include <sys/time.h># else#  include <time.h># endif#endif#ifdef HAVE_NETINET_IN_H#include <netinet/in.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>#ifdef USE_INTERNAL_MD5#include <net-snmp/library/md5.h>#endif#include <net-snmp/library/snmp_api.h>#include <net-snmp/library/callback.h>#include <net-snmp/library/snmp_secmod.h>#include <net-snmp/library/snmpusm.h>#include <net-snmp/library/keytools.h>#include <net-snmp/library/scapi.h>#include <net-snmp/library/mib.h>#include <net-snmp/library/transform_oids.h>#ifdef USE_OPENSSL#include <openssl/hmac.h>#include <openssl/evp.h>#include <openssl/rand.h>#include <openssl/des.h>#ifdef HAVE_AES#include <openssl/aes.h>#endif#ifdef STRUCT_DES_KS_STRUCT_HAS_WEAK_KEY/* these are older names for newer structures that exist in openssl .9.7 */#define DES_key_schedule    des_key_schedule #define DES_cblock          des_cblock #define DES_key_sched       des_key_sched #define DES_ncbc_encrypt    des_ncbc_encrypt#define DES_cbc_encrypt    des_cbc_encrypt#define OLD_DES#endif#endif /* HAVE_OPENSSL */#ifdef QUITFUN#undef QUITFUN#define QUITFUN(e, l)					\	if (e != SNMPERR_SUCCESS) {			\		rval = SNMPERR_SC_GENERAL_FAILURE;	\		goto l ;				\	}#endif/* * sc_get_properlength(oid *hashtype, u_int hashtype_len): *  * Given a hashing type ("hashtype" and its length hashtype_len), return * the length of the hash result. *  * Returns either the length or SNMPERR_GENERR for an unknown hashing type. */intsc_get_properlength(const oid * hashtype, u_int hashtype_len){    DEBUGTRACE;    /*     * Determine transform type hash length.     */    if (ISTRANSFORM(hashtype, HMACMD5Auth)) {        return BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5);    } else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {        return BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);    }    return SNMPERR_GENERR;}/*******************************************************************-o-****** * sc_init * * Returns: *	SNMPERR_SUCCESS			Success. */intsc_init(void){    int             rval = SNMPERR_SUCCESS;#ifndef USE_OPENSSL#ifdef USE_INTERNAL_MD5    struct timeval  tv;    DEBUGTRACE;    gettimeofday(&tv, (struct timezone *) 0);    srandom(tv.tv_sec ^ tv.tv_usec);#else    rval = SNMPERR_SC_NOT_CONFIGURED;#endif    /*     * XXX ogud: The only reason to do anything here with openssl is to      * * XXX ogud: seed random number generator      */#endif                          /* ifndef USE_OPENSSL */    return rval;}                               /* end sc_init() *//*******************************************************************-o-****** * sc_random * * Parameters: *	*buf		Pre-allocated buffer. *	*buflen 	Size of buffer. *       * Returns: *	SNMPERR_SUCCESS			Success. */intsc_random(u_char * buf, size_t * buflen)#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL){    int             rval = SNMPERR_SUCCESS;#ifdef USE_INTERNAL_MD5    int             i;    int             rndval;    u_char         *ucp = buf;#endif    DEBUGTRACE;#ifdef USE_OPENSSL    RAND_bytes(buf, *buflen);   /* will never fail */#else                           /* USE_INTERNAL_MD5 */    /*     * fill the buffer with random integers.  Note that random()     * is defined in config.h and may not be truly the random()     * system call if something better existed      */    rval = *buflen - *buflen % sizeof(rndval);    for (i = 0; i < rval; i += sizeof(rndval)) {        rndval = random();        memcpy(ucp, &rndval, sizeof(rndval));        ucp += sizeof(rndval);    }    rndval = random();    memcpy(ucp, &rndval, *buflen % sizeof(rndval));    rval = SNMPERR_SUCCESS;#endif                          /* USE_OPENSSL */    return rval;}                               /* end sc_random() */#else_SCAPI_NOT_CONFIGURED#endif                          /*  *//*******************************************************************-o-****** * sc_generate_keyed_hash * * Parameters: *	 authtype	Type of authentication transform. *	 authtypelen *	*key		Pointer to key (Kul) to use in keyed hash. *	 keylen		Length of key in bytes. *	*message	Pointer to the message to hash. *	 msglen		Length of the message. *	*MAC		Will be returned with allocated bytes containg hash. *	*maclen		Length of the hash buffer in bytes; also indicates *				whether the MAC should be truncated. *       * Returns: *	SNMPERR_SUCCESS			Success. *	SNMPERR_GENERR			All errs * * * A hash of the first msglen bytes of message using a keyed hash defined * by authtype is created and stored in MAC.  MAC is ASSUMED to be a buffer * of at least maclen bytes.  If the length of the hash is greater than * maclen, it is truncated to fit the buffer.  If the length of the hash is * less than maclen, maclen set to the number of hash bytes generated. * * ASSUMED that the number of hash bits is a multiple of 8. */intsc_generate_keyed_hash(const oid * authtype, size_t authtypelen,                       u_char * key, u_int keylen,                       u_char * message, u_int msglen,                       u_char * MAC, size_t * maclen)#if  defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL){    int             rval = SNMPERR_SUCCESS;    int             properlength;    u_char          buf[SNMP_MAXBUF_SMALL];#if  defined(USE_OPENSSL)    int             buf_len = sizeof(buf);#endif    DEBUGTRACE;#ifdef SNMP_TESTING_CODE    {        int             i;        DEBUGMSG(("sc_generate_keyed_hash",                  "sc_generate_keyed_hash(): key=0x"));        for (i = 0; i < keylen; i++)            DEBUGMSG(("sc_generate_keyed_hash", "%02x", key[i] & 0xff));        DEBUGMSG(("sc_generate_keyed_hash", " (%d)\n", keylen));    }#endif                          /* SNMP_TESTING_CODE */    /*     * Sanity check.     */    if (!authtype || !key || !message || !MAC || !maclen        || (keylen <= 0) || (msglen <= 0) || (*maclen <= 0)        || (authtypelen != USM_LENGTH_OID_TRANSFORM)) {        QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);    }    properlength = sc_get_properlength(authtype, authtypelen);    if (properlength == SNMPERR_GENERR)        return properlength;    if (((int) keylen < properlength)) {        QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);    }#ifdef USE_OPENSSL    /*     * Determine transform type.     */    if (ISTRANSFORM(authtype, HMACMD5Auth))        HMAC(EVP_md5(), key, keylen, message, msglen, buf, &buf_len);    else if (ISTRANSFORM(authtype, HMACSHA1Auth))        HMAC(EVP_sha1(), key, keylen, message, msglen, buf, &buf_len);    else {        QUITFUN(SNMPERR_GENERR, sc_generate_keyed_hash_quit);    }    if (buf_len != properlength) {        QUITFUN(rval, sc_generate_keyed_hash_quit);    }    if (*maclen > buf_len)        *maclen = buf_len;    memcpy(MAC, buf, *maclen);#else    if ((int) *maclen > properlength)        *maclen = properlength;    if (MDsign(message, msglen, MAC, *maclen, key, keylen)) {        rval = SNMPERR_GENERR;        goto sc_generate_keyed_hash_quit;    }#endif                          /* USE_OPENSSL */#ifdef SNMP_TESTING_CODE    {        char           *s;        int             len = binary_to_hex(MAC, *maclen, &s);        DEBUGMSGTL(("scapi", "Full v3 message hash: %s\n", s));        SNMP_ZERO(s, len);        SNMP_FREE(s);    }#endif  sc_generate_keyed_hash_quit:    SNMP_ZERO(buf, SNMP_MAXBUF_SMALL);    return rval;}                               /* end sc_generate_keyed_hash() */#else                _SCAPI_NOT_CONFIGURED#endif                          /* *//* * sc_hash(): a generic wrapper around whatever hashing package we are using. *  * IN: * hashtype    - oid pointer to a hash type * hashtypelen - length of oid pointer * buf         - u_char buffer to be hashed * buf_len     - integer length of buf data * MAC_len     - length of the passed MAC buffer size. *  * OUT:     * MAC         - pre-malloced space to store hash output. * MAC_len     - length of MAC output to the MAC buffer. *  * Returns: * SNMPERR_SUCCESS              Success. * SNMP_SC_GENERAL_FAILURE      Any error. */intsc_hash(const oid * hashtype, size_t hashtypelen, u_char * buf,        size_t buf_len, u_char * MAC, size_t * MAC_len)#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL){#ifdef USE_OPENSSL    int             rval = SNMPERR_SUCCESS;    EVP_MD         *hash(void);    HMAC_CTX       *c = NULL;#endif    DEBUGTRACE;    if (hashtype == NULL || hashtypelen < 0 || buf == NULL ||        buf_len < 0 || MAC == NULL || MAC_len == NULL ||        (int) (*MAC_len) < sc_get_properlength(hashtype, hashtypelen))        return (SNMPERR_GENERR);#ifdef USE_OPENSSL    /*     * Determine transform type.     */    c = malloc(sizeof(HMAC_CTX));    if (c == NULL)        return (SNMPERR_GENERR);    if (ISTRANSFORM(hashtype, HMACMD5Auth)) {        EVP_DigestInit(&c->md_ctx, (const EVP_MD *) EVP_md5());    } else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {        EVP_DigestInit(&c->md_ctx, (const EVP_MD *) EVP_sha1());    } else {        return (SNMPERR_GENERR);    }    EVP_DigestUpdate(&c->md_ctx, buf, buf_len);    EVP_DigestFinal(&(c->md_ctx), MAC, MAC_len);    free(c);    return (rval);#else                           /* USE_INTERNAL_MD5 */    if (MDchecksum(buf, buf_len, MAC, *MAC_len)) {        return SNMPERR_GENERR;    }    if (*MAC_len > 16)        *MAC_len = 16;    return SNMPERR_SUCCESS;#endif                          /* USE_OPENSSL */}#else                           /* !defined(USE_OPENSSL) && !defined(USE_INTERNAL_MD5) */_SCAPI_NOT_CONFIGURED#endif                          /* !defined(USE_OPENSSL) && !defined(USE_INTERNAL_MD5) *//*******************************************************************-o-****** * sc_check_keyed_hash * * Parameters: *	 authtype	Transform type of authentication hash. *	*key		Key bits in a string of bytes. *	 keylen		Length of key in bytes. *	*message	Message for which to check the hash. *	 msglen		Length of message. *	*MAC		Given hash. *	 maclen		Length of given hash; indicates truncation if it is *				shorter than the normal size of output for *				given hash transform. * Returns: *	SNMPERR_SUCCESS		Success. *	SNMP_SC_GENERAL_FAILURE	Any error * * * Check the hash given in MAC against the hash of message.  If the length * of MAC is less than the length of the transform hash output, only maclen * bytes are compared.  The length of MAC cannot be greater than the * length of the hash transform output. */intsc_check_keyed_hash(const oid * authtype, size_t authtypelen,                    u_char * key, u_int keylen,                    u_char * message, u_int msglen,                    u_char * MAC, u_int maclen)#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL){    int             rval = SNMPERR_SUCCESS;    size_t          buf_len = SNMP_MAXBUF_SMALL;    u_char          buf[SNMP_MAXBUF_SMALL];    DEBUGTRACE;#ifdef SNMP_TESTING_CODE    {        int             i;        DEBUGMSG(("scapi", "sc_check_keyed_hash():    key=0x"));        for (i = 0; i < keylen; i++)            DEBUGMSG(("scapi", "%02x", key[i] & 0xff));        DEBUGMSG(("scapi", " (%d)\n", keylen));    }#endif                          /* SNMP_TESTING_CODE */

⌨️ 快捷键说明

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