Example #1
0
/*******************************************************************-o-******
 * test_dorandom
 *
 * One large request, one set of short requests.
 *
 * Returns:
 *	Number of failures.
 *
 * XXX	probably should split up into individual options.
 */
int
test_dorandom(void)
{
    int             rval = SNMPERR_SUCCESS,
        failcount = 0,
        origrequest = (1024 * 2),
        origrequest_short = 19, nbytes = origrequest, shortcount = 7, i;
    char            buf[LOCAL_MAXBUF];

    OUTPUT("Random test -- large request:");

    rval = sc_random(buf, &nbytes);
    FAILED(rval, "sc_random().");

    if (nbytes != origrequest) {
        FAILED(SNMPERR_GENERR,
               "sc_random() returned different than requested.");
    }

    dump_chunk("scapitest", NULL, buf, nbytes);

    SUCCESS("Random test -- large request.");


    OUTPUT("Random test -- short requests:");
    origrequest_short = 16;

    for (i = 0; i < shortcount; i++) {
        nbytes = origrequest_short;
        rval = sc_random(buf, &nbytes);
        FAILED(rval, "sc_random().");

        if (nbytes != origrequest_short) {
            FAILED(SNMPERR_GENERR,
                   "sc_random() returned different " "than requested.");
        }

        dump_chunk("scapitest", NULL, buf, nbytes);
    }                           /* endfor */

    SUCCESS("Random test -- short requests.");


    return failcount;

}                               /* end test_dorandom() */
Example #2
0
/**
 * Returns pointer to allocaed & set buffer on success, size contains
 * number of random bytes filled.  buf is NULL and *size set to KMT
 * error value upon failure.
 *
 *	@param size	Number of bytes to malloc() and fill with random bytes.
 *
 * @return a malloced buffer
 *
 */
u_char         *
malloc_random(size_t * size)
{
    int             rval = SNMPERR_SUCCESS;
    u_char         *buf = (u_char *) calloc(1, *size);

    if (buf) {
        rval = sc_random(buf, size);

        if (rval < 0) {
            free_zero(buf, *size);
            buf = NULL;
        } else {
            *size = rval;
        }
    }

    return buf;

}                               /* end malloc_random() */
Example #3
0
_KEYTOOLS_NOT_AVAILABLE
#endif						/* internal or openssl */




/*******************************************************************-o-******
 * encode_keychange
 *
 * Parameters:
 *	*hashtype	MIB OID for the hash transform type.
 *	 hashtype_len	Length of the MIB OID hash transform type.
 *	*oldkey		Old key that is used to encodes the new key.
 *	 oldkey_len	Length of oldkey in bytes.
 *	*newkey		New key that is encoded using the old key.
 *	 newkey_len	Length of new key in bytes.
 *	*kcstring	Buffer to contain the KeyChange TC string.
 *	*kcstring_len	Length of kcstring buffer.
 *
 * Returns:
 *	SNMPERR_SUCCESS			Success.
 *	SNMPERR_GENERR			All errors.
 *
 *
 * Uses oldkey and acquired random bytes to encode newkey into kcstring
 * according to the rules of the KeyChange TC described in RFC 2274, Section 5.
 *
 * Upon successful return, *kcstring_len contains the length of the
 * encoded string.
 *
 * ASSUMES	Old and new key are always equal to each other, although
 *		this may be less than the transform type hash output
 * 		output length (eg, using KeyChange for a DESPriv key when
 *		the user also uses SHA1Auth).  This also implies that the
 *		hash placed in the second 1/2 of the key change string
 *		will be truncated before the XOR'ing when the hash output is
 *		larger than that 1/2 of the key change string.
 *
 *		*kcstring_len will be returned as exactly twice that same
 *		length though the input buffer may be larger.
 *
 * XXX FIX:     Does not handle varibable length keys.
 * XXX FIX:     Does not handle keys larger than the hash algorithm used.
 */
int
encode_keychange(	oid	*hashtype,	u_int  hashtype_len,
                    u_char	*oldkey,	size_t  oldkey_len,
                    u_char	*newkey,	size_t  newkey_len,
                    u_char	*kcstring,	size_t *kcstring_len)
#if defined(USE_OPENSSL) || defined(USE_INTERNAL_MD5)
{
    int		 rval    = SNMPERR_SUCCESS;
    size_t		 properlength;
    size_t            nbytes  = 0;

    u_char          *tmpbuf = NULL;
    void		*context = NULL;


    /*
     * Sanity check.
     */
    if ( !hashtype || !oldkey || !newkey || !kcstring || !kcstring_len
            || (oldkey_len<=0) || (newkey_len<=0) || (*kcstring_len<=0)
            || (hashtype_len != USM_LENGTH_OID_TRANSFORM) )
    {
        QUITFUN(SNMPERR_GENERR, encode_keychange_quit);
    }

    /*
     * Setup for the transform type.
     */
    properlength = sc_get_properlength(hashtype, hashtype_len);
    if (properlength == SNMPERR_GENERR)
        QUITFUN(SNMPERR_GENERR, encode_keychange_quit);

    if ( (oldkey_len != newkey_len) || (*kcstring_len < (2*oldkey_len)) )
    {
        QUITFUN(SNMPERR_GENERR, encode_keychange_quit);
    }

    properlength = SNMP_MIN((int)oldkey_len, properlength);

    /*
     * Use the old key and some random bytes to encode the new key
     * in the KeyChange TC format:
     *	. Get random bytes (store in first half of kcstring),
     *	. Hash (oldkey | random_bytes) (into second half of kcstring),
     *	. XOR hash and newkey (into second half of kcstring).
     *
     * Getting the wrong number of random bytes is considered an error.
     */
    nbytes = properlength;

#if defined(SNMP_TESTING_CODE) && defined(RANDOMZEROS)
    memset(kcstring, 0, nbytes);
    DEBUGMSG(("encode_keychange",
              "** Using all zero bits for \"random\" delta of )"
              "the keychange string! **\n"));
#else /* !SNMP_TESTING_CODE */
    rval = sc_random(kcstring, &nbytes);
    QUITFUN(rval, encode_keychange_quit);
    if ((int)nbytes != properlength) {
        QUITFUN(SNMPERR_GENERR, encode_keychange_quit);
    }
#endif /* !SNMP_TESTING_CODE */

    tmpbuf = (u_char *)malloc(properlength*2);
    if (tmpbuf) {
        memcpy(tmpbuf, oldkey, properlength);
        memcpy(tmpbuf+properlength, kcstring, properlength);

        *kcstring_len -= properlength;
        rval = sc_hash(hashtype, hashtype_len, tmpbuf, properlength*2,
                       kcstring+properlength, kcstring_len);

        QUITFUN(rval, encode_keychange_quit);

        *kcstring_len = (properlength*2);

        kcstring += properlength;
        nbytes    = 0;
        while ((int)(nbytes++) < properlength) {
            *kcstring++ = *kcstring ^ *newkey++;
        }
    }

encode_keychange_quit:
    if (rval != SNMPERR_SUCCESS) memset(kcstring, 0, *kcstring_len);
    SNMP_FREE(tmpbuf);
    SNMP_FREE(context);

    return rval;

}  /* end encode_keychange() */
Example #4
0
static void smp_server(const void *data, uint16_t len, void *user_data)
{
	struct test_data *test_data = user_data;
	struct bthost *bthost = hciemu_client_get_host(test_data->hciemu);
	const struct smp_data *smp = test_data->test_data;
	const struct smp_req_rsp *req;
	uint8_t opcode;
	const void *pdu;

	if (len < 1) {
		tester_warn("Received too small SMP PDU");
		goto failed;
	}

	opcode = *((const uint8_t *) data);

	tester_print("Received SMP opcode 0x%02x", opcode);

	if (test_data->counter >= smp->req_count) {
		test_condition_complete(test_data);
		return;
	}

	req = &smp->req[test_data->counter++];
	if (!req->expect)
		goto next;

	if (req->expect_len != len) {
		tester_warn("Unexpected SMP PDU length (%u != %u)",
							len, req->expect_len);
		goto failed;
	}

	switch (opcode) {
	case 0x01: /* Pairing Request */
		memcpy(test_data->preq, data, sizeof(test_data->preq));
		break;
	case 0x02: /* Pairing Response */
		memcpy(test_data->prsp, data, sizeof(test_data->prsp));
		break;
	case 0x03: /* Pairing Confirm */
		memcpy(test_data->pcnf, data + 1, 16);
		goto next;
	case 0x04: /* Pairing Random */
		memcpy(test_data->rrnd, data + 1, 16);
		if (smp->sc) {
			if (!sc_random(test_data))
				goto failed;
		} else {
			if (!verify_random(data + 1))
				goto failed;
		}
		goto next;
	case 0x0c: /* Public Key */
		memcpy(test_data->remote_pk, data + 1, 64);
		ecdh_shared_secret(test_data->remote_pk, test_data->local_sk,
							test_data->dhkey);
		goto next;
	default:
		break;
	}

	if (memcmp(req->expect, data, len) != 0) {
		tester_warn("Unexpected SMP PDU");
		goto failed;
	}

next:
	while (true) {
		if (smp->req_count == test_data->counter) {
			test_condition_complete(test_data);
			break;
		}

		req = &smp->req[test_data->counter];

		pdu = get_pdu(req->send);
		bthost_send_cid(bthost, test_data->handle, SMP_CID, pdu,
								req->send_len);
		if (req->expect)
			break;
		else
			test_data->counter++;
	}

	return;

failed:
	tester_test_failed();
}