static void create_dnskeys(dnssec_keystore_t *keystore, dnssec_key_algorithm_t algorithm, const char *id, dnssec_key_t **p11_key_ptr, dnssec_key_t **soft_key_ptr) { int r; // construct PKCS #11 privkey-pubkey key pair dnssec_key_t *p11_key = NULL; r = dnssec_key_new(&p11_key); ok(r == DNSSEC_EOK && p11_key != NULL, MSG_PKCS11 " dnssec_key_new()"); r = dnssec_key_set_algorithm(p11_key, algorithm); ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_set_key_algorithm()"); r = dnssec_key_import_keystore(p11_key, keystore, id); ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_key_import_keystore()"); // construct software public key dnssec_key_t *soft_key = NULL; r = dnssec_key_new(&soft_key); ok(r == DNSSEC_EOK && soft_key != NULL, MSG_SOFTWARE " dnssec_key_new()"); dnssec_binary_t rdata = { 0 }; dnssec_key_get_rdata(p11_key, &rdata); r = dnssec_key_set_rdata(soft_key, &rdata); ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_key_set_rdata()"); *p11_key_ptr = p11_key; *soft_key_ptr = soft_key; }
/*! * Parse DNSKEY record. * * \todo Currently, the function waits for the first DNSKEY record, and skips * the others. We should be more strict and report other records as errors. * However, there is currently no API to stop the scanner. */ static void parse_record(zs_scanner_t *scanner) { assert(scanner); assert(scanner->data); dnssec_key_t *key = scanner->data; if (dnssec_key_get_dname(key) != NULL) { // skip till the the parser finishes return; } if (scanner->r_type != RTYPE_DNSKEY) { // should report error return; } dnssec_binary_t rdata = { .data = scanner->r_data, .size = scanner->r_data_length }; dnssec_key_set_dname(key, scanner->dname); dnssec_key_set_rdata(key, &rdata); } int legacy_pubkey_parse(const char *filename, dnssec_key_t **key_ptr) { assert(filename); assert(key_ptr); dnssec_key_t *key = NULL; int result = dnssec_key_new(&key); if (result != DNSSEC_EOK) { return result; } uint16_t cls = CLASS_IN; uint32_t ttl = 0; zs_scanner_t *scanner = zs_scanner_create(".", cls, ttl, parse_record, NULL, key); if (!scanner) { dnssec_key_free(key); return DNSSEC_NOT_FOUND; } result = zs_scanner_parse_file(scanner, filename); zs_scanner_free(scanner); if (result != 0 || dnssec_key_get_dname(key) == NULL) { dnssec_key_free(key); return DNSSEC_INVALID_PUBLIC_KEY; } *key_ptr = key; return DNSSEC_EOK; }
int kr_dnssec_key_from_rdata(struct dseckey **key, const knot_dname_t *kown, const uint8_t *rdata, size_t rdlen) { if (!key || !rdata || rdlen == 0) { return kr_error(EINVAL); } dnssec_key_t *new_key = NULL; const dnssec_binary_t binary_key = { .size = rdlen, .data = (uint8_t *)rdata }; int ret = dnssec_key_new(&new_key); if (ret != DNSSEC_EOK) { return kr_error(ENOMEM); } ret = dnssec_key_set_rdata(new_key, &binary_key); if (ret != DNSSEC_EOK) { dnssec_key_free(new_key); return kr_error(ENOMEM); } if (kown) { ret = dnssec_key_set_dname(new_key, kown); if (ret != DNSSEC_EOK) { dnssec_key_free(new_key); return kr_error(ENOMEM); } } *key = (struct dseckey *) new_key; return kr_ok(); } void kr_dnssec_key_free(struct dseckey **key) { assert(key); dnssec_key_free((dnssec_key_t *) *key); *key = NULL; }
/*! * Parse DNSKEY record. * * \todo Currently, the function waits for the first DNSKEY record, and skips * the others. We should be more strict and report other records as errors. */ static void parse_record(zs_scanner_t *scanner) { assert(scanner); assert(scanner->process.data); dnssec_key_t *key = scanner->process.data; if (dnssec_key_get_dname(key) != NULL) { // should report error scanner->state = ZS_STATE_STOP; return; } if (scanner->r_type != RTYPE_DNSKEY) { // should report error scanner->state = ZS_STATE_STOP; return; } dnssec_binary_t rdata = { .data = scanner->r_data, .size = scanner->r_data_length }; dnssec_key_set_dname(key, scanner->dname); dnssec_key_set_rdata(key, &rdata); } int legacy_pubkey_parse(const char *filename, dnssec_key_t **key_ptr) { assert(filename); assert(key_ptr); dnssec_key_t *key = NULL; int result = dnssec_key_new(&key); if (result != DNSSEC_EOK) { return result; } uint16_t cls = CLASS_IN; uint32_t ttl = 0; zs_scanner_t *scanner = malloc(sizeof(zs_scanner_t)); if (scanner == NULL) { dnssec_key_free(key); return DNSSEC_ENOMEM; } if (zs_init(scanner, ".", cls, ttl) != 0 || zs_set_input_file(scanner, filename) != 0 || zs_set_processing(scanner, parse_record, NULL, key) != 0 || zs_parse_all(scanner) != 0) { zs_deinit(scanner); free(scanner); dnssec_key_free(key); return DNSSEC_NOT_FOUND; } zs_deinit(scanner); free(scanner); if (dnssec_key_get_dname(key) == NULL) { dnssec_key_free(key); return DNSSEC_INVALID_PUBLIC_KEY; } *key_ptr = key; return DNSSEC_EOK; }