Example #1
0
isc_result_t
isccc_cc_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp)
{
	isccc_sexpr_t *kv, *v;

	kv = isccc_alist_assq(alist, key);
	if (kv != NULL) {
		v = ISCCC_SEXPR_CDR(kv);
		if (isccc_sexpr_binaryp(v)) {
			if (strp != NULL)
				*strp = isccc_sexpr_tostring(v);
			return (ISC_R_SUCCESS);
		} else
			return (ISC_R_EXISTS);
	}

	return (ISC_R_NOTFOUND);
}
Example #2
0
isc_result_t
isccc_alist_lookupbinary(isccc_sexpr_t *alist, const char *key, isccc_region_t **r)
{
	isccc_sexpr_t *kv, *v;

	kv = isccc_alist_assq(alist, key);
	if (kv != NULL) {
		v = CDR(kv);
		if (isccc_sexpr_binaryp(v)) {
			if (r != NULL)
				*r = isccc_sexpr_tobinary(v);
			return (ISC_R_SUCCESS);
		} else
			return (ISC_R_EXISTS);
	}

	return (ISC_R_NOTFOUND);
}
Example #3
0
isc_result_t
isccc_cc_lookupuint32(isccc_sexpr_t *alist, const char *key,
		       isc_uint32_t *uintp)
{
	isccc_sexpr_t *kv, *v;

	kv = isccc_alist_assq(alist, key);
	if (kv != NULL) {
		v = ISCCC_SEXPR_CDR(kv);
		if (isccc_sexpr_binaryp(v)) {
			if (uintp != NULL)
				*uintp = (isc_uint32_t)
					strtoul(isccc_sexpr_tostring(v),
						NULL, 10);
			return (ISC_R_SUCCESS);
		} else
			return (ISC_R_EXISTS);
	}

	return (ISC_R_NOTFOUND);
}
Example #4
0
static isc_result_t
value_towire(isccc_sexpr_t *elt, isccc_region_t *target)
{
	size_t len;
	unsigned char *lenp;
	isccc_region_t *vr;
	isc_result_t result;

	if (isccc_sexpr_binaryp(elt)) {
		vr = isccc_sexpr_tobinary(elt);
		len = REGION_SIZE(*vr);
		if (REGION_SIZE(*target) < 1 + 4 + len)
			return (ISC_R_NOSPACE);
		PUT8(ISCCC_CCMSGTYPE_BINARYDATA, target->rstart);
		PUT32(len, target->rstart);
		if (REGION_SIZE(*target) < len)
			return (ISC_R_NOSPACE);
		PUT_MEM(vr->rstart, len, target->rstart);
	} else if (isccc_alist_alistp(elt)) {
		if (REGION_SIZE(*target) < 1 + 4)
			return (ISC_R_NOSPACE);
		PUT8(ISCCC_CCMSGTYPE_TABLE, target->rstart);
		/*
		 * Emit a placeholder length.
		 */
		lenp = target->rstart;
		PUT32(0, target->rstart);
		/*
		 * Emit the table.
		 */
		result = table_towire(elt, target);
		if (result != ISC_R_SUCCESS)
			return (result);
		len = (size_t)(target->rstart - lenp);
		/*
		 * 'len' is 4 bytes too big, since it counts
		 * the placeholder length too.  Adjust and
		 * emit.
		 */
		INSIST(len >= 4U);
		len -= 4;
		PUT32(len, lenp);
	} else if (isccc_sexpr_listp(elt)) {
		if (REGION_SIZE(*target) < 1 + 4)
			return (ISC_R_NOSPACE);
		PUT8(ISCCC_CCMSGTYPE_LIST, target->rstart);
		/*
		 * Emit a placeholder length and count.
		 */
		lenp = target->rstart;
		PUT32(0, target->rstart);
		/*
		 * Emit the list.
		 */
		result = list_towire(elt, target);
		if (result != ISC_R_SUCCESS)
			return (result);
		len = (size_t)(target->rstart - lenp);
		/*
		 * 'len' is 4 bytes too big, since it counts
		 * the placeholder length.  Adjust and emit.
		 */
		INSIST(len >= 4U);
		len -= 4;
		PUT32(len, lenp);
	}

	return (ISC_R_SUCCESS);
}
Example #5
0
static isc_result_t
verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length,
       isc_uint32_t algorithm, isccc_region_t *secret)
{
	union {
		isc_hmacmd5_t hmd5;
		isc_hmacsha1_t hsha;
		isc_hmacsha224_t h224;
		isc_hmacsha256_t h256;
		isc_hmacsha384_t h384;
		isc_hmacsha512_t h512;
	} ctx;
	isccc_region_t source;
	isccc_region_t target;
	isc_result_t result;
	isccc_sexpr_t *_auth, *hmac;
	unsigned char digest[ISC_SHA512_DIGESTLENGTH];
	unsigned char digestb64[HSHA_LENGTH * 4];

	/*
	 * Extract digest.
	 */
	_auth = isccc_alist_lookup(alist, "_auth");
	if (!isccc_alist_alistp(_auth))
		return (ISC_R_FAILURE);
	if (algorithm == ISCCC_ALG_HMACMD5)
		hmac = isccc_alist_lookup(_auth, "hmd5");
	else
		hmac = isccc_alist_lookup(_auth, "hsha");
	if (!isccc_sexpr_binaryp(hmac))
		return (ISC_R_FAILURE);
	/*
	 * Compute digest.
	 */
	source.rstart = digest;
	target.rstart = digestb64;
	switch (algorithm) {
	case ISCCC_ALG_HMACMD5:
		isc_hmacmd5_init(&ctx.hmd5, secret->rstart,
				 REGION_SIZE(*secret));
		isc_hmacmd5_update(&ctx.hmd5, data, length);
		isc_hmacmd5_sign(&ctx.hmd5, digest);
		source.rend = digest + ISC_MD5_DIGESTLENGTH;
		break;

	case ISCCC_ALG_HMACSHA1:
		isc_hmacsha1_init(&ctx.hsha, secret->rstart,
				    REGION_SIZE(*secret));
		isc_hmacsha1_update(&ctx.hsha, data, length);
		isc_hmacsha1_sign(&ctx.hsha, digest,
				    ISC_SHA1_DIGESTLENGTH);
		source.rend = digest + ISC_SHA1_DIGESTLENGTH;
		break;

	case ISCCC_ALG_HMACSHA224:
		isc_hmacsha224_init(&ctx.h224, secret->rstart,
				    REGION_SIZE(*secret));
		isc_hmacsha224_update(&ctx.h224, data, length);
		isc_hmacsha224_sign(&ctx.h224, digest,
				    ISC_SHA224_DIGESTLENGTH);
		source.rend = digest + ISC_SHA224_DIGESTLENGTH;
		break;

	case ISCCC_ALG_HMACSHA256:
		isc_hmacsha256_init(&ctx.h256, secret->rstart,
				    REGION_SIZE(*secret));
		isc_hmacsha256_update(&ctx.h256, data, length);
		isc_hmacsha256_sign(&ctx.h256, digest,
				    ISC_SHA256_DIGESTLENGTH);
		source.rend = digest + ISC_SHA256_DIGESTLENGTH;
		break;

	case ISCCC_ALG_HMACSHA384:
		isc_hmacsha384_init(&ctx.h384, secret->rstart,
				    REGION_SIZE(*secret));
		isc_hmacsha384_update(&ctx.h384, data, length);
		isc_hmacsha384_sign(&ctx.h384, digest,
				    ISC_SHA384_DIGESTLENGTH);
		source.rend = digest + ISC_SHA384_DIGESTLENGTH;
		break;

	case ISCCC_ALG_HMACSHA512:
		isc_hmacsha512_init(&ctx.h512, secret->rstart,
				    REGION_SIZE(*secret));
		isc_hmacsha512_update(&ctx.h512, data, length);
		isc_hmacsha512_sign(&ctx.h512, digest,
				    ISC_SHA512_DIGESTLENGTH);
		source.rend = digest + ISC_SHA512_DIGESTLENGTH;
		break;

	default:
		return (ISC_R_FAILURE);
	}
	target.rstart = digestb64;
	target.rend = digestb64 + sizeof(digestb64);
	memset(digestb64, 0, sizeof(digestb64));
	result = isccc_base64_encode(&source, 64, "", &target);
	if (result != ISC_R_SUCCESS)
		return (result);

	/*
	 * Verify.
	 */
	if (algorithm == ISCCC_ALG_HMACMD5) {
		unsigned char *value;

		value = (unsigned char *) isccc_sexpr_tostring(hmac);
		if (!isc_safe_memequal(value, digestb64, HMD5_LENGTH))
			return (ISCCC_R_BADAUTH);
	} else {
		unsigned char *value;
		isc_uint32_t valalg;

		value = (unsigned char *) isccc_sexpr_tostring(hmac);
		GET8(valalg, value);
		if ((valalg != algorithm) ||
		    !isc_safe_memequal(value, digestb64, HSHA_LENGTH))
			return (ISCCC_R_BADAUTH);
	}

	return (ISC_R_SUCCESS);
}