auth_priv.cpp
资源名称:snmp_pp.rar [点击查看]
上传用户:ets1996
上传日期:2014-09-30
资源大小:353k
文件大小:61k
源码类别:
SNMP编程
开发平台:
Visual C++
- /*_############################################################################
- _##
- _## auth_priv.cpp
- _##
- _## SNMP++v3.2.22
- _## -----------------------------------------------
- _## Copyright (c) 2001-2007 Jochen Katz, Frank Fock
- _##
- _## This software is based on SNMP++2.6 from Hewlett Packard:
- _##
- _## Copyright (c) 1996
- _## Hewlett-Packard Company
- _##
- _## ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
- _## Permission to use, copy, modify, distribute and/or sell this software
- _## and/or its documentation is hereby granted without fee. User agrees
- _## to display the above copyright notice and this license notice in all
- _## copies of the software and any documentation of the software. User
- _## agrees to assume all liability for the use of the software;
- _## Hewlett-Packard and Jochen Katz make no representations about the
- _## suitability of this software for any purpose. It is provided
- _## "AS-IS" without warranty of any kind, either express or implied. User
- _## hereby grants a royalty-free license to any and all derivatives based
- _## upon this software code base.
- _##
- _## Stuttgart, Germany, Wed May 2 23:22:30 CEST 2007
- _##
- _##########################################################################*/
- char auth_priv_version[]="@(#) SNMP++ $Id: auth_priv.cpp 256 2006-06-03 20:16:00Z katz $";
- #include "snmp_pp/config_snmp_pp.h"
- #ifdef _SNMPv3
- #include <string.h>
- #include <stdlib.h>
- #include <time.h>
- // Only use DES, AES, SHA1 and MD5 from libtomcrypt if openssl is not used
- #if defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)
- #include <tomcrypt.h>
- #endif
- // Use DES, AES, SHA and MD5 from openssl
- #ifdef _USE_OPENSSL
- #include <openssl/des.h>
- #include <openssl/aes.h>
- #include <openssl/sha.h>
- #include <openssl/md5.h>
- #endif
- // Use internal functions for SHA and MD5 and libdes only
- // if not using libtomcrypt and openssl
- #if !defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)
- #include "snmp_pp/sha.h"
- #ifdef RSAEURO
- #include <rsaeuro.h>
- #else
- #include <des.h>
- #include "snmp_pp/md5.h"
- #endif
- #endif // !defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)
- // IDEA can only be used with a valid license
- #ifdef _USE_IDEA
- #include "snmp_pp/idea.h"
- #endif
- #include "snmp_pp/auth_priv.h"
- #include "snmp_pp/v3.h"
- #include "snmp_pp/snmperrs.h"
- #include "snmp_pp/address.h"
- #include "snmp_pp/log.h"
- #ifdef SNMP_PP_NAMESPACE
- namespace Snmp_pp {
- #endif
- /*-----------------[ defines for crypto libraries ]------------------*/
- #ifdef _USE_OPENSSL
- /* -- START: Defines for OpenSSL -- */
- typedef SHA_CTX SHAHashStateType;
- #define SHA1_INIT(s) SHA1_Init(s)
- #define SHA1_PROCESS(s, p, l) SHA1_Update(s, p, l)
- #define SHA1_DONE(s, k) SHA1_Final(k, s)
- typedef MD5_CTX MD5HashStateType;
- #define MD5_INIT(s) MD5_Init(s)
- #define MD5_PROCESS(s, p, l) MD5_Update(s, p, l)
- #define MD5_DONE(s, k) MD5_Final(k, s)
- typedef des_key_schedule DESCBCType;
- #define DES_CBC_START_ENCRYPT(c, iv, k, kl, r, s)
- if (des_key_sched((C_Block*)(k), s) < 0)
- {
- debugprintf(0, "Starting DES encryption failed.");
- return SNMPv3_USM_ERROR;
- }
- #define DES_CBC_START_DECRYPT(c, iv, k, kl, r, s)
- if (des_key_sched((C_Block*)(k), s) < 0)
- {
- debugprintf(0, "Starting DES decryption failed.");
- return SNMPv3_USM_ERROR;
- }
- #define DES_CBC_ENCRYPT(pt, ct, s, iv, l)
- des_ncbc_encrypt(pt, ct, l,
- s, (C_Block*)(iv), DES_ENCRYPT)
- #define DES_CBC_DECRYPT(ct, pt, s, iv, l)
- des_ncbc_encrypt(ct, pt, l,
- s, (C_Block*)(iv), DES_DECRYPT)
- #define DES_EDE3_CBC_ENCRYPT(pt, ct, l, k1, k2, k3, iv)
- des_ede3_cbc_encrypt(pt, ct, l,
- k1, k2, k3, (C_Block*)(iv), DES_ENCRYPT)
- #define DES_EDE3_CBC_DECRYPT(ct, pt, l, k1, k2, k3, iv)
- des_ede3_cbc_encrypt(ct, pt, l,
- k1, k2, k3, (C_Block*)(iv), DES_DECRYPT)
- #define DES_MEMSET(s, c, l) memset(&(s), c, l)
- /* -- END: Defines for OpenSSL -- */
- #else
- #ifdef _USE_LIBTOMCRYPT
- /* -- START: Defines for LibTomCrypt -- */
- typedef hash_state SHAHashStateType;
- #define SHA1_INIT(s) sha1_init(s)
- #define SHA1_PROCESS(s, p, l) sha1_process(s, p, l)
- #define SHA1_DONE(s, k) sha1_done(s, k)
- typedef hash_state MD5HashStateType;
- #define MD5_INIT(s) md5_init(s)
- #define MD5_PROCESS(s, p, l) md5_process(s, p, l)
- #define MD5_DONE(s, k) md5_done(s, k)
- typedef symmetric_CBC DESCBCType;
- #define DES_CBC_START_ENCRYPT(c, iv, k, kl, r, s)
- if (cbc_start(c, iv, k, kl, r, &(s)) != CRYPT_OK)
- {
- debugprintf(0, "Starting DES encryption failed.");
- return SNMPv3_USM_ERROR;
- }
- #define DES_CBC_START_DECRYPT(c, iv, k, kl, r, s)
- if (cbc_start(c, iv, k, kl, r, &(s)) != CRYPT_OK)
- {
- debugprintf(0, "Starting DES decryption failed.");
- return SNMPv3_USM_ERROR;
- }
- #define DES_CBC_ENCRYPT(pt, ct, s, iv, l)
- if (cbc_encrypt(pt, ct, l, &(s)) != CRYPT_OK)
- {
- debugprintf(0, "Error during DES encryption.");
- return SNMPv3_USM_ERROR;
- }
- #define DES_CBC_DECRYPT(ct, pt, s, iv, l)
- if (cbc_decrypt(ct, pt, l, &(s)) != CRYPT_OK)
- {
- debugprintf(0, "Error during DES decryption.");
- return SNMPv3_USM_ERROR;
- }
- #define DES_MEMSET(s, c, l) memset(&(s), c, l)
- /* -- END: Defines for LibTomCrypt -- */
- #else // _USE_LIBTOMCRYPT --> libdes
- /* -- START: Defines for libdes -- */
- typedef SHA_CTX SHAHashStateType;
- #define SHA1_INIT(s) SHAInit(s)
- #define SHA1_PROCESS(s, p, l) SHAUpdate(s, p, l)
- #define SHA1_DONE(s, k) SHAFinal(k, s)
- typedef MD5_CTX MD5HashStateType;
- #define MD5_INIT(s) MD5Init(s)
- #define MD5_PROCESS(s, p, l) MD5Update(s, p, l)
- #define MD5_DONE(s, k) MD5Final(k, s)
- #define DES_EDE3_CBC_ENCRYPT(pt, ct, l, k1, k2, k3, iv)
- des_ede3_cbc_encrypt((C_Block*)(pt), (C_Block*)(ct), l,
- k1, k2, k3, (C_Block*)(iv), DES_ENCRYPT)
- #define DES_EDE3_CBC_DECRYPT(ct, pt, l, k1, k2, k3, iv)
- des_ede3_cbc_encrypt((C_Block*)(ct), (C_Block*)(pt), l,
- k1, k2, k3, (C_Block*)(iv), DES_DECRYPT)
- #ifdef RSAEURO
- #undef MD5_PROCESS
- #define MD5_PROCESS(s, p, l) MD5Update(s, (unsigned char*)(p), l)
- typedef DES_CBC_CTX DESCBCType;
- #define DES_CBC_START_ENCRYPT(c, iv, k, kl, r, s)
- DES_CBCInit(&(s), (unsigned char*)(k), iv, 1)
- #define DES_CBC_START_DECRYPT(c, iv, k, kl, r, s)
- DES_CBCInit(&(s),(unsigned char*)(k), iv, 0)
- #define DES_CBC_ENCRYPT(pt, ct, s, iv, l) DES_CBCUpdate(&(s), pt, ct, l)
- #define DES_CBC_DECRYPT(ct, pt, s, iv, l) DES_CBCUpdate(&(s), (unsigned char*)(ct), pt, l)
- #define DES_MEMSET(s, c, l) R_memset((POINTER)&(s), c, l)
- #else // RSAEURO
- typedef des_key_schedule DESCBCType;
- #define DES_CBC_START_ENCRYPT(c, iv, k, kl, r, s)
- if (des_key_sched((C_Block*)(k), s) < 0)
- {
- debugprintf(0, "Starting DES encryption failed.");
- return SNMPv3_USM_ERROR;
- }
- #define DES_CBC_START_DECRYPT(c, iv, k, kl, r, s)
- if (des_key_sched((C_Block*)(k), s) < 0)
- {
- debugprintf(0, "Starting DES decryption failed.");
- return SNMPv3_USM_ERROR;
- }
- #define DES_CBC_ENCRYPT(pt, ct, s, iv, l)
- des_ncbc_encrypt((C_Block*)(pt), (C_Block*)(ct), l,
- s, (C_Block*)(iv), DES_ENCRYPT)
- #define DES_CBC_DECRYPT(ct, pt, s, iv, l)
- des_ncbc_encrypt((C_Block*)(ct), (C_Block*)(pt), l,
- s, (C_Block*)(iv), DES_DECRYPT)
- #define DES_MEMSET(s, c, l) memset(&(s), c, l)
- /* -- END: Defines for libdes -- */
- #endif // RSAEURO
- #endif // _USE_LIBTOMCRYPT
- #endif // _USE_OPENSSL
- AuthPriv::AuthPriv(int &construct_state)
- {
- auth = new AuthPtr[10];
- priv = new PrivPtr[10];
- if (auth)
- auth_size = 10;
- else
- {
- auth_size = 0;
- LOG_BEGIN(ERROR_LOG | 1);
- LOG("AuthPriv: Error allocating array for authentication.");
- LOG_END;
- }
- if (priv)
- priv_size = 10;
- else
- {
- priv_size = 0;
- LOG_BEGIN(ERROR_LOG | 1);
- LOG("AuthPriv: Error allocating array for privacy.");
- LOG_END;
- }
- for (int i = 0; i < auth_size; i++)
- auth[i] = 0;
- for (int j = 0; j < priv_size; j++)
- priv[j] = 0;
- /* Check size of salt, has to be 64 bits */
- if (sizeof(salt) != 8)
- {
- LOG_BEGIN(ERROR_LOG | 1);
- LOG("AuthPriv: *BUG* sizeof(pp_uint64) is not 8 bytes. snmp++ has to be patched for this system.");
- LOG_END;
- construct_state = SNMPv3_USM_ERROR;
- return;
- }
- /* Initialize salt. srand() has been already done in Snmp::init() */
- unsigned int *rnd = (unsigned int*)&salt;
- *rnd = rand() << 1;
- if (rand() < (RAND_MAX / 2))
- *rnd += 1;
- rnd++;
- *rnd = rand() << 1;
- if (rand() < (RAND_MAX / 2))
- *rnd += 1;
- construct_state = SNMPv3_USM_OK;
- #if defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)
- /* register needed hashes and ciphers in libtomcrypt */
- if (register_cipher(&rijndael_desc) < 0)
- {
- LOG_BEGIN(ERROR_LOG | 1);
- LOG("AuthPriv: Error registering Rijndael.");
- LOG_END;
- construct_state = SNMPv3_USM_ERROR;
- }
- if (register_cipher(&des_desc) < 0)
- {
- LOG_BEGIN(ERROR_LOG | 1);
- LOG("AuthPriv: Error registering DES.");
- LOG_END;
- construct_state = SNMPv3_USM_ERROR;
- }
- if (register_cipher(&des3_desc) < 0)
- {
- LOG_BEGIN(ERROR_LOG | 1);
- LOG("AuthPriv: Error registering 3DES.");
- LOG_END;
- construct_state = SNMPv3_USM_ERROR;
- }
- if (register_hash(&sha1_desc) < 0)
- {
- LOG_BEGIN(ERROR_LOG | 1);
- LOG("AuthPriv: Error registering SHA1.");
- LOG_END;
- construct_state = SNMPv3_USM_ERROR;
- }
- if (register_hash(&md5_desc) < 0)
- {
- LOG_BEGIN(ERROR_LOG | 1);
- LOG("AuthPriv: Error registering MD5.");
- LOG_END;
- construct_state = SNMPv3_USM_ERROR;
- }
- #endif // defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)
- }
- AuthPriv::~AuthPriv()
- {
- for (int i = 0; i < auth_size; i++)
- if (auth[i])
- {
- delete auth[i];
- auth[i] = 0;
- }
- for (int j = 0; j < priv_size; j++)
- if (priv[j])
- {
- delete priv[j];
- priv[j] = 0;
- }
- delete [] auth;
- delete [] priv;
- }
- int AuthPriv::add_auth(Auth *new_auth)
- {
- if (!new_auth)
- {
- return SNMP_CLASS_ERROR;
- }
- int id = new_auth->get_id();
- if (id < 0)
- {
- return SNMP_CLASS_ERROR;
- }
- if (id >= auth_size)
- {
- AuthPtr *new_array = new AuthPtr[id + 5];
- if (!new_array)
- {
- LOG_BEGIN(ERROR_LOG | 1);
- LOG("AuthPriv: Could not allocate new auth array.");
- LOG_END;
- return SNMP_CLASS_ERROR;
- }
- for (int i=0 ; i<auth_size; i++)
- new_array[i] = auth[i];
- for (int j=auth_size ; j<id + 5; j++)
- new_array[j] = 0;
- AuthPtr *victim = auth;
- auth = new_array;
- delete [] victim;
- auth_size = id + 5;
- }
- new_auth->set_salt(&salt);
- if (auth[id])
- {
- LOG_BEGIN(WARNING_LOG | 4);
- LOG("AuthPriv: deleting old auth object before adding new one (id)");
- LOG(id);
- LOG_END;
- delete auth[id];
- }
- auth[id] = new_auth;
- LOG_BEGIN(INFO_LOG | 6);
- LOG("AuthPriv: Added auth protocol (id)");
- LOG(id);
- LOG_END;
- return SNMP_CLASS_SUCCESS;
- }
- int AuthPriv::del_auth(const int auth_id)
- {
- if ((auth_id < 0) || (auth_id >= auth_size) || (auth[auth_id] == 0))
- {
- LOG_BEGIN(WARNING_LOG | 4);
- LOG("AuthPriv: Request to delete non existing auth protocol (id)");
- LOG(auth_id);
- LOG_END;
- return SNMP_CLASS_ERROR;
- }
- delete auth[auth_id];
- auth[auth_id] = 0;
- LOG_BEGIN(INFO_LOG | 6);
- LOG("AuthPriv: Removed auth protocol (id)");
- LOG(auth_id);
- LOG_END;
- return SNMP_CLASS_SUCCESS;
- }
- int AuthPriv::add_priv(Priv *new_priv)
- {
- if (!new_priv)
- {
- return SNMP_CLASS_ERROR;
- }
- int id = new_priv->get_id();
- if (id < 0)
- {
- return SNMP_CLASS_ERROR;
- }
- if (id >= priv_size)
- {
- PrivPtr *new_array = new PrivPtr[id + 5];
- if (!new_array)
- {
- LOG_BEGIN(ERROR_LOG | 1);
- LOG("AuthPriv: Could not allocate new priv array.");
- LOG_END;
- return SNMP_CLASS_ERROR;
- }
- for (int i=0 ; i<priv_size; i++)
- new_array[i] = priv[i];
- for (int j=priv_size ; j<id + 5; j++)
- new_array[j] = 0;
- PrivPtr *victim = priv;
- priv = new_array;
- delete [] victim;
- priv_size = id + 5;
- }
- new_priv->set_salt(&salt);
- if (priv[id])
- {
- LOG_BEGIN(WARNING_LOG | 4);
- LOG("AuthPriv: deleting old priv object before adding new one (id)");
- LOG(id);
- LOG_END;
- delete priv[id];
- }
- priv[id] = new_priv;
- LOG_BEGIN(INFO_LOG | 6);
- LOG("AuthPriv: Added priv protocol (id)");
- LOG(id);
- LOG_END;
- return SNMP_CLASS_SUCCESS;
- }
- int AuthPriv::del_priv(const int priv_id)
- {
- if ((priv_id < 0) || (priv_id >= priv_size) || (priv[priv_id] == 0))
- {
- LOG_BEGIN(WARNING_LOG | 4);
- LOG("AuthPriv: Request to delete non existing priv protocol (id)");
- LOG(priv_id);
- LOG_END;
- return SNMP_CLASS_ERROR;
- }
- delete priv[priv_id];
- priv[priv_id] = 0;
- LOG_BEGIN(INFO_LOG | 6);
- LOG("AuthPriv: Removed priv protocol (id)");
- LOG(priv_id);
- LOG_END;
- return SNMP_CLASS_SUCCESS;
- }
- Auth *AuthPriv::get_auth(const int auth_prot)
- {
- if ((auth_prot >= 0) && (auth_prot < auth_size))
- return auth[auth_prot];
- return 0;
- }
- Priv *AuthPriv::get_priv(const int priv_prot)
- {
- if ((priv_prot >= 0) && (priv_prot < priv_size))
- return priv[priv_prot];
- return 0;
- }
- // Get the unique id for the given auth protocol.
- int AuthPriv::get_auth_id(const char *string_id) const
- {
- for (int i = 0; i < auth_size; ++i)
- if ((auth[i]) && (strcmp(string_id, auth[i]->get_id_string()) == 0))
- return i;
- return -1;
- }
- // Get the unique id for the given priv protocol.
- int AuthPriv::get_priv_id(const char *string_id) const
- {
- for (int i = 0; i < priv_size; ++i)
- if ((priv[i]) && (strcmp(string_id, priv[i]->get_id_string()) == 0))
- return i;
- return -1;
- }
- int AuthPriv::get_keychange_value(const int auth_prot,
- const OctetStr& old_key,
- const OctetStr& new_key,
- OctetStr& keychange_value)
- {
- // uses fixed key length determined from oldkey!
- // works with SHA and MD5
- // modifications needed to support variable length keys
- // algorithm according to USM-document textual convention KeyChange
- int key_len = old_key.len();
- Auth *a = get_auth(auth_prot);
- if (!a)
- return SNMPv3_USM_UNSUPPORTED_AUTHPROTOCOL;
- // compute random value
- OctetStr random = "";
- for (int i=0; i<key_len; i++) {
- #ifdef _TEST
- // do not use random values for testing
- random += OctetStr((unsigned char*)"