Пример #1
0
Файл: dlv.c Проект: jelu/validns
static struct rr* dlv_parse(char *name, long ttl, int type, char *s)
{
    struct rr_dlv *rr = getmem(sizeof(*rr));
    int key_tag, algorithm, digest_type;

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

    algorithm = extract_algorithm(&s, "algorithm");
    if (algorithm == ALG_UNSUPPORTED)   return NULL;
    rr->algorithm = algorithm;

    digest_type = extract_integer(&s, "digest type", NULL);
    if (digest_type < 0)    return NULL;
    rr->digest_type = digest_type;

    rr->digest = extract_hex_binary_data(&s, "digest", EXTRACT_EAT_WHITESPACE);
    if (rr->digest.length < 0)  return NULL;

    switch (digest_type) {
    case 1:
        if (rr->digest.length != SHA1_BYTES) {
            return bitch("wrong SHA-1 digest length: %d bytes found, %d bytes expected", rr->digest.length, SHA1_BYTES);
        }
        break;
    case 2:
        if (rr->digest.length != SHA256_BYTES) {
            return bitch("wrong SHA-256 digest length: %d bytes found, %d bytes expected", rr->digest.length, SHA256_BYTES);
        }
        break;
    case 3:
        if (rr->digest.length != GOST_BYTES) {
            return bitch("wrong GOST R 34.11-94 digest length: %d bytes found, %d bytes expected", rr->digest.length, GOST_BYTES);
        }
        break;
    case 4:
        if (rr->digest.length != SHA384_BYTES) {
            return bitch("wrong SHA-384 digest length: %d bytes found, %d bytes expected", rr->digest.length, SHA384_BYTES);
        }
        break;
    default:
        return bitch("bad or unsupported digest type %d", digest_type);
    }

    if (*s) {
        return bitch("garbage after valid DLV data");
    }
    G.dnssec_active = 1;
    return store_record(type, name, ttl, rr);
}
Пример #2
0
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);
}
Пример #3
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;
}