/*! * 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; }
/*! * 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; }