int kr_check_signature(const knot_rrset_t *rrsigs, size_t pos, const dnssec_key_t *key, const knot_rrset_t *covered, int trim_labels) { if (!rrsigs || !key || !dnssec_key_can_verify(key)) { return kr_error(EINVAL); } int ret = 0; dnssec_sign_ctx_t *sign_ctx = NULL; dnssec_binary_t signature = {0, }; knot_rrsig_signature(&rrsigs->rrs, pos, &signature.data, &signature.size); if (!signature.data || !signature.size) { ret = kr_error(EINVAL); goto fail; } if (dnssec_sign_new(&sign_ctx, key) != 0) { ret = kr_error(ENOMEM); goto fail; } uint32_t orig_ttl = knot_rrsig_original_ttl(&rrsigs->rrs, pos); const knot_rdata_t *rr_data = knot_rdataset_at(&rrsigs->rrs, pos); uint8_t *rdata = knot_rdata_data(rr_data); if (sign_ctx_add_data(sign_ctx, rdata, covered, orig_ttl, trim_labels) != 0) { ret = kr_error(ENOMEM); goto fail; } if (dnssec_sign_verify(sign_ctx, &signature) != 0) { ret = kr_error(EBADMSG); goto fail; } ret = kr_ok(); fail: dnssec_sign_free(sign_ctx); return ret; }
static void test_sign(dnssec_key_t *p11_key, dnssec_key_t *soft_key) { int r; static const dnssec_binary_t input = { .data = (uint8_t *)"So Long, and Thanks for All the Fish.", .size = 37 }; dnssec_binary_t sign = { 0 }; // usage constraints ok(dnssec_key_can_sign(p11_key), MSG_PKCS11 " dnssec_key_can_sign()"); ok(dnssec_key_can_verify(p11_key), MSG_PKCS11 " dnssec_key_can_verify()"); ok(!dnssec_key_can_sign(soft_key), MSG_SOFTWARE " dnssec_key_can_sign()"); ok(dnssec_key_can_verify(soft_key), MSG_SOFTWARE " dnssec_key_can_verify()"); // PKCS #11 key signature dnssec_sign_ctx_t *ctx = NULL; r = dnssec_sign_new(&ctx, p11_key); ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_init() "); r = dnssec_sign_add(ctx, &input); ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_add()"); r = dnssec_sign_write(ctx, &sign); ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_write()"); // PKCS #11 key verification r = dnssec_sign_init(ctx); ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_init()"); r = dnssec_sign_add(ctx, &input); ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_add()"); r = dnssec_sign_verify(ctx, &sign); ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_verify()"); // software verification dnssec_sign_free(ctx); ctx = NULL; r = dnssec_sign_new(&ctx, soft_key); ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_sign_init()"); r = dnssec_sign_add(ctx, &input); ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_sign_add()"); r = dnssec_sign_verify(ctx, &sign); ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_sign_verify()"); dnssec_binary_free(&sign); dnssec_sign_free(ctx); } static void test_key_use(dnssec_keystore_t *store, dnssec_key_algorithm_t algorithm, const char *keyid) { dnssec_key_t *p11_key = NULL; dnssec_key_t *soft_key = NULL; create_dnskeys(store, algorithm, keyid, &p11_key, &soft_key); test_sign(p11_key, soft_key); dnssec_key_free(p11_key); dnssec_key_free(soft_key); }