xref: /openbsd-src/usr.bin/dig/lib/dns/rdata/generic/keydata_65533.c (revision 873f12b9e6aaf39ba104db6af3d0dc687cd95f7e)
15185a700Sflorian /*
25185a700Sflorian  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
35185a700Sflorian  *
45185a700Sflorian  * Permission to use, copy, modify, and/or distribute this software for any
55185a700Sflorian  * purpose with or without fee is hereby granted, provided that the above
65185a700Sflorian  * copyright notice and this permission notice appear in all copies.
75185a700Sflorian  *
85185a700Sflorian  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
95185a700Sflorian  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
105185a700Sflorian  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
115185a700Sflorian  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
125185a700Sflorian  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
135185a700Sflorian  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
145185a700Sflorian  * PERFORMANCE OF THIS SOFTWARE.
155185a700Sflorian  */
165185a700Sflorian 
175185a700Sflorian #ifndef GENERIC_KEYDATA_65533_C
185185a700Sflorian #define GENERIC_KEYDATA_65533_C 1
195185a700Sflorian 
204465bcfbSjsg #include <time.h>
215185a700Sflorian 
225185a700Sflorian #include <dst/dst.h>
235185a700Sflorian 
2498bc8dccSflorian /*
2598bc8dccSflorian  * ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially
2698bc8dccSflorian  * more for other locales to handle longer national abbreviations when
2798bc8dccSflorian  * expanding strftime's %a and %b.
2898bc8dccSflorian  */
2998bc8dccSflorian #define ISC_FORMATHTTPTIMESTAMP_SIZE 50
3098bc8dccSflorian 
3198bc8dccSflorian static void
isc_time_formathttptimestamp(const struct timespec * t,char * buf,size_t len)3298bc8dccSflorian isc_time_formathttptimestamp(const struct timespec *t, char *buf, size_t len) {
3398bc8dccSflorian 	size_t flen;
3498bc8dccSflorian 	/*
3598bc8dccSflorian 	 * 5 spaces, 1 comma, 3 GMT, 2 %d, 4 %Y, 8 %H:%M:%S, 3+ %a, 3+ %b (29+)
3698bc8dccSflorian 	 */
3798bc8dccSflorian 
3898bc8dccSflorian 	flen = strftime(buf, len, "%a, %d %b %Y %H:%M:%S GMT",
3998bc8dccSflorian 	    gmtime(&t->tv_sec));
4098bc8dccSflorian 	INSIST(flen < len);
4198bc8dccSflorian }
4298bc8dccSflorian 
435185a700Sflorian static inline isc_result_t
totext_keydata(ARGS_TOTEXT)445185a700Sflorian totext_keydata(ARGS_TOTEXT) {
455185a700Sflorian 	isc_region_t sr;
465185a700Sflorian 	char buf[sizeof("64000")];
475185a700Sflorian 	unsigned int flags;
485185a700Sflorian 	unsigned char algorithm;
495185a700Sflorian 	unsigned long refresh, add, deltime;
505185a700Sflorian 	char algbuf[DNS_NAME_FORMATSIZE];
515185a700Sflorian 	const char *keyinfo;
525185a700Sflorian 
535185a700Sflorian 	REQUIRE(rdata->type == dns_rdatatype_keydata);
545185a700Sflorian 
555185a700Sflorian 	if ((tctx->flags & DNS_STYLEFLAG_KEYDATA) == 0 || rdata->length < 16)
565185a700Sflorian 		return (unknown_totext(rdata, tctx, target));
575185a700Sflorian 
585185a700Sflorian 	dns_rdata_toregion(rdata, &sr);
595185a700Sflorian 
605185a700Sflorian 	/* refresh timer */
615185a700Sflorian 	refresh = uint32_fromregion(&sr);
625185a700Sflorian 	isc_region_consume(&sr, 4);
635185a700Sflorian 	RETERR(dns_time32_totext(refresh, target));
64*873f12b9Sflorian 	RETERR(isc_str_tobuffer(" ", target));
655185a700Sflorian 
665185a700Sflorian 	/* add hold-down */
675185a700Sflorian 	add = uint32_fromregion(&sr);
685185a700Sflorian 	isc_region_consume(&sr, 4);
695185a700Sflorian 	RETERR(dns_time32_totext(add, target));
70*873f12b9Sflorian 	RETERR(isc_str_tobuffer(" ", target));
715185a700Sflorian 
725185a700Sflorian 	/* remove hold-down */
735185a700Sflorian 	deltime = uint32_fromregion(&sr);
745185a700Sflorian 	isc_region_consume(&sr, 4);
755185a700Sflorian 	RETERR(dns_time32_totext(deltime, target));
76*873f12b9Sflorian 	RETERR(isc_str_tobuffer(" ", target));
775185a700Sflorian 
785185a700Sflorian 	/* flags */
795185a700Sflorian 	flags = uint16_fromregion(&sr);
805185a700Sflorian 	isc_region_consume(&sr, 2);
815185a700Sflorian 	snprintf(buf, sizeof(buf), "%u", flags);
82*873f12b9Sflorian 	RETERR(isc_str_tobuffer(buf, target));
83*873f12b9Sflorian 	RETERR(isc_str_tobuffer(" ", target));
845185a700Sflorian 	if ((flags & DNS_KEYFLAG_KSK) != 0) {
855185a700Sflorian 		if (flags & DNS_KEYFLAG_REVOKE)
865185a700Sflorian 			keyinfo = "revoked KSK";
875185a700Sflorian 		else
885185a700Sflorian 			keyinfo = "KSK";
895185a700Sflorian 	} else
905185a700Sflorian 		keyinfo = "ZSK";
915185a700Sflorian 
925185a700Sflorian 	/* protocol */
935185a700Sflorian 	snprintf(buf, sizeof(buf), "%u", sr.base[0]);
945185a700Sflorian 	isc_region_consume(&sr, 1);
95*873f12b9Sflorian 	RETERR(isc_str_tobuffer(buf, target));
96*873f12b9Sflorian 	RETERR(isc_str_tobuffer(" ", target));
975185a700Sflorian 
985185a700Sflorian 	/* algorithm */
995185a700Sflorian 	algorithm = sr.base[0];
1005185a700Sflorian 	snprintf(buf, sizeof(buf), "%u", algorithm);
1015185a700Sflorian 	isc_region_consume(&sr, 1);
102*873f12b9Sflorian 	RETERR(isc_str_tobuffer(buf, target));
1035185a700Sflorian 
1045185a700Sflorian 	/* No Key? */
1055185a700Sflorian 	if ((flags & 0xc000) == 0xc000)
1065185a700Sflorian 		return (ISC_R_SUCCESS);
1075185a700Sflorian 
1085185a700Sflorian 	/* key */
1095185a700Sflorian 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
110*873f12b9Sflorian 		RETERR(isc_str_tobuffer(" (", target));
111*873f12b9Sflorian 	RETERR(isc_str_tobuffer(tctx->linebreak, target));
1125185a700Sflorian 	if (tctx->width == 0)   /* No splitting */
1135185a700Sflorian 		RETERR(isc_base64_totext(&sr, 60, "", target));
1145185a700Sflorian 	else
1155185a700Sflorian 		RETERR(isc_base64_totext(&sr, tctx->width - 2,
1165185a700Sflorian 					 tctx->linebreak, target));
1175185a700Sflorian 
1185185a700Sflorian 	if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0)
119*873f12b9Sflorian 		RETERR(isc_str_tobuffer(tctx->linebreak, target));
1205185a700Sflorian 	else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
121*873f12b9Sflorian 		RETERR(isc_str_tobuffer(" ", target));
1225185a700Sflorian 
1235185a700Sflorian 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
124*873f12b9Sflorian 		RETERR(isc_str_tobuffer(")", target));
1255185a700Sflorian 
1265185a700Sflorian 	if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
1275185a700Sflorian 		isc_region_t tmpr;
1285185a700Sflorian 		char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
1295185a700Sflorian 		char abuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
1305185a700Sflorian 		char dbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
1317238a213Sflorian 		struct timespec t;
1325185a700Sflorian 
133*873f12b9Sflorian 		RETERR(isc_str_tobuffer(" ; ", target));
134*873f12b9Sflorian 		RETERR(isc_str_tobuffer(keyinfo, target));
1355185a700Sflorian 		dns_secalg_format((dns_secalg_t) algorithm, algbuf,
1365185a700Sflorian 				  sizeof(algbuf));
137*873f12b9Sflorian 		RETERR(isc_str_tobuffer("; alg = ", target));
138*873f12b9Sflorian 		RETERR(isc_str_tobuffer(algbuf, target));
139*873f12b9Sflorian 		RETERR(isc_str_tobuffer("; key id = ", target));
1405185a700Sflorian 		dns_rdata_toregion(rdata, &tmpr);
1415185a700Sflorian 		/* Skip over refresh, addhd, and removehd */
1425185a700Sflorian 		isc_region_consume(&tmpr, 12);
1435185a700Sflorian 		snprintf(buf, sizeof(buf), "%u",
1445185a700Sflorian 			 dst_region_computeid(&tmpr, algorithm));
145*873f12b9Sflorian 		RETERR(isc_str_tobuffer(buf, target));
1465185a700Sflorian 
1475185a700Sflorian 		if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
148c576c3baSflorian 			time_t now;
1495185a700Sflorian 
150c576c3baSflorian 			time(&now);
1515185a700Sflorian 
152*873f12b9Sflorian 			RETERR(isc_str_tobuffer(tctx->linebreak, target));
153*873f12b9Sflorian 			RETERR(isc_str_tobuffer("; next refresh: ", target));
154bb7ec108Sflorian 			t.tv_sec = refresh;
155bb7ec108Sflorian 			t.tv_nsec = 0;
1565185a700Sflorian 			isc_time_formathttptimestamp(&t, rbuf, sizeof(rbuf));
157*873f12b9Sflorian 			RETERR(isc_str_tobuffer(rbuf, target));
1585185a700Sflorian 
1595185a700Sflorian 			if (add == 0U) {
160*873f12b9Sflorian 				RETERR(isc_str_tobuffer(tctx->linebreak, target));
161*873f12b9Sflorian 				RETERR(isc_str_tobuffer("; no trust", target));
1625185a700Sflorian 			} else {
163*873f12b9Sflorian 				RETERR(isc_str_tobuffer(tctx->linebreak, target));
164c576c3baSflorian 				if ((time_t)add < now) {
165*873f12b9Sflorian 					RETERR(isc_str_tobuffer("; trusted since: ",
1665185a700Sflorian 							  target));
1675185a700Sflorian 				} else {
168*873f12b9Sflorian 					RETERR(isc_str_tobuffer("; trust pending: ",
1695185a700Sflorian 							  target));
1705185a700Sflorian 				}
171bb7ec108Sflorian 				t.tv_sec = add;
172bb7ec108Sflorian 				t.tv_nsec = 0;
1735185a700Sflorian 				isc_time_formathttptimestamp(&t, abuf,
1745185a700Sflorian 							     sizeof(abuf));
175*873f12b9Sflorian 				RETERR(isc_str_tobuffer(abuf, target));
1765185a700Sflorian 			}
1775185a700Sflorian 
1785185a700Sflorian 			if (deltime != 0U) {
179*873f12b9Sflorian 				RETERR(isc_str_tobuffer(tctx->linebreak, target));
180*873f12b9Sflorian 				RETERR(isc_str_tobuffer("; removal pending: ",
1815185a700Sflorian 						  target));
182bb7ec108Sflorian 				t.tv_sec = deltime;
183bb7ec108Sflorian 				t.tv_nsec = 0;
1845185a700Sflorian 				isc_time_formathttptimestamp(&t, dbuf,
1855185a700Sflorian 							     sizeof(dbuf));
186*873f12b9Sflorian 				RETERR(isc_str_tobuffer(dbuf, target));
1875185a700Sflorian 			}
1885185a700Sflorian 		}
1895185a700Sflorian 
1905185a700Sflorian 	}
1915185a700Sflorian 	return (ISC_R_SUCCESS);
1925185a700Sflorian }
1935185a700Sflorian 
1945185a700Sflorian static inline isc_result_t
fromwire_keydata(ARGS_FROMWIRE)1955185a700Sflorian fromwire_keydata(ARGS_FROMWIRE) {
1965185a700Sflorian 	isc_region_t sr;
1975185a700Sflorian 
1985185a700Sflorian 	REQUIRE(type == dns_rdatatype_keydata);
1995185a700Sflorian 
2005185a700Sflorian 	UNUSED(type);
2015185a700Sflorian 	UNUSED(rdclass);
2025185a700Sflorian 	UNUSED(dctx);
2035185a700Sflorian 	UNUSED(options);
2045185a700Sflorian 
2055185a700Sflorian 	isc_buffer_activeregion(source, &sr);
2065185a700Sflorian 	isc_buffer_forward(source, sr.length);
207637d8eb6Sflorian 	return (isc_mem_tobuffer(target, sr.base, sr.length));
2085185a700Sflorian }
2095185a700Sflorian 
2105185a700Sflorian static inline isc_result_t
towire_keydata(ARGS_TOWIRE)2115185a700Sflorian towire_keydata(ARGS_TOWIRE) {
2125185a700Sflorian 	isc_region_t sr;
2135185a700Sflorian 
2145185a700Sflorian 	REQUIRE(rdata->type == dns_rdatatype_keydata);
2155185a700Sflorian 
2165185a700Sflorian 	UNUSED(cctx);
2175185a700Sflorian 
2185185a700Sflorian 	dns_rdata_toregion(rdata, &sr);
219637d8eb6Sflorian 	return (isc_mem_tobuffer(target, sr.base, sr.length));
2205185a700Sflorian }
2215185a700Sflorian 
2225185a700Sflorian #endif /* GENERIC_KEYDATA_65533_C */
223