📄 scapi.c
字号:
#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
{
int rval = SNMPERR_SUCCESS;
#ifdef USE_OPENSSL
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 (rval);
#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.
*/
int
sc_check_keyed_hash( 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 */
/*
* Sanity check.
*/
if ( !authtype || !key || !message || !MAC
|| (keylen<=0) || (msglen<=0) || (maclen<=0)
|| (authtypelen != USM_LENGTH_OID_TRANSFORM) )
{
QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);
}
/*
* Generate a full hash of the message, then compare
* the result with the given MAC which may shorter than
* the full hash length.
*/
rval = sc_generate_keyed_hash( authtype, authtypelen,
key, keylen,
message, msglen,
buf, &buf_len);
QUITFUN(rval, sc_check_keyed_hash_quit);
if (maclen > msglen) {
QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);
} else if ( memcmp(buf, MAC, maclen) != 0 ) {
QUITFUN(SNMPERR_GENERR, sc_check_keyed_hash_quit);
}
sc_check_keyed_hash_quit:
SNMP_ZERO(buf, SNMP_MAXBUF_SMALL);
return rval;
} /* end sc_check_keyed_hash() */
#else
_SCAPI_NOT_CONFIGURED
#endif /* USE_INTERNAL_MD5 */
/*******************************************************************-o-******
* sc_encrypt
*
* Parameters:
* privtype Type of privacy cryptographic transform.
* *key Key bits for crypting.
* keylen Length of key (buffer) in bytes.
* *iv IV bits for crypting.
* ivlen Length of iv (buffer) in bytes.
* *plaintext Plaintext to crypt.
* ptlen Length of plaintext.
* *ciphertext Ciphertext to crypt.
* *ctlen Length of ciphertext.
*
* Returns:
* SNMPERR_SUCCESS Success.
* SNMPERR_SC_NOT_CONFIGURED Encryption is not supported.
* SNMPERR_SC_GENERAL_FAILURE Any other error
*
*
* Encrypt plaintext into ciphertext using key and iv.
*
* ctlen contains actual number of crypted bytes in ciphertext upon
* successful return.
*/
int
sc_encrypt( oid *privtype, size_t privtypelen,
u_char *key, u_int keylen,
u_char *iv, u_int ivlen,
u_char *plaintext, u_int ptlen,
u_char *ciphertext, size_t *ctlen)
#if defined(USE_OPENSSL)
{
int rval = SNMPERR_SUCCESS;
u_int transform,
properlength,
properlength_iv;
u_char pad_block[32]; /* bigger than anything I need */
u_char my_iv[32]; /* ditto */
int pad, plast, pad_size;
des_key_schedule key_sch;
des_cblock key_struct;
DEBUGTRACE;
/*
* Sanity check.
*/
#if !defined(SCAPI_AUTHPRIV)
return SNMPERR_SC_NOT_CONFIGURED;
#endif
if ( !privtype || !key || !iv || !plaintext || !ciphertext || !ctlen
|| (keylen<=0) || (ivlen<=0) || (ptlen<=0) || (*ctlen<=0)
|| (privtypelen != USM_LENGTH_OID_TRANSFORM) )
{
QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
}
else if ( ptlen >= *ctlen) {
QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
}
#ifdef SNMP_TESTING_CODE
{
char buf[SNMP_MAXBUF];
sprint_hexstring(buf, iv, ivlen);
DEBUGMSGTL(("scapi", "encrypt: IV: %s/ ", buf));
sprint_hexstring(buf, key, keylen);
DEBUGMSG(("scapi","%s\n", buf));
sprint_hexstring(buf, plaintext, 16);
DEBUGMSGTL(("scapi","encrypt: string: %s\n", buf));
}
#endif /* SNMP_TESTING_CODE */
/*
* Determine privacy transform.
*/
if ( ISTRANSFORM(privtype, DESPriv) ) {
properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
pad_size = properlength;
} else {
QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
}
if ( (keylen<properlength) || (ivlen<properlength_iv) ) {
QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
}
else if ( (keylen<properlength) || (ivlen<properlength_iv) ) {
QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
}
/* now calculate the padding needed */
pad = pad_size - (ptlen % pad_size);
if (ptlen + pad > *ctlen) {
QUITFUN(SNMPERR_GENERR, sc_encrypt_quit); /* not enough space */
}
memset(pad_block, 0, sizeof(pad_block));
plast = (int) ptlen - (pad_size - pad);
if (pad > 0) /* copy data into pad block if needed */
memcpy( pad_block, plaintext + plast, pad_size - pad);
memset(&pad_block[pad_size-pad], pad, pad); /* filling in padblock */
memset(my_iv, 0, sizeof(my_iv));
if ( ISTRANSFORM(privtype, DESPriv) ) {
memcpy(key_struct, key, sizeof(key_struct));
(void) des_key_sched(&key_struct, key_sch);
memcpy(my_iv, iv, ivlen);
/* encrypt the data */
des_ncbc_encrypt(plaintext, ciphertext, plast, key_sch,
(des_cblock *) &my_iv, DES_ENCRYPT);
/* then encrypt the pad block */
des_ncbc_encrypt(pad_block, ciphertext+plast, pad_size,
key_sch, (des_cblock *)&my_iv, DES_ENCRYPT);
*ctlen = plast + pad_size;
}
sc_encrypt_quit:
/* clear memory just in case */
memset(my_iv, 0, sizeof(my_iv));
memset(pad_block, 0, sizeof(pad_block));
memset(key_struct, 0, sizeof(key_struct));
memset(key_sch, 0, sizeof(key_sch));
return rval;
} /* end sc_encrypt() */
#else
{
# if USE_INTERNAL_MD5
{
DEBUGMSGTL(("scapi","Encrypt function not defined.\n"));
return SNMPERR_SC_GENERAL_FAILURE;
}
# else
_SCAPI_NOT_CONFIGURED
# endif /* USE_INTERNAL_MD5 */
}
#endif /* */
/*******************************************************************-o-******
* sc_decrypt
*
* Parameters:
* privtype
* *key
* keylen
* *iv
* ivlen
* *ciphertext
* ctlen
* *plaintext
* *ptlen
*
* Returns:
* SNMPERR_SUCCESS Success.
* SNMPERR_SC_NOT_CONFIGURED Encryption is not supported.
* SNMPERR_SC_GENERAL_FAILURE Any other error
*
*
* Decrypt ciphertext into plaintext using key and iv.
*
* ptlen contains actual number of plaintext bytes in plaintext upon
* successful return.
*/
int
sc_decrypt( oid *privtype, size_t privtypelen,
u_char *key, u_int keylen,
u_char *iv, u_int ivlen,
u_char *ciphertext, u_int ctlen,
u_char *plaintext, size_t *ptlen)
#ifdef USE_OPENSSL
{
int rval = SNMPERR_SUCCESS;
int i, j;
u_char *my_iv[32];
des_key_schedule key_sch;
des_cblock key_struct;
u_int properlength,
properlength_iv;
DEBUGTRACE;
if ( !privtype || !key || !iv || !plaintext || !ciphertext || !ptlen
|| (ctlen<=0) || (*ptlen<=0) || (*ptlen < ctlen)
|| (privtypelen != USM_LENGTH_OID_TRANSFORM) )
{
QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
}
#ifdef SNMP_TESTING_CODE
{
char buf[SNMP_MAXBUF];
sprint_hexstring(buf, iv, ivlen);
DEBUGMSGTL(("scapi", "decrypt: IV: %s/ ", buf));
sprint_hexstring(buf, key, keylen);
DEBUGMSG(("scapi","%s\n", buf));
}
#endif /* SNMP_TESTING_CODE */
/*
* Determine privacy transform.
*/
if ( ISTRANSFORM(privtype, DESPriv) ) {
properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
} else {
QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
}
if ( (keylen<properlength) || (ivlen<properlength_iv) ) {
QUITFUN(SNMPERR_GENERR, sc_decrypt_quit);
}
memset(my_iv, 0, sizeof(my_iv));
if (ISTRANSFORM(privtype, DESPriv)) {
memcpy(key_struct, key, sizeof(key_struct));
(void) des_key_sched(&key_struct, key_sch);
memcpy(my_iv, iv, ivlen);
des_cbc_encrypt(ciphertext, plaintext, ctlen, key_sch,
(des_cblock *) &my_iv, DES_DECRYPT);
}
/* exit cond */
sc_decrypt_quit:
memset(key_sch, 0, sizeof(key_sch));
memset(key_struct, 0, sizeof(key_struct));
memset(my_iv, 0, sizeof(my_iv));
return rval;
}
#else /* USE OPEN_SSL */
{
#if !defined(SCAPI_AUTHPRIV)
return SNMPERR_SC_NOT_CONFIGURED;
#else
# if USE_INTERNAL_MD5
{
DEBUGMSGTL(("scapi","Decryption function not defined.\n"));
return SNMPERR_SC_GENERAL_FAILURE;
}
# else
_SCAPI_NOT_CONFIGURED
# endif /* USE_INTERNAL_MD5 */
#endif /* */
}
#endif /* USE_OPENSSL */
#endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -