示例#1
0
文件: cert.c 项目: MikeAT/validns
static struct rr* cert_parse(char *name, long ttl, int type, char *s)
{
	struct rr_cert *rr = getmem(sizeof(*rr));
	int cert_type, key_tag, alg;

	cert_type = extract_certificate_type(&s, "certificate type");
	if (cert_type < 0)	return NULL;
	rr->type = cert_type;

	key_tag = extract_integer(&s, "key tag");
	if (key_tag < 0)	return NULL;
	if (key_tag > 65535)
		return bitch("bad key tag");
	rr->key_tag = key_tag;

	if (isdigit(*s)) {
		alg = extract_integer(&s, "algorithm");
		if (alg < 0)	return NULL;
		if (alg > 255)	return bitch("bad algorithm");
		if (alg != 0) {  /* 0 is just fine */
			if (algorithm_type(alg) == ALG_UNSUPPORTED)
				return bitch("bad algorithm %d", alg);
		}
	} else {
		alg = extract_algorithm(&s, "algorithm");
		if (alg == ALG_UNSUPPORTED)	return NULL;
	}
	rr->algorithm = alg;

	if (alg == 0 && key_tag != 0) {
		/* we might want to bitch here, but RFC says "SHOULD", so we don't */
	}

	rr->certificate = extract_base64_binary_data(&s, "certificate");
	if (rr->certificate.length < 0)	return NULL;
	/* TODO validate cert length based on algorithm */

	if (*s) {
		return bitch("garbage after valid CERT data");
	}
	return store_record(type, name, ttl, rr);
}
示例#2
0
static struct rr* dnskey_parse(char *name, long ttl, int type, char *s)
{
	struct rr_dnskey *rr = getmem(sizeof(*rr));
	struct binary_data key;
	int flags, proto, algorithm;
	unsigned int ac;
	int i;
	static struct rr *result;

	flags = extract_integer(&s, "flags");
	if (flags < 0) return NULL;
	if (flags & 0xfefe)
		return bitch("reserved flags bits are set");
	if (flags & 0x0001 && !(flags & 0x0100))
		return bitch("SEP bit is set but Zone Key bit is unset");
	rr->flags = flags;

	/* TODO validate that `name` is the name of the zone if flags have Zone Key bit set */

	proto = extract_integer(&s, "protocol");
	if (proto < 0) return NULL;
	if (proto != 3)
		return bitch("bad protocol value");
	rr->protocol = proto;

	algorithm = extract_algorithm(&s, "algorithm");
	if (algorithm == ALG_UNSUPPORTED)	return NULL;
	if (algorithm == ALG_PRIVATEDNS || algorithm == ALG_PRIVATEOID) {
		return bitch("private algorithms are not supported in DNSKEY");
	}
	rr->algorithm = algorithm;

	key = extract_base64_binary_data(&s, "public key");
	if (key.length < 0)	return NULL;
	/* TODO validate key length based on algorithm */
	rr->pubkey = key;

	ac = 0;
	ac += rr->flags;
	ac += rr->protocol << 8;
	ac += rr->algorithm;
	for (i = 0; i < rr->pubkey.length; i++) {
		ac += (i & 1) ? (unsigned char)rr->pubkey.data[i] : ((unsigned char)rr->pubkey.data[i]) << 8;
	}
	ac += (ac >> 16) & 0xFFFF;
	rr->key_tag = ac & 0xFFFF;

	rr->pkey_built = 0;
	rr->pkey = NULL;
	rr->key_type = KEY_TYPE_UNUSED;

	if (*s) {
		return bitch("garbage after valid DNSKEY data");
	}
	result = store_record(type, name, ttl, rr);
	if (result) {
		rr->next_key = all_dns_keys;
		all_dns_keys = rr;
	}
	return result;
}
示例#3
0
static struct rr *ipseckey_parse(char *name, long ttl, int type, char *s)
{
	struct rr_ipseckey *rr = getmem(sizeof(*rr));
	int i;

	rr->precedence = i = extract_integer(&s, "precedence", NULL);
	if (i < 0)    return NULL;
	if (i >= 256) return bitch("precedence range is not valid");

	rr->gateway_type = i = extract_integer(&s, "gateway type", NULL);
	if (i < 0) return NULL;
	if (i > 3) return bitch("gateway type is not valid");

	rr->algorithm = i = extract_integer(&s, "algorithm", NULL);
	if (i < 0) return NULL;
	if (i > 2) return bitch("algorithm is not valid");

	switch (rr->gateway_type) {
	case 0:
		rr->gateway.gateway_none = extract_name(&s, "gateway/.", KEEP_CAPITALIZATION);
		if (!rr->gateway.gateway_none) return NULL;
		if (strcmp(rr->gateway.gateway_none, ".") != 0)
			return bitch("gateway must be \".\" for gateway type 0");
		break;
	case 1:
		if (extract_ipv4(&s, "gateway/IPv4", &rr->gateway.gateway_ipv4) <= 0)
			return NULL;
		break;
	case 2:
		if (extract_ipv6(&s, "gateway/IPv6", &rr->gateway.gateway_ipv6) <= 0)
			return NULL;
		break;
	case 3:
		rr->gateway.gateway_name = extract_name(&s, "gateway/name", KEEP_CAPITALIZATION);
		if (!rr->gateway.gateway_name) return NULL;
		break;
	default:
		croakx(7, "assertion failed: gateway type %d not within range", rr->gateway_type);
	}

	/* My reading of http://tools.ietf.org/html/rfc4025 is fuzzy on:
	 *
	 * - whether it is possible to have algorithm 0 and non-empty key;
	 * - whether it is possible to have empty key and algorithm != 0.
	 *
	 * Here I assume "not possible" for both.
	 */
	switch (rr->algorithm) {
	case 0:
		break;
	case 1:
		/* DSA key */
		rr->public_key = extract_base64_binary_data(&s, "public key");
		if (rr->public_key.length < 0)     return NULL;
		break;
	case 2:
		/* RSA key */
		rr->public_key = extract_base64_binary_data(&s, "public key");
		if (rr->public_key.length < 0)     return NULL;
		break;
	default:
		croakx(7, "assertion failed: algorithm %d not within range", rr->algorithm);
	}

	if (*s) {
		return bitch("garbage after valid IPSECKEY data");
	}

	return store_record(type, name, ttl, rr);
}