Exemple #1
0
  /*
   * 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.
 */
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() */
Exemple #2
0
/*******************************************************************-o-******
 * test_dokeyedhash
 *
 * Returns:
 *	Number of failures.
 *
 *
 * Test keyed hashes with a variety of MAC length requests.
 *
 *
 * NOTE Both tests intentionally use the same secret
 *
 * FIX	Get input or output from some other package which hashes...
 * XXX	Could cut this in half with a little indirection...
 */
int
test_dokeyedhash(void)
{
    int             rval = SNMPERR_SUCCESS, failcount = 0, bigstring_len = strlen(BIGSTRING), secret_len = strlen(BIGSECRET), properlength, mlcount = 0,        /* MAC Length count.   */
                    hblen;      /* Hash Buffer length. */

    u_int           hashbuf_len[MLCOUNT_MAX] = {
        LOCAL_MAXBUF,
        BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1),
        BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5),
        BYTESIZE(SNMP_TRANS_AUTHLEN_HMAC96),
        7,
        0,
    };

    u_char          hashbuf[LOCAL_MAXBUF];
    char           *s;

  test_dokeyedhash_again:

    OUTPUT("Keyed hash test using MD5 --");

    memset(hashbuf, 0, LOCAL_MAXBUF);
    hblen = hashbuf_len[mlcount];
    properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5);

    rval =
        sc_generate_keyed_hash(usmHMACMD5AuthProtocol,
                               USM_LENGTH_OID_TRANSFORM, BIGSECRET,
                               secret_len, BIGSTRING, bigstring_len,
                               hashbuf, &hblen);
    FAILED(rval, "sc_generate_keyed_hash().");

    if (hashbuf_len[mlcount] > properlength) {
        if (hblen != properlength) {
            FAILED(SNMPERR_GENERR, "Wrong MD5 hash length returned.  (1)");
        }

    } else if (hblen != hashbuf_len[mlcount]) {
        FAILED(SNMPERR_GENERR, "Wrong MD5 hash length returned.  (2)");
    }

    rval =
        sc_check_keyed_hash(usmHMACMD5AuthProtocol,
                            USM_LENGTH_OID_TRANSFORM, BIGSECRET,
                            secret_len, BIGSTRING, bigstring_len, hashbuf,
                            hblen);
    FAILED(rval, "sc_check_keyed_hash().");

    binary_to_hex(hashbuf, hblen, &s);
    fprintf(stdout, "hash buffer (len=%d, request=%d):   %s\n",
            hblen, hashbuf_len[mlcount], s);
    SNMP_FREE(s);

    SUCCESS("Keyed hash test using MD5.");



    OUTPUT("Keyed hash test using SHA1 --");

    memset(hashbuf, 0, LOCAL_MAXBUF);
    hblen = hashbuf_len[mlcount];
    properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);

    rval =
        sc_generate_keyed_hash(usmHMACSHA1AuthProtocol,
                               USM_LENGTH_OID_TRANSFORM, BIGSECRET,
                               secret_len, BIGSTRING, bigstring_len,
                               hashbuf, &hblen);
    FAILED(rval, "sc_generate_keyed_hash().");

    if (hashbuf_len[mlcount] > properlength) {
        if (hblen != properlength) {
            FAILED(SNMPERR_GENERR,
                   "Wrong SHA1 hash length returned.  (1)");
        }

    } else if (hblen != hashbuf_len[mlcount]) {
        FAILED(SNMPERR_GENERR, "Wrong SHA1 hash length returned.  (2)");
    }

    rval =
        sc_check_keyed_hash(usmHMACSHA1AuthProtocol,
                            USM_LENGTH_OID_TRANSFORM, BIGSECRET,
                            secret_len, BIGSTRING, bigstring_len, hashbuf,
                            hblen);
    FAILED(rval, "sc_check_keyed_hash().");

    binary_to_hex(hashbuf, hblen, &s);
    fprintf(stdout, "hash buffer (len=%d, request=%d):   %s\n",
            hblen, hashbuf_len[mlcount], s);
    SNMP_FREE(s);

    SUCCESS("Keyed hash test using SHA1.");



    /*
     * Run the basic hash tests but vary the size MAC requests.
     */
    if (hashbuf_len[++mlcount] != 0) {
        goto test_dokeyedhash_again;
    }


    return failcount;

}                               /* end test_dokeyedhash() */