Пример #1
0
_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.
*/

int
sc_hash(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)
{
  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 SNMPERR_SUCCESS;

#endif /* USE_OPENSSL */
}
                _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.
 */
int
sc_hash(const oid * hashtype, size_t hashtypelen, u_char * buf,
        size_t buf_len, u_char * MAC, size_t * MAC_len)
#if defined(NETSNMP_USE_INTERNAL_MD5) || defined(NETSNMP_USE_OPENSSL) || defined(NETSNMP_USE_PKCS11)
{
#if defined(NETSNMP_USE_OPENSSL) || defined(NETSNMP_USE_PKCS11)
    int            rval = SNMPERR_SUCCESS;
#endif
    int            ret;

#ifdef NETSNMP_USE_OPENSSL
    const EVP_MD   *hashfn;
    EVP_MD_CTX     ctx, *cptr;
    unsigned int   tmp_len;
#endif

    DEBUGTRACE;

    if (hashtype == NULL || hashtypelen < 0 || buf == NULL ||
        buf_len <= 0 || MAC == NULL || MAC_len == NULL )
        return (SNMPERR_GENERR);
    ret = sc_get_properlength(hashtype, hashtypelen);
    if (( ret < 0 ) || (*MAC_len < ret ))
        return (SNMPERR_GENERR);

#ifdef NETSNMP_USE_OPENSSL
    /*
     * Determine transform type.
     */
#ifndef NETSNMP_DISABLE_MD5
    if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
        hashfn = (const EVP_MD *) EVP_md5();
    } else
#endif
        if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {
        hashfn = (const EVP_MD *) EVP_sha1();
    } else {
        return (SNMPERR_GENERR);
    }

/** initialize the pointer */
    memset(&ctx, 0, sizeof(ctx));
    cptr = &ctx;
#if defined(OLD_DES)
    EVP_DigestInit(cptr, hashfn);
#else /* !OLD_DES */
    /* this is needed if the runtime library is different than the compiled
       library since the openssl versions are very different. */
    if (SSLeay() < 0x907000) {
        /* the old version of the struct was bigger and thus more
           memory is needed. should be 152, but we use 256 for safety. */
        cptr = (EVP_MD_CTX *)malloc(256);
        EVP_DigestInit(cptr, hashfn);
    } else {
        EVP_MD_CTX_init(cptr);
        EVP_DigestInit(cptr, hashfn);
    }
#endif

/** pass the data */
    EVP_DigestUpdate(cptr, buf, buf_len);

/** do the final pass */
#if defined(OLD_DES)
    EVP_DigestFinal(cptr, MAC, &tmp_len);
    *MAC_len = tmp_len;
#else /* !OLD_DES */
    if (SSLeay() < 0x907000) {
        EVP_DigestFinal(cptr, MAC, &tmp_len);
        *MAC_len = tmp_len;
        free(cptr);
    } else {
        EVP_DigestFinal_ex(cptr, MAC, &tmp_len);
        *MAC_len = tmp_len;
        EVP_MD_CTX_cleanup(cptr);
    }
#endif                          /* OLD_DES */
    return (rval);
#elif NETSNMP_USE_PKCS11                  /* NETSNMP_USE_PKCS11 */

#ifndef NETSNMP_DISABLE_MD5
    if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
	rval = pkcs_digest(CKM_MD5, buf, buf_len, MAC, &tmp_len);
        *MAC_len = tmp_len;
    } else
#endif
        if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {
	rval = pkcs_digest(CKM_SHA_1, buf, buf_len, MAC, &tmp_len);
        *MAC_len = tmp_len;
    } else {
        return (SNMPERR_GENERR);
    }

     return (rval);

#else                           /* NETSNMP_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                          /* NETSNMP_USE_OPENSSL */
}