static inline isc_result_t fromtext_keydata(ARGS_FROMTEXT) { isc_token_t token; dns_secalg_t alg; dns_secproto_t proto; dns_keyflags_t flags; isc_uint32_t refresh, addhd, removehd; REQUIRE(type == 65533); UNUSED(type); UNUSED(rdclass); UNUSED(origin); UNUSED(options); UNUSED(callbacks); /* refresh timer */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &refresh)); RETERR(uint32_tobuffer(refresh, target)); /* add hold-down */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &addhd)); RETERR(uint32_tobuffer(addhd, target)); /* remove hold-down */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &removehd)); RETERR(uint32_tobuffer(removehd, target)); /* flags */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); RETERR(uint16_tobuffer(flags, target)); /* protocol */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &proto, 1)); /* algorithm */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &alg, 1)); /* No Key? */ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); return (isc_base64_tobuffer(lexer, target, -1)); }
ATF_TC_BODY(half_maxint, tc) { const char *test_text = "20380119031407"; const isc_uint32_t test_time = 0x7fffffff; isc_result_t result; isc_buffer_t target; isc_uint32_t when; char buf[128]; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); memset(buf, 0, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf)); result = dns_time32_totext(test_time, &target); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_STREQ(buf, test_text); result = dns_time32_fromtext(test_text, &when); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(when, test_time); dns_test_end(); }
ATF_TC_BODY(epoch_minus_one, tc) { const char *test_text = "19691231235959"; const isc_uint32_t test_time = 0xffffffff; isc_result_t result; isc_buffer_t target; isc_uint32_t when; char buf[128]; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); memset(buf, 0, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf)); result = dns_time32_totext(test_time, &target); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_STREQ(buf, test_text); result = dns_time32_fromtext(test_text, &when); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(when, test_time); dns_test_end(); }
ATF_TC_BODY(fifty_before, tc) { isc_result_t result; const char *test_text = "19610307130000"; const isc_uint32_t test_time = 0xef68f5d0; isc_buffer_t target; isc_uint32_t when; char buf[128]; UNUSED(tc); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); memset(buf, 0, sizeof(buf)); isc_buffer_init(&target, buf, sizeof(buf)); result = dns_time32_totext(test_time, &target); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_STREQ(buf, test_text); result = dns_time32_fromtext(test_text, &when); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_REQUIRE_EQ(when, test_time); dns_test_end(); }
static inline isc_result_t fromtext_sig(ARGS_FROMTEXT) { isc_token_t token; unsigned char c; long i; dns_rdatatype_t covered; char *e; isc_result_t result; dns_name_t name; isc_buffer_t buffer; isc_uint32_t time_signed, time_expire; REQUIRE(type == dns_rdatatype_sig); UNUSED(type); UNUSED(rdclass); UNUSED(callbacks); /* * Type covered. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion); if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { i = strtol(DNS_AS_STR(token), &e, 10); if (i < 0 || i > 65535) RETTOK(ISC_R_RANGE); if (*e != 0) RETTOK(result); covered = (dns_rdatatype_t)i; } RETERR(uint16_tobuffer(covered, target)); /* * Algorithm. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion)); RETERR(mem_tobuffer(target, &c, 1)); /* * Labels. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); if (token.value.as_ulong > 0xffU) RETTOK(ISC_R_RANGE); c = (unsigned char)token.value.as_ulong; RETERR(mem_tobuffer(target, &c, 1)); /* * Original ttl. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); RETERR(uint32_tobuffer(token.value.as_ulong, target)); /* * Signature expiration. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire)); RETERR(uint32_tobuffer(time_expire, target)); /* * Time signed. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed)); RETERR(uint32_tobuffer(time_signed, target)); /* * Key footprint. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, ISC_FALSE)); RETERR(uint16_tobuffer(token.value.as_ulong, target)); /* * Signer. */ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); if (origin == NULL) origin = dns_rootname; RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); /* * Sig. */ return (isc_base64_tobuffer(lexer, target, -1)); }
isc_result_t dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex, isc_mem_t *mctx, dst_private_t *priv) { int n = 0, major, minor, check; isc_buffer_t b; isc_token_t token; unsigned char *data = NULL; unsigned int opt = ISC_LEXOPT_EOL; isc_stdtime_t when; isc_result_t ret; isc_boolean_t external = ISC_FALSE; REQUIRE(priv != NULL); priv->nelements = 0; memset(priv->elements, 0, sizeof(priv->elements)); #define NEXTTOKEN(lex, opt, token) \ do { \ ret = isc_lex_gettoken(lex, opt, token); \ if (ret != ISC_R_SUCCESS) \ goto fail; \ } while (/*CONSTCOND*/0) #define READLINE(lex, opt, token) \ do { \ ret = isc_lex_gettoken(lex, opt, token); \ if (ret == ISC_R_EOF) \ break; \ else if (ret != ISC_R_SUCCESS) \ goto fail; \ } while ((*token).type != isc_tokentype_eol) /* * Read the description line. */ NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string || strcmp(DST_AS_STR(token), PRIVATE_KEY_STR) != 0) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string || (DST_AS_STR(token))[0] != 'v') { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } if (sscanf(DST_AS_STR(token), "v%d.%d", &major, &minor) != 2) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } if (major > DST_MAJOR_VERSION) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } /* * Store the private key format version number */ dst_key_setprivateformat(key, major, minor); READLINE(lex, opt, &token); /* * Read the algorithm line. */ NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string || strcmp(DST_AS_STR(token), ALGORITHM_STR) != 0) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token); if (token.type != isc_tokentype_number || token.value.as_ulong != (unsigned long) dst_key_alg(key)) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } READLINE(lex, opt, &token); /* * Read the key data. */ for (n = 0; n < MAXFIELDS; n++) { int tag; isc_region_t r; do { ret = isc_lex_gettoken(lex, opt, &token); if (ret == ISC_R_EOF) goto done; if (ret != ISC_R_SUCCESS) goto fail; } while (token.type == isc_tokentype_eol); if (token.type != isc_tokentype_string) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } if (strcmp(DST_AS_STR(token), "External:") == 0) { external = ISC_TRUE; goto next; } /* Numeric metadata */ tag = find_numericdata(DST_AS_STR(token)); if (tag >= 0) { INSIST(tag < NUMERIC_NTAGS); NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token); if (token.type != isc_tokentype_number) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } dst_key_setnum(key, tag, token.value.as_ulong); goto next; } /* Timing metadata */ tag = find_timedata(DST_AS_STR(token)); if (tag >= 0) { INSIST(tag < TIMING_NTAGS); NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } ret = dns_time32_fromtext(DST_AS_STR(token), &when); if (ret != ISC_R_SUCCESS) goto fail; dst_key_settime(key, tag, when); goto next; } /* Key data */ tag = find_value(DST_AS_STR(token), alg); if (tag < 0 && minor > DST_MINOR_VERSION) goto next; else if (tag < 0) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } priv->elements[n].tag = tag; data = (unsigned char *) isc_mem_get(mctx, MAXFIELDSIZE); if (data == NULL) goto fail; isc_buffer_init(&b, data, MAXFIELDSIZE); ret = isc_base64_tobuffer(lex, &b, -1); if (ret != ISC_R_SUCCESS) goto fail; isc_buffer_usedregion(&b, &r); priv->elements[n].length = r.length; priv->elements[n].data = r.base; priv->nelements++; next: READLINE(lex, opt, &token); data = NULL; } done: if (external && priv->nelements != 0) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } check = check_data(priv, alg, ISC_TRUE, external); if (check < 0) { ret = DST_R_INVALIDPRIVATEKEY; goto fail; } else if (check != ISC_R_SUCCESS) { ret = check; goto fail; } key->external = external; return (ISC_R_SUCCESS); fail: dst__privstruct_free(priv, mctx); if (data != NULL) isc_mem_put(mctx, data, MAXFIELDSIZE); return (ret); }