Skip to content
Snippets Groups Projects
Commit f0153330 authored by Jan Včelák's avatar Jan Včelák :rocket:
Browse files

[dnssec] cleanup keytag API, simplify computation

parent e2850793
Branches
Tags
1 merge request!332libdnssec
......@@ -40,7 +40,7 @@ static void update_keytag(dnssec_key_t *key)
return;
}
key->keytag = keytag(&key->rdata);
keytag(&key->rdata, &key->keytag);
}
static void update_key_id(dnssec_key_t *key)
......
#include <arpa/inet.h>
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include "binary.h"
#include "error.h"
// TODO: verify conditions
// TODO: write tests
static uint16_t keytag_rsa_md5(const dnssec_binary_t *rdata)
/*!
* Compute keytag for RSA/MD5 key.
*
* \see RFC 2537 (section 2) , RFC 4034 (appendix B.1)
*/
static uint16_t keytag_compat(const dnssec_binary_t *rdata)
{
assert(rdata);
assert(rdata->data);
uint16_t ac = 0;
if (rdata->size > 4) {
memmove(&ac, rdata->data + rdata->size - 3, 2);
if (rdata->size < 9) { // in fact, the condition could be stricter
return 0;
}
return ntohs(ac);
}
uint8_t msb = rdata->data[rdata->size - 3];
uint8_t lsb = rdata->data[rdata->size - 2];
return (msb << 8) + lsb;
}
uint16_t keytag(const dnssec_binary_t *rdata)
/*!
* Compute keytag for other than RSA/MD5 key.
*
* \see RFC 4034 (appendix B)
*/
static uint16_t keytag_current(const dnssec_binary_t *rdata)
{
if (!rdata || !rdata->data || rdata->size < 4) {
return 0;
}
assert(rdata);
assert(rdata->data);
uint32_t ac = 0;
for (int i = 0; i < rdata->size; i++) {
ac += (i & 1) ? rdata->data[i] : rdata->data[i] << 8;
}
if (rdata->data[3] == 1) {
return keytag_rsa_md5(rdata);
ac += (ac >> 16) & 0xFFFF;
return ac & 0xFFFF;
}
/* -- public API ----------------------------------------------------------- */
/*!
* Compute keytag for a DNSSEC key.
*/
int keytag(const dnssec_binary_t *rdata, uint16_t *keytag)
{
if (!rdata || !keytag) {
return DNSSEC_EINVAL;
}
for(int i = 0; i < rdata->size; i++) {
ac += (i & 1) ? rdata->data[i] : rdata->data[i] << 8;
if (!rdata->data || rdata->size < 4) {
return DNSSEC_MALFORMED_DATA;
}
ac += (ac >> 16) & 0xFFFF;
return (uint16_t)ac & 0xFFFF;
uint8_t algorithm = rdata->data[3];
if (algorithm == 1) {
*keytag = keytag_compat(rdata);
} else {
*keytag = keytag_current(rdata);
}
return DNSSEC_EOK;
}
#include <stdint.h>
#include "binary.h"
uint16_t keytag(const dnssec_binary_t *rdata);
/*!
* Compute keytag for a DNSSEC key.
*
* \param[in] rdata DNSKEY RDATA.
* \param[out] keytag Computed keytag.
*
* \return Error code, DNSSEC_EOK of successful.
*/
int keytag(const dnssec_binary_t *rdata, uint16_t *keytag);
......@@ -2,6 +2,7 @@
#include <stdint.h>
#include "binary.h"
#include "error.h"
#include "key/keytag.h"
int main(void)
......@@ -19,7 +20,9 @@ int main(void)
0xc1, 0x02, 0x00, 0x6f, 0x31, 0x9f, 0xa2, 0x1d
}};
ok(keytag(&rsa_md5_rdata) == 40866, "keytag for RSA/MD5");
uint16_t tag = 0;
ok(keytag(&rsa_md5_rdata, &tag) == DNSSEC_EOK && tag == 40866,
"keytag for RSA/MD5");
const dnssec_binary_t ecdsa_rdata = { .size = 100, .data = (uint8_t []) {
0x01, 0x00, 0x03, 0x0e,
......@@ -35,7 +38,8 @@ int main(void)
0xf4, 0xfc, 0xe2, 0x10, 0xd4, 0x26
}};
ok(keytag(&ecdsa_rdata) == 61768, "keytag for ECDSA/SHA384");
ok(keytag(&ecdsa_rdata, &tag) == DNSSEC_EOK && tag == 61768,
"keytag for ECDSA/SHA384");
return 0;
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment